yeah
This commit is contained in:
119
server/utils/fileScanner.ts
Normal file
119
server/utils/fileScanner.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { readdir, readFile } from 'node:fs/promises'
|
||||
import { join, extname, basename } from 'node:path'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { slugify } from './slugify'
|
||||
import { getCardFromDate } from './getCardFromDate'
|
||||
import type { Card } from '@/types/types'
|
||||
|
||||
const listAudioExts = ['.mp3', '.opus', 'flac']
|
||||
const listImageExts = ['.jpg', '.jpeg', '.webp']
|
||||
|
||||
export async function scanMusicFolder(folderPath: string): Promise<Card[]> {
|
||||
try {
|
||||
const files = await readdir(folderPath)
|
||||
const cardMap = new Map<string, Card>()
|
||||
|
||||
// D'abord, on traite tous les fichiers audio
|
||||
for (const file of files) {
|
||||
const ext = extname(file).toLowerCase()
|
||||
|
||||
// On ne traite que les fichiers audio
|
||||
if (!listAudioExts.includes(ext)) continue
|
||||
|
||||
const parsed = await parseFilename(join(folderPath, file))
|
||||
if (parsed) {
|
||||
// On vérifie s'il existe une image avec le même nom de base
|
||||
const baseName = basename(file, ext)
|
||||
let imageUrl = ''
|
||||
|
||||
// On cherche une image correspondante
|
||||
for (const imgExt of listImageExts) {
|
||||
const potentialImage = baseName + imgExt
|
||||
if (files.includes(potentialImage)) {
|
||||
imageUrl = process.env.URL_PREFIX + baseName + imgExt
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cardMap.set(parsed.esid, {
|
||||
...parsed,
|
||||
url_audio: process.env.URL_PREFIX + baseName + ext,
|
||||
url_image: imageUrl,
|
||||
suit: parsed.suit,
|
||||
rank: parsed.rank
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(cardMap.values())
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du scan du dossier:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function parseFilename(
|
||||
filename: string
|
||||
): Promise<Omit<Card, 'url_audio' | 'url_image'> | null> {
|
||||
// Format: yyyymmddhh__artist__title.ext
|
||||
const nameWithoutExt = basename(filename, extname(filename))
|
||||
const parts = nameWithoutExt.split('__')
|
||||
|
||||
if (parts.length !== 3) {
|
||||
console.warn(`Nom de fichier invalide: ${filename}`)
|
||||
return null
|
||||
}
|
||||
|
||||
const [datetime, artist, title] = parts
|
||||
|
||||
if (!datetime || !artist || !title) {
|
||||
console.warn(`Format de fichier invalide: ${filename} - manque des parties`)
|
||||
return null
|
||||
}
|
||||
|
||||
if (datetime.length !== 10) {
|
||||
console.warn(`Format de date invalide: ${filename}`)
|
||||
return null
|
||||
}
|
||||
|
||||
// Utilisation d'un hash basé sur le contenu du fichier pour un ESID stable
|
||||
let fileHash = ''
|
||||
try {
|
||||
const fileContent = await readFile(filename)
|
||||
fileHash = createHash('md5').update(fileContent).digest('hex').substring(0, 8)
|
||||
} catch (error) {
|
||||
console.warn(`Impossible de lire le fichier pour générer le hash: ${filename}`)
|
||||
fileHash = createHash('md5').update(filename).digest('hex').substring(0, 8)
|
||||
}
|
||||
|
||||
const year = datetime.substring(0, 4)
|
||||
const month = datetime.substring(4, 6)
|
||||
const day = datetime.substring(6, 8)
|
||||
const hour = datetime.substring(8, 10)
|
||||
// Créer l'ID unique pour la card
|
||||
const esid = createHash('md5')
|
||||
.update(`${year}${month}${day}${hour}${artist}${title}`)
|
||||
.digest('hex')
|
||||
|
||||
const date = new Date(
|
||||
parseInt(year, 10),
|
||||
parseInt(month, 10) - 1,
|
||||
parseInt(day, 10),
|
||||
parseInt(hour, 10)
|
||||
)
|
||||
const card = getCardFromDate(date)
|
||||
|
||||
return {
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
artist: artist.replace(/_/g, ' '), // Remplacer les _ par des espaces
|
||||
title: title.replace(/_/g, ' '),
|
||||
esid,
|
||||
slug: slugify(`${artist} ${title}`),
|
||||
createdAt: date,
|
||||
suit: card.suit,
|
||||
rank: card.rank
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user