feat: watcher akislarini ve wscraper servis entegrasyonunu ekle
This commit is contained in:
116
apps/server/src/watcher/watcher.routes.ts
Normal file
116
apps/server/src/watcher/watcher.routes.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import { Router } from "express";
|
||||
import { z } from "zod";
|
||||
import {
|
||||
createWatcher,
|
||||
deleteWatcher,
|
||||
fetchWatcherImage,
|
||||
getQbitCategories,
|
||||
getWatcherItems,
|
||||
getWatcherSummary,
|
||||
listTrackers,
|
||||
listWatchers,
|
||||
runWatcherById,
|
||||
updateWatcher,
|
||||
} from "./watcher.service";
|
||||
|
||||
const router = Router();
|
||||
|
||||
const createWatcherSchema = z.object({
|
||||
tracker: z.string().min(1),
|
||||
cookie: z.string().min(1),
|
||||
intervalMinutes: z.number().int().min(1).max(24 * 60),
|
||||
category: z.string().optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
});
|
||||
|
||||
const updateWatcherSchema = z.object({
|
||||
cookie: z.string().min(1).optional(),
|
||||
intervalMinutes: z.number().int().min(1).max(24 * 60).optional(),
|
||||
category: z.string().optional(),
|
||||
enabled: z.boolean().optional(),
|
||||
});
|
||||
|
||||
router.get("/trackers", (_req, res) => {
|
||||
return res.json(listTrackers());
|
||||
});
|
||||
|
||||
router.get("/categories", async (_req, res) => {
|
||||
try {
|
||||
return res.json(await getQbitCategories());
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Failed to load qBittorrent categories" });
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/", async (_req, res) => {
|
||||
return res.json(await listWatchers());
|
||||
});
|
||||
|
||||
router.post("/", async (req, res) => {
|
||||
const parsed = createWatcherSchema.safeParse(req.body ?? {});
|
||||
if (!parsed.success) {
|
||||
return res.status(400).json({ error: "Invalid watcher payload" });
|
||||
}
|
||||
try {
|
||||
const watcher = await createWatcher(parsed.data);
|
||||
return res.status(201).json(watcher);
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Failed to create watcher" });
|
||||
}
|
||||
});
|
||||
|
||||
router.patch("/:id", async (req, res) => {
|
||||
const parsed = updateWatcherSchema.safeParse(req.body ?? {});
|
||||
if (!parsed.success) {
|
||||
return res.status(400).json({ error: "Invalid watcher payload" });
|
||||
}
|
||||
try {
|
||||
const watcher = await updateWatcher(req.params.id, parsed.data);
|
||||
return res.json(watcher);
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Failed to update watcher" });
|
||||
}
|
||||
});
|
||||
|
||||
router.delete("/:id", async (req, res) => {
|
||||
try {
|
||||
return res.json(await deleteWatcher(req.params.id));
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Failed to delete watcher" });
|
||||
}
|
||||
});
|
||||
|
||||
router.post("/:id/run", async (req, res) => {
|
||||
try {
|
||||
await runWatcherById(req.params.id);
|
||||
return res.json({ ok: true });
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Watcher run failed" });
|
||||
}
|
||||
});
|
||||
|
||||
router.get("/summary", async (_req, res) => {
|
||||
return res.json(await getWatcherSummary());
|
||||
});
|
||||
|
||||
router.get("/items", async (_req, res) => {
|
||||
return res.json(await getWatcherItems());
|
||||
});
|
||||
|
||||
router.get("/image", async (req, res) => {
|
||||
const watcherId = String(req.query.watcherId ?? "");
|
||||
const imageUrl = String(req.query.url ?? "");
|
||||
if (!watcherId || !imageUrl) {
|
||||
return res.status(400).json({ error: "Missing watcherId or url" });
|
||||
}
|
||||
try {
|
||||
const image = await fetchWatcherImage(watcherId, imageUrl);
|
||||
res.setHeader("Content-Type", image.contentType);
|
||||
res.setHeader("Cache-Control", "private, max-age=300");
|
||||
return res.send(image.data);
|
||||
} catch (error) {
|
||||
return res.status(400).json({ error: error instanceof Error ? error.message : "Failed to fetch image" });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Reference in New Issue
Block a user