Spaces:
No application file
No application file
| import { Router, Request, Response } from "express"; | |
| import { getJob, updateJob } from "./jobStore"; | |
| import { refreshLibrary } from "./jellyfinClient"; | |
| const router = Router(); | |
| /** | |
| * Marks a job ready and kicks Jellyfin to rescan the library. | |
| * | |
| * This is called directly by the in-process downloader in downloadRoutes.ts, | |
| * but it's also exposed as a real HTTP endpoint below so a future external | |
| * downloader/worker (or a manual retry) can report completion the same way. | |
| */ | |
| export async function markDownloadComplete(jobId: string): Promise<void> { | |
| const job = getJob(jobId); | |
| if (!job) return; | |
| updateJob(jobId, { status: "ready", progress: 100 }); | |
| try { | |
| await refreshLibrary(); | |
| } catch (err: any) { | |
| // The file is still safely on disk even if Jellyfin's refresh call fails | |
| // (e.g. Jellyfin isn't configured yet) — surface it on the job, but don't | |
| // mark the download itself as failed. | |
| updateJob(jobId, { | |
| error: `Saved, but Jellyfin refresh failed: ${err?.message || "unknown error"}`, | |
| }); | |
| } | |
| } | |
| // POST /api/webhook/download-complete — { jobId } | |
| // External callers (a worker, a manual curl, etc.) can report completion here. | |
| router.post("/webhook/download-complete", async (req: Request, res: Response) => { | |
| const { jobId } = req.body || {}; | |
| if (typeof jobId !== "string") { | |
| return res.status(400).json({ error: "'jobId' is required." }); | |
| } | |
| const job = getJob(jobId); | |
| if (!job) { | |
| return res.status(404).json({ error: "No job with that id." }); | |
| } | |
| await markDownloadComplete(jobId); | |
| res.json({ ok: true }); | |
| }); | |
| export default router; | |