feat(organize): 整理、季包选文件、刮削、文件管理识别统一套用集数映射;单集沿用资源判定,待确认文件不按原号入库

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-03 18:46:04 +08:00
1 parent 691671a1d2
commit fe597187dd
12 files changed
+848 -21

No files matched your search

+11
View File
@@ -67,6 +67,11 @@ export interface OrganizeInput {
export interface FileOverride {
season?: number;
episodes?: { start: number; end: number };
/**
* 不入库(调用方按作品集数映射判定:集数待确认 episode_unresolved、映射规则标为特别篇 / 花絮 / 忽略 special_extra);
* 只按精确路径生效,目录前缀覆写不带它
*/
exclude?: { reason: "episode_unresolved" | "special_extra"; detail?: string };
}
/** 源路径的覆写:精确命中优先,否则取最长的目录前缀 */
@@ -112,6 +117,7 @@ export interface ExcludedFile {
| "not_imported_kind"
| "orphan_sidecar"
| "no_episode"
| "episode_unresolved"
| "special_extra"
| "extra_content"
| "no_target_dir"
@@ -226,6 +232,11 @@ export function planOrganize(input: OrganizeInput): OrganizePlan {
}
const parsed = parseReleasePath(segmentsFor(f.path, input.sourceRoot), input.parse ?? {});
const ov = input.mediaType === "tv" ? overrideFor(input.overrides, f.path) : undefined;
const ex = input.mediaType === "tv" ? input.overrides?.[f.path]?.exclude : undefined;
if (ex) {
excluded.push({ src: f.path, kind, reason: ex.reason, ...(ex.detail ? { detail: ex.detail } : {}) });
continue;
}
if (ov?.season !== undefined) parsed.season = ov.season;
if (ov?.episodes) {
parsed.episodes = ov.episodes;