feat(scrape): 任意目录就地刮削,按路径识别作品,每次刮削一条记录(SCR-2)
- POST /files/scrape 改为对目录 / 视频文件刮削:已登记用作品,否则按路径识别(本地 + TMDB), 认不准返回候选,选定后再提交;未登记直接用 TMDB 字段,addToLibrary 顺手建作品 - 作品详情重新刮削、入库后自动刮削改为对作品目录刮削,同一实现 - 迁移 0058_scrape_record 替代 media_scrape;GET /files/scrape-records - 与 MP ScrapingChain 的文件布局差分(7 个场景,3 处登记偏离) Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
f60254e265
commit
87bf33b42b
29 files changed
+2272
-653
No files matched your search
@@ -14,7 +14,7 @@ import {
|
||||
} from "./harness.ts";
|
||||
|
||||
// identify(只读,本地 + 远端召回前 5,不落库)、organize(按作品分组走 planImport,dryRun→execute 一致与源变更)、
|
||||
// probe(已登记写回 media_info)、scrape(仅已登记作品,入队 refreshMetadata;NFO 待 W5)。
|
||||
// probe(已登记写回 media_info)、刷新元数据(scrape-batch,入队 refreshMetadata)。
|
||||
|
||||
const skip = !(await pgAvailable());
|
||||
|
||||
@@ -278,7 +278,7 @@ describe.skipIf(skip)("files 识别 / 整理 / 探测 / 刮削", () => {
|
||||
expect(r.status).toBeLessThan(500);
|
||||
});
|
||||
|
||||
it("probe:已登记资产写回 media_info;scrape 仅已登记作品", async () => {
|
||||
it("probe:已登记资产写回 media_info;刷新元数据按作品入队", async () => {
|
||||
await mkdir(join(h.lib, "Blue Film probe"));
|
||||
await writeFile(join(h.lib, "Blue Film probe", "Blue.Film.2021.mkv"), "x");
|
||||
const a = await seedAsset(h.db, h, { entityId: film, rel: "Blue Film probe/Blue.Film.2021.mkv" });
|
||||
@@ -303,21 +303,10 @@ describe.skipIf(skip)("files 识别 / 整理 / 探测 / 刮削", () => {
|
||||
const u2 = await h.api("POST", "/files/probe", { items: [{ root: h.dlRoot, path: "Remote.Film.2019.1080p.mkv" }] });
|
||||
expect(u2.body.data.items[0].cached).toBe(true);
|
||||
|
||||
const s = await h.api("POST", "/files/scrape", { idempotencyKey: key(), mediaEntityId: film, writeNfo: true });
|
||||
expect(s.status).toBe(200);
|
||||
// SCR-1:writeNfo 另排 scrapeMedia(写 NFO 与图片到媒体库目录)
|
||||
expect(s.body.data).toMatchObject({ mediaEntityId: film, nfo: "queued", images: "not_requested" });
|
||||
expect(s.body.data.scrapeTaskId).toBeTruthy();
|
||||
expect(h.engine.enqueued.some((e) => e.task === "refreshMetadata")).toBe(true);
|
||||
expect(h.engine.enqueued.some((e) => e.task === "scrapeMedia")).toBe(true);
|
||||
const b = await h.api("POST", "/files/scrape-batch", {
|
||||
idempotencyKey: key(),
|
||||
mediaEntityIds: [film],
|
||||
write: true,
|
||||
});
|
||||
// 刷新元数据(scrape-batch):按作品入队 refreshMetadata;刮削(写 NFO)见 scrape.test.ts
|
||||
const b = await h.api("POST", "/files/scrape-batch", { idempotencyKey: key(), mediaEntityIds: [film] });
|
||||
expect(b.status).toBe(200);
|
||||
expect(b.body.data.submitted).toHaveLength(1);
|
||||
const none = await h.api("POST", "/files/scrape", { idempotencyKey: key(), mediaEntityId: show });
|
||||
expect(none.status).toBe(400);
|
||||
expect(h.engine.enqueued.some((e) => e.task === "refreshMetadata")).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user