Files
hoerdle/scripts/restore_songs.ts
2025-11-28 15:36:06 +01:00

95 lines
3.2 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();
// Find genre by checking all genres (name is now JSON)
const allGenres = await prisma.genre.findMany();
let genre = allGenres.find(g => {
const name = g.name as any;
return (typeof name === 'string' && name === normalizedGenre) ||
(typeof name === 'object' && (name.de === normalizedGenre || name.en === normalizedGenre));
});
if (!genre) {
// Create with JSON structure
genre = await prisma.genre.create({
data: {
name: { de: normalizedGenre, en: normalizedGenre },
active: true
}
});
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();