Files
UHD_Media_Tool/packages/adapters/src/sites/user-parsers/nexus-project.ts
T
rootandClaude Opus 5.5 d9f2af2f3c 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]>
2026-09-27 18:39:27 +08:00

59 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 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);
}
}