feat(adapters): port MoviePilot open site framework (7 spiders, 20 user parsers) + MovieClaw v0.27.0 site definitions + mp-sync tools (W1-3c)
- sites/spiders: Haidan/HDDolby/RousiPro/SunnyPT/TNode/TorrentLeech/Yema (+mTorrent wrapper), specialized SiteAdapter, indirect download resolved at download time - sites/user-parsers: SiteParserBase + all 20 MP SiteSchema parsers (lxml XPath via xpath+xmldom), refreshSiteUserData with schema fallback - sites/definitions: zod SiteDefinition schemas, 23 MovieClaw v0.27.0 (MIT) definitions via scripts/mp-sync/movieclaw-import.mjs, registry getSiteDefinition/listSiteDefinitions, NOTICE - scripts/mp-sync: ledger.json (upstream sha256), check.mjs, build-ledger.mjs; docs/porting/mp-sync-ledger.md - license-and-provenance: add copied-mit kind, re-anchor MovieClaw rows to v0.27.0 Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
cf85481d95
commit
d9f2af2f3c
166 files changed
+16577
-186
No files matched your search
@@ -1,16 +1,48 @@
|
||||
import type { IndexerDefinition } from "../spider/schema";
|
||||
import audiencesJson from "./audiences.json";
|
||||
/**
|
||||
* 站点定义加载与校验。
|
||||
* - `*.json`:由 scripts/mp-sync/movieclaw-import.mjs 从 MovieClaw v0.27.0(MIT,见 NOTICE-MovieClaw.md)转换,
|
||||
* 手工覆盖层在 scripts/mp-sync/movieclaw-overrides/;不要直接手改 JSON(重跑脚本会覆盖)。
|
||||
* - 加载时一律经 zod schema(./schema.ts)校验,失败即抛错。
|
||||
*/
|
||||
import type { MteamDefinition } from "../mteam/definition.ts";
|
||||
import type { IndexerDefinition } from "../spider/schema.ts";
|
||||
import type { SpecializedSiteDefinition } from "../spiders/types.ts";
|
||||
import { MOVIECLAW_DEFINITION_JSON } from "./manifest.generated.ts";
|
||||
import { parseIndexerDefinition, parseMteamDefinition, parseSpecializedSiteDefinition } from "./schema.ts";
|
||||
|
||||
/** 站点定义最小校验(随产品发布的定义文件;加站只需新增 JSON 并在此登记)。 */
|
||||
export function loadIndexerDefinition(json: unknown): IndexerDefinition {
|
||||
const d = json as Partial<IndexerDefinition>;
|
||||
if (!d || typeof d !== "object") throw new Error("站点定义必须是对象");
|
||||
for (const k of ["id", "name", "domain"] as const) {
|
||||
if (typeof d[k] !== "string" || !d[k]) throw new Error(`站点定义缺少 ${k}`);
|
||||
}
|
||||
if (!d.torrents?.list?.selector || !d.torrents.fields) throw new Error(`站点定义 ${d.id} 缺少 torrents.list/fields`);
|
||||
if (!d.umt?.version || !d.umt.timezone || !d.umt.rateLimit) throw new Error(`站点定义 ${d.id} 缺少 umt 扩展`);
|
||||
return d as IndexerDefinition;
|
||||
export type SiteDefinition = IndexerDefinition | MteamDefinition | SpecializedSiteDefinition;
|
||||
|
||||
/** 按 `umt.kind` 分派校验 */
|
||||
export function loadSiteDefinition(json: unknown): SiteDefinition {
|
||||
const kind = (json as { umt?: { kind?: unknown } } | null)?.umt?.kind;
|
||||
if (kind === "mteam") return parseMteamDefinition(json);
|
||||
if (kind === "nexusphp") return parseIndexerDefinition(json);
|
||||
if (kind === "api") return parseSpecializedSiteDefinition(json);
|
||||
throw new Error(`站点定义 ${(json as { id?: unknown })?.id ?? "<unknown>"} 的 umt.kind 未知:${String(kind)}`);
|
||||
}
|
||||
|
||||
export const audiencesDefinition: IndexerDefinition = loadIndexerDefinition(audiencesJson);
|
||||
/** 兼容 W1-3b 导出名:NexusPHP 定义校验 */
|
||||
export function loadIndexerDefinition(json: unknown): IndexerDefinition {
|
||||
return parseIndexerDefinition(json);
|
||||
}
|
||||
|
||||
/** 随产品发布的全部定义(已校验),键为站点 id */
|
||||
export const BUILTIN_SITE_DEFINITIONS: Readonly<Record<string, SiteDefinition>> = Object.freeze(
|
||||
Object.fromEntries(Object.entries(MOVIECLAW_DEFINITION_JSON).map(([id, json]) => [id, loadSiteDefinition(json)])),
|
||||
);
|
||||
|
||||
export const audiencesDefinition = BUILTIN_SITE_DEFINITIONS.audiences as IndexerDefinition;
|
||||
export const hhanclubDefinition = BUILTIN_SITE_DEFINITIONS.hhanclub as IndexerDefinition;
|
||||
export const chdbitsDefinition = BUILTIN_SITE_DEFINITIONS.chdbits as IndexerDefinition;
|
||||
|
||||
export {
|
||||
DefinitionProvenanceSchema,
|
||||
IndexerDefinitionSchema,
|
||||
MteamDefinitionSchema,
|
||||
parseIndexerDefinition,
|
||||
parseMteamDefinition,
|
||||
parseSpecializedSiteDefinition,
|
||||
SpecializedSiteDefinitionSchema,
|
||||
SpiderFieldSelectorSchema,
|
||||
SpiderFilterSchema,
|
||||
} from "./schema.ts";
|
||||
Reference in new issue
Block a user