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
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
* 移植自 MoviePilot(https://github.com/jxxghp/MoviePilot,GPLv3),本文件按 GPLv3 条款提供。
|
||||
* @mp-source app/modules/indexer/parser/nexus_project.py @ e6820a8
|
||||
*
|
||||
* NexusProject 站点用户信息解析器,继承 NexusPHP 通用解析。
|
||||
*
|
||||
* 函数对照(`NexusProjectSiteUserInfo`):`_parse_site_page` → `_parseSitePage`(兼容 `user_detail.php?uid=` 变种)、
|
||||
* `_parse_user_traffic_info` → `_parseUserTrafficInfo`(兼容 `span#user_info` 无 B 后缀的流量文本)。正则逐字保留。
|
||||
*/
|
||||
import { reSearch } from "./common.ts";
|
||||
import { parseHtml } from "./dom.ts";
|
||||
import { NexusPhpSiteUserInfo, round3 } from "./nexus-php.ts";
|
||||
import { SiteSchema, type SiteSchemaValue } from "./types.ts";
|
||||
|
||||
export class NexusProjectSiteUserInfo extends NexusPhpSiteUserInfo {
|
||||
static override schema: SiteSchemaValue | null = SiteSchema.NexusProject;
|
||||
|
||||
protected override _parseSitePage(htmlText: string): void {
|
||||
const text = this._prepareHtmlText(htmlText);
|
||||
let userDetail = reSearch(/userdetails\.php\?id=(\d+)/, text);
|
||||
if (userDetail?.[0].trim()) {
|
||||
this._userDetailPage = userDetail[0].trim().replace(/^\/+/, "");
|
||||
this.userid = userDetail[1]!;
|
||||
} else {
|
||||
// 兼容部分 NexusProject 变种站点(如 star-space.net)的 p_user/user_detail.php?uid= 用户定位格式
|
||||
userDetail = reSearch(/user_detail\.php\?uid=(\d+)/, text);
|
||||
if (userDetail?.[0].trim()) {
|
||||
this._userDetailPage = userDetail[0].trim().replace(/^\/+/, "");
|
||||
this.userid = userDetail[1]!;
|
||||
const uname = reSearch(/user_detail\.php\?uid=\d+[^>]*?>\s*<[^>]*>([^<]+)</, text);
|
||||
if (uname) this.username = uname[1]!.trim();
|
||||
}
|
||||
}
|
||||
this._torrentSeedingPage = `viewusertorrents.php?id=${this.userid}&show=seeding`;
|
||||
}
|
||||
|
||||
protected override _parseUserTrafficInfo(htmlText: string): void {
|
||||
// 兼容 span#user_info / span#user_info_no_hover:"上传:445.11 G" / "下载:29.61 G"(单位无 B 后缀)
|
||||
try {
|
||||
const html = parseHtml(htmlText);
|
||||
if (html) {
|
||||
const bodyText = html
|
||||
.strings('//span[@id="user_info"]//text() | //span[@id="user_info_no_hover"]//text()')
|
||||
.join(" ");
|
||||
let m = reSearch(/上传[::]\s*([\d.,]+)\s*([GMKT]?i?B?)/i, bodyText);
|
||||
if (m) this.upload = this.numFilesize(`${m[1]!.replaceAll(",", "")} ${m[2]!.toUpperCase()}B`);
|
||||
m = reSearch(/下载[::]\s*([\d.,]+)\s*([GMKT]?i?B?)/i, bodyText);
|
||||
if (m) this.download = this.numFilesize(`${m[1]!.replaceAll(",", "")} ${m[2]!.toUpperCase()}B`);
|
||||
if (this.upload && this.download) this.ratio = round3(this.upload / this.download);
|
||||
if (this.upload || this.download) return;
|
||||
}
|
||||
} catch {
|
||||
// 与 MP 一致:吞掉异常回落到通用解析
|
||||
}
|
||||
super._parseUserTrafficInfo(htmlText);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user