Redesign Nuggets upload portal: single episode submission form; v2.0.5
- Replace two-tab file picker with a combined form: episode name, passage, description, and audio file in one submit - Server now generates an Episode Info text file (name, host, passage, description, timestamp) and uploads it to /Episode Info/ automatically, while the audio goes to /Episode Upload/ - Drop zone changes color when a valid file is selected (green border) - Success shows submitted episode name and filename in the session log Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
afdc00114a
commit
6a03813914
3 files changed
+288
-249
No files matched your search
@@ -184,7 +184,7 @@ export function register(app) {
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// ── File upload ───────────────────────────────────────────────────────
|
||||
// ── Episode upload (audio file + metadata) ───────────────────────────
|
||||
|
||||
app.post('/api/nuggets-upload/upload', requireHostAuth, upload.single('file'), async (req, res) => {
|
||||
if (!req.file) {
|
||||
@@ -192,10 +192,19 @@ export function register(app) {
|
||||
return
|
||||
}
|
||||
|
||||
const targetDir = req.body?.targetDir === 'info' ? SEAFILE_EPISODE_INFO_DIR : SEAFILE_EPISODE_UPLOAD_DIR
|
||||
const session = getHostSession(req)
|
||||
const episodeName = typeof req.body?.episodeName === 'string' ? req.body.episodeName.trim() : ''
|
||||
const passage = typeof req.body?.passage === 'string' ? req.body.passage.trim() : ''
|
||||
const description = typeof req.body?.description === 'string' ? req.body.description.trim() : ''
|
||||
const originalName = req.file.originalname || req.file.filename
|
||||
const tempPath = req.file.path
|
||||
|
||||
if (!episodeName || !passage) {
|
||||
await unlink(tempPath).catch(() => {})
|
||||
res.status(400).json({ message: 'Episode name and passage are required.' })
|
||||
return
|
||||
}
|
||||
|
||||
if (!seafileConfigured()) {
|
||||
await unlink(tempPath).catch(() => {})
|
||||
res.status(503).json({ message: 'Seafile is not configured on this server. Contact the admin.' })
|
||||
@@ -206,14 +215,33 @@ export function register(app) {
|
||||
const { readFile: rf } = await import('node:fs/promises')
|
||||
const fileBuffer = await rf(tempPath)
|
||||
|
||||
const uploadLink = await getSeafileUploadLink(targetDir)
|
||||
await uploadToSeafile(uploadLink, fileBuffer, originalName, targetDir)
|
||||
|
||||
// Upload audio to /Episode Upload/
|
||||
const audioLink = await getSeafileUploadLink(SEAFILE_EPISODE_UPLOAD_DIR)
|
||||
await uploadToSeafile(audioLink, fileBuffer, originalName, SEAFILE_EPISODE_UPLOAD_DIR)
|
||||
await unlink(tempPath).catch(() => {})
|
||||
|
||||
const session = getHostSession(req)
|
||||
console.log(`[nuggets-upload] ${session?.hostName ?? 'unknown'} uploaded "${originalName}" to ${targetDir}`)
|
||||
res.json({ ok: true, filename: originalName, dir: targetDir })
|
||||
// Build and upload info file to /Episode Info/
|
||||
const now = new Date()
|
||||
const dateStr = now.toISOString().slice(0, 10)
|
||||
const infoContent = [
|
||||
`Episode: ${episodeName}`,
|
||||
`Host: ${session?.hostName ?? 'Unknown'}`,
|
||||
`Passage: ${passage}`,
|
||||
`Audio File: ${originalName}`,
|
||||
`Submitted: ${now.toUTCString()}`,
|
||||
'',
|
||||
'Description:',
|
||||
description || '(none)',
|
||||
].join('\n')
|
||||
|
||||
const safeEpName = episodeName.replace(/[^a-z0-9 _-]/gi, '').trim().replace(/\s+/g, '-').slice(0, 60)
|
||||
const infoFilename = `${dateStr}-${safeEpName}-info.txt`
|
||||
const infoBuffer = Buffer.from(infoContent, 'utf8')
|
||||
const infoLink = await getSeafileUploadLink(SEAFILE_EPISODE_INFO_DIR)
|
||||
await uploadToSeafile(infoLink, infoBuffer, infoFilename, SEAFILE_EPISODE_INFO_DIR)
|
||||
|
||||
console.log(`[nuggets-upload] ${session?.hostName ?? 'unknown'} uploaded "${episodeName}" (${originalName})`)
|
||||
res.json({ ok: true, episodeName, filename: originalName, infoFile: infoFilename })
|
||||
} catch (err) {
|
||||
await unlink(tempPath).catch(() => {})
|
||||
console.error('[nuggets-upload] upload error:', err.message)
|
||||
|
||||
Reference in new issue
Block a user