Files
hoerdle/scripts/restore_songs.ts

83 lines
2.6 KiB
TypeScript

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';
const genres = metadata.common.genre || [];
// Create or find genres
const genreConnect = [];
for (const genreName of genres) {
if (!genreName) continue;
// Simple normalization
const normalizedGenre = genreName.trim();
// Upsert genre (we can't use upsert easily with connect, so find or create first)
let genre = await prisma.genre.findUnique({ where: { name: normalizedGenre } });
if (!genre) {
genre = await prisma.genre.create({ data: { name: normalizedGenre } });
console.log(`Created genre: ${normalizedGenre}`);
}
genreConnect.push({ id: genre.id });
}
await prisma.song.create({
data: {
title,
artist,
filename,
genres: {
connect: genreConnect
}
}
});
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();