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 { try { const files = await readdir(folderPath) const cardMap = new Map() // 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 | 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 } }