File size: 1,617 Bytes
972b772
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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;