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:
rootandClaude Opus 5.5 committed 2026-10-01 00:08:17 +08:00
1 parent f60254e265
commit 87bf33b42b
29 files changed
+2272 -653

No files matched your search

+34 -26
View File
@@ -159,9 +159,6 @@ export type MediaAssetKind = "video" | "bluray_dir" | "subtitle" | "audio" | "nf
export type MediaAssetStatus = "active" | "replaced" | "retired" | "missing";
export type MediaEntityKind = "movie" | "series" | "variety" | "collection" | "other";
export type MediaEntityStatus = "provisional" | "active" | "merged" | "archived";
export type MediaScrapeStatus = "queued" | "running" | "succeeded" | "partial" | "failed";
export type MediaScrapeTrigger = "auto" | "manual";
export type MediaScrapeMode = "missing" | "overwrite";
export type MediaServerInstanceKind = "emby" | "jellyfin";
export type MediaServerInstanceHealthStatus = "unknown" | "healthy" | "degraded" | "offline";
export type MetadataEnrichmentStatus = "suggested" | "applied" | "failed";
@@ -226,6 +223,9 @@ export type ScheduledJobKind = "task" | "agent_check";
export type ScheduledJobLastStatus = "ok" | "failed" | "skipped" | "running";
export type ScheduledJobRunTrigger = "schedule" | "manual" | "skip";
export type ScheduledJobRunStatus = "ok" | "failed" | "skipped" | "running";
export type ScrapeRecordStatus = "queued" | "running" | "succeeded" | "partial" | "failed";
export type ScrapeRecordTrigger = "auto" | "manual";
export type ScrapeRecordMode = "missing" | "overwrite";
export type SecretPurpose =
| "site_cookie"
| "site_passkey"
@@ -918,25 +918,6 @@ export interface MediaEntityTable {
naming_override: Json | null;
}
export interface MediaScrapeTable {
media_entity_id: string;
status: Generated<MediaScrapeStatus>;
trigger: Generated<MediaScrapeTrigger>;
mode: Generated<MediaScrapeMode>;
record_id: string | null;
engine_run_id: string | null;
requested_at: GeneratedTimestamptz;
started_at: Timestamptz | null;
finished_at: Timestamptz | null;
written: Generated<number>;
skipped: Generated<number>;
failed: Generated<number>;
reason: string | null;
files: Generated<Json>;
created_at: GeneratedTimestamptz;
updated_at: GeneratedTimestamptz;
}
export interface MediaServerInstanceTable {
id: Generated<string>;
name: string;
@@ -1345,6 +1326,33 @@ export interface ScheduledJobRunTable {
created_at: GeneratedTimestamptz;
}
export interface ScrapeRecordTable {
id: Generated<string>;
root_id: string;
root_path: string;
library_root_id: string | null;
path: Generated<string>;
media_entity_id: string | null;
match: Json | null;
status: Generated<ScrapeRecordStatus>;
trigger: Generated<ScrapeRecordTrigger>;
mode: Generated<ScrapeRecordMode>;
organization_record_id: string | null;
engine_run_id: string | null;
actor_type: string | null;
actor_id: string | null;
requested_at: GeneratedTimestamptz;
started_at: Timestamptz | null;
finished_at: Timestamptz | null;
written: Generated<number>;
skipped: Generated<number>;
failed: Generated<number>;
reason: string | null;
files: Generated<Json>;
created_at: GeneratedTimestamptz;
updated_at: GeneratedTimestamptz;
}
export interface SecretTable {
id: Generated<string>;
name: string;
@@ -1720,7 +1728,6 @@ export interface DB {
mcp_server_config: McpServerConfigTable;
media_asset: MediaAssetTable;
media_entity: MediaEntityTable;
media_scrape: MediaScrapeTable;
media_server_instance: MediaServerInstanceTable;
metadata_enrichment: MetadataEnrichmentTable;
metadata_field: MetadataFieldTable;
@@ -1744,6 +1751,7 @@ export interface DB {
rule_group: RuleGroupTable;
scheduled_job: ScheduledJobTable;
scheduled_job_run: ScheduledJobRunTable;
scrape_record: ScrapeRecordTable;
secret: SecretTable;
server_mapping: ServerMappingTable;
settings: SettingsTable;
@@ -1881,9 +1889,6 @@ export type MediaAssetUpdate = Updateable<MediaAssetTable>;
export type MediaEntityRow = Selectable<MediaEntityTable>;
export type NewMediaEntity = Insertable<MediaEntityTable>;
export type MediaEntityUpdate = Updateable<MediaEntityTable>;
export type MediaScrapeRow = Selectable<MediaScrapeTable>;
export type NewMediaScrape = Insertable<MediaScrapeTable>;
export type MediaScrapeUpdate = Updateable<MediaScrapeTable>;
export type MediaServerInstanceRow = Selectable<MediaServerInstanceTable>;
export type NewMediaServerInstance = Insertable<MediaServerInstanceTable>;
export type MediaServerInstanceUpdate = Updateable<MediaServerInstanceTable>;
@@ -1953,6 +1958,9 @@ export type ScheduledJobUpdate = Updateable<ScheduledJobTable>;
export type ScheduledJobRunRow = Selectable<ScheduledJobRunTable>;
export type NewScheduledJobRun = Insertable<ScheduledJobRunTable>;
export type ScheduledJobRunUpdate = Updateable<ScheduledJobRunTable>;
export type ScrapeRecordRow = Selectable<ScrapeRecordTable>;
export type NewScrapeRecord = Insertable<ScrapeRecordTable>;
export type ScrapeRecordUpdate = Updateable<ScrapeRecordTable>;
export type SecretRow = Selectable<SecretTable>;
export type NewSecret = Insertable<SecretTable>;
export type SecretUpdate = Updateable<SecretTable>;