import { PrismaClient } from '@prisma/client'; import { parseFile } from 'music-metadata'; import path from 'path'; import fs from 'fs/promises'; const prisma = new PrismaClient(); const UPLOADS_DIR = path.join(process.cwd(), 'public/uploads'); async function restoreSongs() { console.log('Starting song restoration...'); try { const files = await fs.readdir(UPLOADS_DIR); const mp3Files = files.filter(f => f.endsWith('.mp3')); console.log(`Found ${mp3Files.length} MP3 files.`); for (const filename of mp3Files) { // Check if song already exists const existing = await prisma.song.findFirst({ where: { filename } }); if (existing) { console.log(`Skipping ${filename} (already exists)`); continue; } const filePath = path.join(UPLOADS_DIR, filename); try { const metadata = await parseFile(filePath); const title = metadata.common.title || 'Unknown Title'; const artist = metadata.common.artist || 'Unknown Artist'; // Try to find matching cover // This is a best-effort guess based on timestamp or just null if we can't link it easily // Since we don't store the link between file and cover in filename, we might lose cover association // unless we re-extract it. But we already have cover files. // For now, let's just restore the song entry. Re-extracting cover would duplicate files. // If the user wants covers back perfectly, we might need to re-parse or just leave null. // Let's leave null for now to avoid clutter, or maybe try to find a cover with similar timestamp if possible? // Actually, the cover filename is not easily deducible from song filename. // Let's just restore the song data. await prisma.song.create({ data: { title, artist, filename, // coverImage: null // We lose the cover link unfortunately, unless we re-extract } }); console.log(`Restored: ${title} - ${artist}`); } catch (e) { console.error(`Failed to process ${filename}:`, e); } } console.log('Restoration complete.'); } catch (e) { console.error('Error reading uploads directory:', e); } finally { await prisma.$disconnect(); } } restoreSongs();