import { readFile, writeFile } from 'node:fs/promises' import { sendNuggetsUploadNotification } from './email.js' import { SEAFILE_URL, SEAFILE_TOKEN, SEAFILE_NUGGETS_REPO_ID, SEAFILE_EPISODE_UPLOAD_DIR, SEAFILE_EPISODE_INFO_DIR, SEAFILE_POLL_INTERVAL_MS, NUGGETS_SEAFILE_SEEN_FILE, NUGGETS_NOTIFY_EMAIL, } from './config.js' async function loadSeen() { try { return JSON.parse(await readFile(NUGGETS_SEAFILE_SEEN_FILE, 'utf8')) } catch { return { files: [] } } } async function saveSeen(data) { await writeFile(NUGGETS_SEAFILE_SEEN_FILE, JSON.stringify(data, null, 2), 'utf8') } // Called by the upload route after a successful portal upload so the poller // doesn't also fire a notification for the same file. export async function markSeafileFileSeen(filename) { const data = await loadSeen() if (!data.files.includes(filename)) { data.files.push(filename) await saveSeen(data) } } async function listSeafileDir(dir) { if (!SEAFILE_URL || !SEAFILE_TOKEN || !SEAFILE_NUGGETS_REPO_ID) return [] try { const url = `${SEAFILE_URL}/api2/repos/${SEAFILE_NUGGETS_REPO_ID}/dir/?p=${encodeURIComponent(dir)}` const res = await fetch(url, { headers: { Authorization: `Token ${SEAFILE_TOKEN}` }, signal: AbortSignal.timeout(10_000), }) if (!res.ok) return [] const data = await res.json() return (data.dirent ?? []).filter(e => e.type === 'file').map(e => e.name) } catch { return [] } } async function poll() { if (!SEAFILE_URL || !SEAFILE_TOKEN || !SEAFILE_NUGGETS_REPO_ID) return const [uploadFiles, seen] = await Promise.all([ listSeafileDir(SEAFILE_EPISODE_UPLOAD_DIR), loadSeen(), ]) const seenSet = new Set(seen.files) const newFiles = uploadFiles.filter(f => !seenSet.has(f)) if (newFiles.length === 0) return for (const filename of newFiles) { console.log(`[nuggets-watcher] new direct upload detected: ${filename}`) await sendNuggetsUploadNotification({ to: NUGGETS_NOTIFY_EMAIL, source: 'direct', filename, }) seenSet.add(filename) } seen.files = [...seenSet] await saveSeen(seen) } export function startNuggetsSeafileWatcher() { if (!SEAFILE_URL || !SEAFILE_TOKEN || !SEAFILE_NUGGETS_REPO_ID) { console.log('[nuggets-watcher] Seafile not configured — watcher disabled.') return } // Initial poll after 2 min (let the server settle), then every 15 min setTimeout(() => { poll().catch(err => console.error('[nuggets-watcher] poll error:', err)) setInterval(() => { poll().catch(err => console.error('[nuggets-watcher] poll error:', err)) }, SEAFILE_POLL_INTERVAL_MS) }, 2 * 60 * 1000) console.log(`[nuggets-watcher] started — polling every ${SEAFILE_POLL_INTERVAL_MS / 60000} min`) }