feat: Add cover art support and auto-migration
- Extract cover art from MP3s during upload - Display cover art in game result screens (win/loss) - Add coverImage field to Song model - Add migration script to backfill covers for existing songs - Configure Docker to run migration script on startup
This commit is contained in:
@@ -21,6 +21,7 @@ export async function GET() {
|
||||
artist: song.artist,
|
||||
filename: song.filename,
|
||||
createdAt: song.createdAt,
|
||||
coverImage: song.coverImage,
|
||||
activations: song.puzzles.length,
|
||||
}));
|
||||
|
||||
@@ -62,11 +63,30 @@ export async function POST(request: Request) {
|
||||
|
||||
await writeFile(path.join(uploadDir, filename), buffer);
|
||||
|
||||
// Handle cover image
|
||||
let coverImage = null;
|
||||
try {
|
||||
const metadata = await parseBuffer(buffer, file.type);
|
||||
const picture = metadata.common.picture?.[0];
|
||||
|
||||
if (picture) {
|
||||
const extension = picture.format.split('/')[1] || 'jpg';
|
||||
const coverFilename = `cover-${Date.now()}.${extension}`;
|
||||
const coverPath = path.join(process.cwd(), 'public/uploads/covers', coverFilename);
|
||||
|
||||
await writeFile(coverPath, picture.data);
|
||||
coverImage = coverFilename;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to extract cover image:', e);
|
||||
}
|
||||
|
||||
const song = await prisma.song.create({
|
||||
data: {
|
||||
title,
|
||||
artist,
|
||||
filename,
|
||||
coverImage,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -123,6 +143,16 @@ export async function DELETE(request: Request) {
|
||||
// Continue with DB deletion even if file deletion fails
|
||||
}
|
||||
|
||||
// Delete cover image if exists
|
||||
if (song.coverImage) {
|
||||
const coverPath = path.join(process.cwd(), 'public/uploads/covers', song.coverImage);
|
||||
try {
|
||||
await unlink(coverPath);
|
||||
} catch (e) {
|
||||
console.error('Failed to delete cover image:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete from database (will cascade delete related puzzles)
|
||||
await prisma.song.delete({
|
||||
where: { id: Number(id) },
|
||||
|
||||
Reference in New Issue
Block a user