first working demo
This commit is contained in:
156
src/routes/admin/audio/+page.server.js
Normal file
156
src/routes/admin/audio/+page.server.js
Normal file
@@ -0,0 +1,156 @@
|
||||
import { fail } from '@sveltejs/kit';
|
||||
import { db } from '$lib/server/db/index.js';
|
||||
import { audioFile } from '$lib/server/db/schema.js';
|
||||
import { eq, isNull } from 'drizzle-orm';
|
||||
import { uploadToS3, deleteFromS3, generateAudioS3Key } from '$lib/server/s3.js';
|
||||
|
||||
export async function load() {
|
||||
const audioFiles = await db.select({
|
||||
id: audioFile.id,
|
||||
filename: audioFile.filename,
|
||||
contentType: audioFile.contentType,
|
||||
duration: audioFile.duration,
|
||||
fileSize: audioFile.fileSize,
|
||||
createdAt: audioFile.createdAt
|
||||
})
|
||||
.from(audioFile)
|
||||
.where(isNull(audioFile.deletedAt)); // Only show active audio files
|
||||
|
||||
return {
|
||||
audioFiles
|
||||
};
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
upload: async ({ request }) => {
|
||||
const data = await request.formData();
|
||||
const file = data.get('audioFile');
|
||||
|
||||
if (!file || file.size === 0) {
|
||||
return fail(400, {
|
||||
missing: true
|
||||
});
|
||||
}
|
||||
|
||||
if (!file.type.startsWith('audio/')) {
|
||||
return fail(400, {
|
||||
invalidType: true
|
||||
});
|
||||
}
|
||||
|
||||
const id = crypto.randomUUID();
|
||||
const buffer = Buffer.from(await file.arrayBuffer());
|
||||
const s3Key = generateAudioS3Key(id, file.name);
|
||||
|
||||
try {
|
||||
// Upload to S3 first
|
||||
await uploadToS3(s3Key, buffer, file.type);
|
||||
|
||||
// Then save metadata to database (without blob data)
|
||||
await db.insert(audioFile).values({
|
||||
id,
|
||||
filename: file.name,
|
||||
contentType: file.type,
|
||||
s3Key,
|
||||
duration: null, // Will be updated by client-side after upload
|
||||
fileSize: file.size,
|
||||
createdAt: new Date()
|
||||
});
|
||||
|
||||
return {
|
||||
success: true
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error uploading audio file:', error);
|
||||
return fail(500, {
|
||||
error: error.message || 'Upload failed'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
delete: async ({ request }) => {
|
||||
const data = await request.formData();
|
||||
const fileId = data.get('fileId');
|
||||
|
||||
if (!fileId) {
|
||||
return fail(400, {
|
||||
missing: true
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// Soft delete from database (don't delete from S3 for recovery purposes)
|
||||
await db
|
||||
.update(audioFile)
|
||||
.set({ deletedAt: new Date() })
|
||||
.where(eq(audioFile.id, fileId));
|
||||
|
||||
return {
|
||||
deleted: true
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error deleting audio file:', error);
|
||||
return fail(500, {
|
||||
error: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
updateDuration: async ({ request }) => {
|
||||
const data = await request.formData();
|
||||
const fileId = data.get('fileId');
|
||||
const duration = parseFloat(data.get('duration'));
|
||||
|
||||
if (!fileId || isNaN(duration)) {
|
||||
return fail(400, {
|
||||
missing: true
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await db.update(audioFile)
|
||||
.set({ duration })
|
||||
.where(eq(audioFile.id, fileId));
|
||||
return {
|
||||
success: true
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error updating duration:', error);
|
||||
return fail(500, {
|
||||
error: true
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
renameAudioFile: async ({ request }) => {
|
||||
const data = await request.formData();
|
||||
const audioFileId = data.get('audioFileId');
|
||||
const newFilename = data.get('newFilename');
|
||||
|
||||
if (!audioFileId || !newFilename) {
|
||||
return fail(400, { error: 'Invalid data provided' });
|
||||
}
|
||||
|
||||
// Validate filename
|
||||
const filename = newFilename.trim();
|
||||
if (filename.length === 0) {
|
||||
return fail(400, { error: 'Filename cannot be empty' });
|
||||
}
|
||||
|
||||
if (filename.length > 255) {
|
||||
return fail(400, { error: 'Filename is too long' });
|
||||
}
|
||||
|
||||
try {
|
||||
await db
|
||||
.update(audioFile)
|
||||
.set({ filename })
|
||||
.where(eq(audioFile.id, audioFileId));
|
||||
|
||||
return { renamed: true, filename };
|
||||
} catch (error) {
|
||||
console.error('Error renaming audio file:', error);
|
||||
return fail(500, { error: 'Failed to rename audio file' });
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user