63 lines
1.6 KiB
TypeScript
63 lines
1.6 KiB
TypeScript
import { Hono } from "hono";
|
|
import { res } from "../response.js";
|
|
import type { SeederRegistry } from "../SeederRegistry.js";
|
|
|
|
export function torrentsRouter(registry: SeederRegistry) {
|
|
const app = new Hono();
|
|
|
|
/** List all active torrents with their current stats */
|
|
app.get("/", (c) => {
|
|
return c.json(registry.listTorrents());
|
|
});
|
|
|
|
/** Add a torrent — accepts multipart/form-data with a 'torrent' file field */
|
|
app.post("/", async (c) => {
|
|
const body = await c.req.parseBody();
|
|
const file = body.torrent;
|
|
|
|
if (!file || typeof file === "string") {
|
|
return res.badRequest(c, "Missing 'torrent' file field");
|
|
}
|
|
|
|
const buf = Buffer.from(await (file as File).arrayBuffer());
|
|
|
|
try {
|
|
const state = await registry.addTorrent(buf);
|
|
return res.created(c, state);
|
|
} catch (err) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
return res.unprocessable(c, msg);
|
|
}
|
|
});
|
|
|
|
/** Get stats + announce history for a specific torrent */
|
|
app.get("/:hash", (c) => {
|
|
const { hash } = c.req.param();
|
|
const list = registry.listTorrents();
|
|
const torrent = list.find((t) => t.infoHashHex === hash);
|
|
|
|
if (!torrent) {
|
|
return res.notFound(c);
|
|
}
|
|
|
|
return c.json({
|
|
...torrent,
|
|
history: registry.getHistory(hash),
|
|
});
|
|
});
|
|
|
|
/** Remove a torrent — sends 'stopped' to trackers then removes it */
|
|
app.delete("/:hash", async (c) => {
|
|
const { hash } = c.req.param();
|
|
const removed = await registry.removeTorrent(hash);
|
|
|
|
if (!removed) {
|
|
return res.notFound(c);
|
|
}
|
|
|
|
return c.json({ ok: true });
|
|
});
|
|
|
|
return app;
|
|
}
|