96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { parseFile } from 'music-metadata';
|
|
import path from 'path';
|
|
import fs from 'fs/promises';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
export async function POST() {
|
|
try {
|
|
console.log('[Rebuild] Starting database rebuild...');
|
|
|
|
// 1. Clear Database
|
|
// Delete in order to respect foreign keys
|
|
await prisma.dailyPuzzle.deleteMany();
|
|
// We need to clear the many-to-many relations first implicitly by deleting songs/genres/specials
|
|
// But explicit deletion of join tables isn't needed with Prisma's cascading deletes usually,
|
|
// but let's be safe and delete main entities.
|
|
await prisma.song.deleteMany();
|
|
await prisma.genre.deleteMany();
|
|
await prisma.special.deleteMany();
|
|
|
|
console.log('[Rebuild] Database cleared.');
|
|
|
|
// 2. Clear Covers Directory
|
|
const coversDir = path.join(process.cwd(), 'public/uploads/covers');
|
|
try {
|
|
const coverFiles = await fs.readdir(coversDir);
|
|
for (const file of coverFiles) {
|
|
if (file !== '.gitkeep') { // Preserve .gitkeep if it exists
|
|
await fs.unlink(path.join(coversDir, file));
|
|
}
|
|
}
|
|
console.log('[Rebuild] Covers directory cleared.');
|
|
} catch (e) {
|
|
console.log('[Rebuild] Covers directory might not exist or empty, creating it.');
|
|
await fs.mkdir(coversDir, { recursive: true });
|
|
}
|
|
|
|
// 3. Re-import Songs
|
|
const uploadsDir = path.join(process.cwd(), 'public/uploads');
|
|
const files = await fs.readdir(uploadsDir);
|
|
const mp3Files = files.filter(f => f.endsWith('.mp3'));
|
|
|
|
console.log(`[Rebuild] Found ${mp3Files.length} MP3 files to import.`);
|
|
|
|
let importedCount = 0;
|
|
|
|
for (const filename of mp3Files) {
|
|
const filePath = path.join(uploadsDir, filename);
|
|
|
|
try {
|
|
const metadata = await parseFile(filePath);
|
|
|
|
const title = metadata.common.title || 'Unknown Title';
|
|
const artist = metadata.common.artist || 'Unknown Artist';
|
|
|
|
let coverImage = null;
|
|
const picture = metadata.common.picture?.[0];
|
|
|
|
if (picture) {
|
|
const extension = picture.format.split('/')[1] || 'jpg';
|
|
const coverFilename = `cover-${Date.now()}-${Math.random().toString(36).substring(7)}.${extension}`;
|
|
const coverPath = path.join(coversDir, coverFilename);
|
|
|
|
await fs.writeFile(coverPath, picture.data);
|
|
coverImage = coverFilename;
|
|
}
|
|
|
|
await prisma.song.create({
|
|
data: {
|
|
title,
|
|
artist,
|
|
filename,
|
|
coverImage
|
|
}
|
|
});
|
|
importedCount++;
|
|
} catch (e) {
|
|
console.error(`[Rebuild] Failed to process ${filename}:`, e);
|
|
}
|
|
}
|
|
|
|
console.log(`[Rebuild] Successfully imported ${importedCount} songs.`);
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
message: `Database rebuilt. Imported ${importedCount} songs.`
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('[Rebuild] Error:', error);
|
|
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
|
|
}
|
|
}
|