fix(sites): OurBits 详情页按 BBCode 解析简介

OurBits 的简介在 div.ubbcode 里是未渲染的 BBCode(站点前端脚本渲染),按 HTML 取文本后
[quote] / [img] / [url] 原样留下、换行全被合并。extractDetailPage 遇到 ubbcode 容器且内容带 BBCode 标记时,
改用 pageFromBbcode 取简介 / 截图 / MediaInfo(换行保留),发布者、文件、标签与页面上的外部 ID 照旧。
覆盖层补 fileListPath(viewfilelist.php),与憨憨一样按需取文件列表。脱敏样例 OURBITS_DETAIL_PAGE + 测试。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 20:59:41 +08:00
1 parent ee128e0b3f
commit 9cdf492291
6 files changed
+72 -1

No files matched your search

@@ -6,6 +6,7 @@ import {
HHANCLUB_LIST_PAGE,
HHANCLUB_LIST_PAGE_2026,
HHANCLUB_LIST_PAGE_TAGS,
OURBITS_DETAIL_PAGE,
OURBITS_LIST_PAGE,
} from "@umt/testkit";
import { describe, expect, it } from "vitest";
@@ -234,6 +235,19 @@ describe("2026-10 真实列表页结构(脱敏样例)", () => {
expect(a!.tags).toEqual(["官方", "中字"]);
});
it("OurBits 详情:ubbcode 里的 BBCode 简介保留换行、去掉标记,图片进截图,引用块里的 MediaInfo 单独取", () => {
const def = BUILTIN_SITE_DEFINITIONS.ourbits as IndexerDefinition;
const page = parseDetailPage(OURBITS_DETAIL_PAGE, def, "900001", OBSERVED).detail!.page!;
expect(page.descriptionText).toContain("官组作品,感谢原制作者发布。\n");
expect(page.descriptionText).toContain("◎片  名 示例剧\n◎年  代 2025");
expect(page.descriptionText).not.toMatch(/\[(img|url|quote|b|color)/);
expect(page.descriptionText).not.toContain("Complete name");
expect(page.mediaInfo).toMatch(/^General\nComplete name/);
expect(page.screenshots).toEqual(["https://img.example.test/poster.jpg", "https://img.example.test/shot1.jpg"]);
expect(page.doubanId).toBe("36000001");
expect(def.umt.detail?.page?.fileListPath).toBe("viewfilelist.php?id={id}");
});
it("IMDb ID 规范化:纯数字补 tt + 7 位,0 与非法值丢弃", () => {
expect(imdbIdOf("299977")).toBe("tt0299977");
expect(imdbIdOf("35522483")).toBe("tt35522483");
@@ -269,6 +269,9 @@
"imdb": "a[href*='imdb.com']::attr(href)",
"douban": "a[href*='douban.com']::attr(href)",
"fileList": "td.rowfollow > ul > li::text"
},
"page": {
"fileListPath": "viewfilelist.php?id={id}"
}
},
"customClass": "movieclaw_tracker.sites.custom.ourbits.OurBitsSite"
@@ -11,6 +11,7 @@ import {
looksLikeMediaInfo,
MAX_FILES,
MAX_SCREENSHOTS,
pageFromBbcode,
screenshotUrl,
tidyText,
} from "../detail-text.ts";
@@ -284,5 +285,22 @@ export function extractDetailPage($: CheerioAPI, conf: DetailConf, base: string)
}
}
}
// 简介是未渲染的 BBCode 原文(OurBits:div.ubbcode,站点靠前端脚本渲染):按 BBCode 取简介 / 截图 / MediaInfo,
// 换行保留;发布者、文件、标签与 HTML 上的外部 ID 照旧
const ubb = desc?.length ? (desc.is(".ubbcode") ? desc : desc.find(".ubbcode").first()) : null;
const raw = ubb?.length ? ubb.text() : "";
if (/\[(?:img|url|quote|b|color|size|code)\b[^\]]*\]/i.test(raw)) {
const b = pageFromBbcode(raw, base, { mediaInfo: page.mediaInfo });
page.descriptionText = b.descriptionText;
page.mediaInfo = b.mediaInfo;
if (b.screenshots.length) {
page.screenshots = b.screenshots;
page.probe.imageCount = b.probe.imageCount;
}
page.imdbId ??= b.imdbId;
page.doubanId ??= b.doubanId;
page.tmdb ??= b.tmdb;
}
return page;
}
@@ -68,3 +68,29 @@ export const HHANCLUB_LIST_PAGE_TAGS = `<!DOCTYPE html><html><head><title>HHCLUB
<div class="torrent-manage"><a href="download.php?id=900201">下载</a></div>
</div>
</body></html>`;
/** OurBits 详情页:简介是 div.ubbcode 里未渲染的 BBCode(站点靠前端脚本渲染),文件列表要另取 viewfilelist.php */
export const OURBITS_DETAIL_PAGE = `<!DOCTYPE html><html><head><title>OurBits :: 种子详情</title></head><body>
<a href="logout.php">退出</a>
<h1 id="top">Sample Show 2025 S01 2160p WEB-DL H265 AAC-UBWEB</h1>
<table width="100%">
<tr><td class="rowhead">副标题</td><td class="rowfollow">示例剧 | 全40集</td></tr>
<tr><td class="rowhead">基本信息</td><td class="rowfollow"><b>大小:</b>185.04 GB</td></tr>
<tr><td class="rowhead">简介</td><td class="rowfollow"><div id='kdescr'><div class='ubbcode'>[quote][b][color=blue]官组作品,感谢原制作者发布。[/color][/b][/quote]
[img]https://img.example.test/poster.jpg[/img]
◎片  名 示例剧
◎年  代 2025
◎豆瓣链接 [url=https://movie.douban.com/subject/36000001/]https://movie.douban.com/subject/36000001/[/url]
[quote]General
Complete name : Sample.Show.S01E01.2160p.WEB-DL.mp4
Format : MPEG-4
Video
Format : HEVC
Width : 3 840 pixels
Audio
Format : AAC[/quote]
[img]https://img.example.test/shot1.jpg[/img]</div></div></td></tr>
<tr><td class="rowhead">种子文件</td><td class="rowfollow"><b>文件数:</b>40个文件<span id='filelist'></span></td></tr>
</table></body></html>`;