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,38 @@
|
||||
# 第三方声明:MovieClaw(MIT)
|
||||
|
||||
本目录下的站点定义 JSON(`provenance.source = "movieclaw"`)由 `scripts/mp-sync/movieclaw-import.mjs`
|
||||
从 MovieClaw **tag `v0.27.0`(提交 `c79bb1b065c826823fc1c15bcb99b3c282c3fce0`)** 的
|
||||
`src/movieclaw_tracker/sites/configs/*.yaml` 与 `src/movieclaw_tracker/selectors.py`(`NexusPHPSelectors` 默认值)
|
||||
转换而来;`packages/adapters/src/sites/spider/mc-selector.ts` 的选择器语义对照 `frameworks/nexusphp.py` `_css_text`。
|
||||
该版本以 MIT 许可发布(MovieClaw 自 `251f1988` 起改为附条件许可,**新许可下的内容未被使用**)。
|
||||
|
||||
- 上游仓库:https://github.com/movieclaw/movieclaw
|
||||
- 许可类别:`copied-mit`(见 `docs/porting/license-and-provenance.md`)
|
||||
- 本项目的修改:字段改写为 MoviePilot indexer schema + `umt` 扩展;默认值展开;分类名与观众/馒头定义由
|
||||
`scripts/mp-sync/movieclaw-overrides/*.json` 覆盖。
|
||||
|
||||
以下为 MovieClaw v0.27.0 `LICENSE` 全文(原样):
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 MovieClaw
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
@@ -0,0 +1,252 @@
|
||||
{
|
||||
"id": "agsvpt",
|
||||
"name": "AGSVPT",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/agsvpt.yaml"
|
||||
},
|
||||
"domain": "https://www.agsvpt.com/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "419",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "411",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > span"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "AGSVPT",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "剧集",
|
||||
"408": "音乐",
|
||||
"411": "音乐",
|
||||
"413": "游戏",
|
||||
"415": "其他",
|
||||
"419": "剧集"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='User_Name']::attr(href)",
|
||||
"username_css": "a[class*='User_Name']",
|
||||
"class_css": "a[class*='User_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding']::next_sibling_text",
|
||||
"leeching_css": "img[alt='Torrents leeching']::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,16 @@
|
||||
{
|
||||
"_provenance": "按 MoviePilot SiteSpider indexer schema 手写;字段结构参考 MovieClaw audiences.yaml(data-ref,未复制);选择器值按 NexusPHP 公开页面惯例编写,仅对 testkit mock 验证,待真实页面核验。见 ../README.md",
|
||||
"id": "audiences",
|
||||
"name": "观众",
|
||||
"enabled": true,
|
||||
"schema": "NexusAudiences",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/audiences.yaml",
|
||||
"overrides": "scripts/mp-sync/movieclaw-overrides/audiences.json"
|
||||
},
|
||||
"domain": "https://audiences.me/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
@@ -10,14 +19,45 @@
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [{ "path": "torrents.php", "type": "all" }],
|
||||
"params": { "search": "{keyword}", "search_area": 4 }
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}",
|
||||
"search_area": 4
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"batch": { "delimiter": " ", "space_replace": "_" },
|
||||
"browse": { "path": "torrents.php?page={page}", "start": 0 },
|
||||
"category": {
|
||||
"movie": [{ "id": "401", "cat": "Movies", "desc": "电影" }],
|
||||
"tv": [{ "id": "402", "cat": "TV Series", "desc": "剧集" }, { "id": "403", "cat": "TV Shows", "desc": "综艺" }],
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"cat": "Movies",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"cat": "TV Series",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"cat": "TV Shows",
|
||||
"desc": "综艺"
|
||||
}
|
||||
],
|
||||
"music": []
|
||||
},
|
||||
"torrents": {
|
||||
@@ -25,28 +65,62 @@
|
||||
"selector": "table.torrents > tbody > tr:has(table.torrentname), table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": { "selector": "a[href*=\"details.php?id=\"]" },
|
||||
"title_optional": { "selector": "a[title][href*=\"details.php?id=\"]", "attribute": "title" },
|
||||
"title_default": {
|
||||
"selector": "a[href*=\"details.php?id=\"]"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[title][href*=\"details.php?id=\"]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": { "selector": "a[href*=\"details.php?id=\"]", "attribute": "href" },
|
||||
"download": { "selector": "a[href*=\"download.php?id=\"]", "attribute": "href" },
|
||||
"details": {
|
||||
"selector": "a[href*=\"details.php?id=\"]",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*=\"download.php?id=\"]",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [{ "name": "re_search", "args": ["tt\\d+", 0] }]
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4) > span"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date_elapsed": { "selector": "td:nth-child(4) > span" },
|
||||
"date_added": { "selector": "td:nth-child(4) > span", "attribute": "title" },
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [{ "name": "dateparse", "args": "%Y-%m-%d %H:%M:%S" }]
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"size": { "selector": "td:nth-child(5)" },
|
||||
"seeders": { "selector": "td:nth-child(6)" },
|
||||
"leechers": { "selector": "td:nth-child(7)" },
|
||||
"grabs": { "selector": "td:nth-child(8)" },
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
@@ -65,17 +139,31 @@
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"freedate": {
|
||||
"selector": "img[class^=\"pro_\"]",
|
||||
"attribute": "title",
|
||||
"filters": [{ "name": "re_search", "args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0] }]
|
||||
"description": {
|
||||
"selector": "span.torrent-subtitle-line"
|
||||
},
|
||||
"description": { "selector": "span.torrent-subtitle-line" },
|
||||
"labels": { "selector": "span.tags" },
|
||||
"category": {
|
||||
"selector": "a[href*=\"?cat=\"]",
|
||||
"attribute": "href",
|
||||
"filters": [{ "name": "querystring", "args": "cat" }]
|
||||
"filters": [
|
||||
{
|
||||
"name": "querystring",
|
||||
"args": "cat"
|
||||
}
|
||||
]
|
||||
},
|
||||
"freedate": {
|
||||
"selector": "img[class^=\"pro_\"]",
|
||||
"attribute": "title",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"labels": {
|
||||
"selector": "span.tags"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -84,14 +172,47 @@
|
||||
"kind": "nexusphp",
|
||||
"displayName": "观众",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": { "minIntervalMs": 3000, "burst": 1 },
|
||||
"capabilities": { "list": true, "search": true, "detail": true, "download": true, "rss": true },
|
||||
"categoryNames": { "401": "电影", "402": "剧集", "403": "综艺", "406": "纪录片" },
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": true
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "综艺",
|
||||
"406": "纪录片"
|
||||
},
|
||||
"loginSuccess": "a[href*=\"logout\"]",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "td.rowhead:contains('等级') + td::text",
|
||||
"uploaded_css": "span.site-userbar__compact-metric--uploaded",
|
||||
"downloaded_css": "span.site-userbar__compact-metric--downloaded",
|
||||
"ratio_css": "td.rowhead:contains('分享率') + td::text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "td.rowhead:contains('当前做种') + td::text",
|
||||
"leeching_css": "td.rowhead:contains('当前下载') + td::text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
{
|
||||
"id": "chdbits",
|
||||
"name": "彩虹岛",
|
||||
"enabled": true,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/chdbits.yaml",
|
||||
"overrides": "scripts/mp-sync/movieclaw-overrides/chdbits.json"
|
||||
},
|
||||
"domain": "https://ptchdbits.co/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "综艺"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "体育"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "MV"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "HQ Audio"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "font.subtitle"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"freedate": {
|
||||
"selector": "td.embedded > span[title]",
|
||||
"attribute": "title",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "彩虹岛",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "综艺",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "MV",
|
||||
"407": "体育",
|
||||
"408": "HQ Audio",
|
||||
"409": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"username_css": "a[href^='userdetails.php?id=']",
|
||||
"class_css": "td.rowhead:contains('等级') + td::text",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding']::next_sibling_text",
|
||||
"leeching_css": "img[alt='Torrents leeching']::next_sibling_text",
|
||||
"vip_css": "a[class^='VIP']"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
import { CHDBITS_LIST_PAGE, CHDBITS_LOGIN_PAGE, HHANCLUB_DETAIL_PAGE, HHANCLUB_LIST_PAGE } from "@umt/testkit";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getSiteDefinition, listSiteDefinitions } from "../registry.ts";
|
||||
import { parseDetailPage } from "../spider/detail.ts";
|
||||
import { spiderTorrentToRelease } from "../spider/map.ts";
|
||||
import type { IndexerDefinition } from "../spider/schema.ts";
|
||||
import { SiteSpider } from "../spider/spider.ts";
|
||||
import {
|
||||
BUILTIN_SITE_DEFINITIONS,
|
||||
chdbitsDefinition,
|
||||
hhanclubDefinition,
|
||||
loadSiteDefinition,
|
||||
parseIndexerDefinition,
|
||||
} from "./index.ts";
|
||||
import { MOVIECLAW_DEFINITION_JSON } from "./manifest.generated.ts";
|
||||
|
||||
const OBSERVED = "2026-09-27T00:00:00.000Z";
|
||||
const PRIMARY = ["audiences", "chdbits", "hhanclub", "mteam"];
|
||||
|
||||
describe("站点定义:加载时 zod 校验", () => {
|
||||
const ids = Object.keys(MOVIECLAW_DEFINITION_JSON).sort();
|
||||
|
||||
it("MovieClaw v0.27.0 全部 23 站转换结果均在注册表中", () => {
|
||||
expect(ids).toHaveLength(23);
|
||||
expect(listSiteDefinitions().map((d) => d.id)).toEqual(ids);
|
||||
});
|
||||
|
||||
it.each(ids)("%s:schema 校验通过,provenance 指向 MovieClaw v0.27.0 MIT", (id) => {
|
||||
const def = loadSiteDefinition(MOVIECLAW_DEFINITION_JSON[id]);
|
||||
expect(def.id).toBe(id);
|
||||
expect(def.provenance).toMatchObject({ source: "movieclaw", ref: "v0.27.0", commit: "c79bb1b0", license: "MIT" });
|
||||
expect(def.provenance?.file).toBe(`src/movieclaw_tracker/sites/configs/${id}.yaml`);
|
||||
expect(def.enabled).toBe(PRIMARY.includes(id));
|
||||
expect(getSiteDefinition(id)).toBe(BUILTIN_SITE_DEFINITIONS[id]);
|
||||
});
|
||||
|
||||
it("enabledOnly 只列 4 个主力站", () => {
|
||||
expect(listSiteDefinitions({ enabledOnly: true }).map((d) => d.id)).toEqual(PRIMARY);
|
||||
});
|
||||
|
||||
it("非法定义被拒绝并指出字段路径", () => {
|
||||
const bad = structuredClone(MOVIECLAW_DEFINITION_JSON.chdbits) as Record<string, unknown>;
|
||||
(bad as { domain: string }).domain = "https://ptchdbits.co"; // 缺结尾 /
|
||||
delete (bad as { umt: Record<string, unknown> }).umt.timezone;
|
||||
expect(() => parseIndexerDefinition(bad)).toThrow(/chdbits.*domain.*umt\.timezone|chdbits.*umt\.timezone.*domain/);
|
||||
expect(() => loadSiteDefinition({ id: "x", umt: { kind: "gopher" } })).toThrow(/umt\.kind 未知/);
|
||||
const typo = structuredClone(MOVIECLAW_DEFINITION_JSON.hhanclub) as {
|
||||
torrents: { fields: Record<string, unknown> };
|
||||
};
|
||||
typo.torrents.fields.size = { selectr: "div" };
|
||||
expect(() => parseIndexerDefinition(typo)).toThrow(/torrents\.fields\.size/);
|
||||
});
|
||||
|
||||
it("观众:W1-3b 手写值优先(覆盖层),MovieClaw 值补空", () => {
|
||||
const a = getSiteDefinition("audiences") as IndexerDefinition;
|
||||
expect(a.search?.params).toEqual({ search: "{keyword}", search_area: 4 }); // W1-3b
|
||||
expect(a.torrents.fields.category?.filters).toEqual([{ name: "querystring", args: "cat" }]); // W1-3b
|
||||
expect(a.umt.profile?.uploaded_css).toBe("span.site-userbar__compact-metric--uploaded"); // MovieClaw 补空
|
||||
expect(a.schema).toBe("NexusAudiences");
|
||||
expect(a.provenance?.overrides).toBe("scripts/mp-sync/movieclaw-overrides/audiences.json");
|
||||
});
|
||||
|
||||
it("OurBits 的 cat[] 分类参数由定义表达;TTG 需自定义适配器 → 禁用", () => {
|
||||
const ob = getSiteDefinition("ourbits") as IndexerDefinition;
|
||||
expect(ob.category?.param).toBe("cat[]");
|
||||
const url = new URL(new SiteSpider(ob, { keyword: "x", mtype: "movie" }).getSearchUrl());
|
||||
expect(url.searchParams.getAll("cat[]").length).toBeGreaterThan(0);
|
||||
const ttg = getSiteDefinition("ttg") as IndexerDefinition;
|
||||
expect(ttg.umt.customClass).toContain("TTGSite");
|
||||
expect(ttg.enabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("HHClub 定义(div 卡片模板)", () => {
|
||||
const parse = (html: string) => {
|
||||
const r = new SiteSpider(hhanclubDefinition, {}).parse(html);
|
||||
return r.torrents.map((t) => spiderTorrentToRelease(t, hhanclubDefinition, OBSERVED)!);
|
||||
};
|
||||
|
||||
it("列表:标题/副标题/综艺原始分类 403/大小/人数/发布时间/免费 + H&R", () => {
|
||||
const [a, b] = parse(HHANCLUB_LIST_PAGE);
|
||||
expect(a).toMatchObject({
|
||||
siteId: "hhanclub",
|
||||
siteReleaseId: "90001",
|
||||
title: "Go.Fighting.S10E01.2026.2160p.WEB-DL.H265.AAC-HHWEB",
|
||||
subtitle: "极限挑战 第十季 第1期",
|
||||
category: { id: "403", name: "综艺" },
|
||||
sizeBytes: Math.round(6.12 * 1024 ** 3),
|
||||
seeders: 88,
|
||||
leechers: 5,
|
||||
snatched: 1024,
|
||||
promotion: { type: "free", downloadFactor: 0, uploadFactor: 1 },
|
||||
hr: true,
|
||||
uploadedAt: "2026-09-20T12:30:00.000Z",
|
||||
detailUrl: "https://hhanclub.net/details.php?id=90001&hit=1",
|
||||
});
|
||||
expect(b).toMatchObject({
|
||||
siteReleaseId: "90002",
|
||||
category: { id: "401", name: "电影" },
|
||||
promotion: { type: "2x50%", downloadFactor: 0.5, uploadFactor: 2 },
|
||||
hr: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("浏览从 page=0 起(MovieClaw page_offset -1);mtype=tv 选 402/403/407/412", () => {
|
||||
expect(new SiteSpider(hhanclubDefinition, { page: 0 }).getSearchUrl()).toBe(
|
||||
"https://hhanclub.net/torrents.php?page=0",
|
||||
);
|
||||
const u = new URL(new SiteSpider(hhanclubDefinition, { keyword: "极限挑战", mtype: "tv" }).getSearchUrl());
|
||||
expect(["cat402", "cat403", "cat407", "cat412"].every((k) => u.searchParams.get(k) === "1")).toBe(true);
|
||||
expect(u.searchParams.get("search")).toBe("极限挑战");
|
||||
});
|
||||
|
||||
it("详情页:逐字段选择器(Tailwind div 结构)取标题/副标题/大小/IMDb/豆瓣", () => {
|
||||
const { kind, detail } = parseDetailPage(HHANCLUB_DETAIL_PAGE, hhanclubDefinition, "90002", OBSERVED);
|
||||
expect(kind).toBe("ok");
|
||||
expect(detail).toMatchObject({
|
||||
title: "Dune.Part.Two.2024.2160p.UHD.BluRay.REMUX-HHWEB",
|
||||
subtitle: "沙丘2 | 中字",
|
||||
sizeBytes: Math.round(78.3 * 1024 ** 3),
|
||||
imdbId: "tt15239678",
|
||||
doubanId: "35575567",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("CHDBits 定义(标准 NexusPHP)", () => {
|
||||
it("列表:title 属性全名、font.subtitle、2x 免费 + 截止时间、cat 链接分类", () => {
|
||||
const r = new SiteSpider(chdbitsDefinition, {}).parse(CHDBITS_LIST_PAGE);
|
||||
const [a, b] = r.torrents.map((t) => spiderTorrentToRelease(t, chdbitsDefinition, OBSERVED)!);
|
||||
expect(a).toMatchObject({
|
||||
siteReleaseId: "555001",
|
||||
title: "The.Last.of.Us.S02.2025.1080p.BluRay.x264.DTS-HD.MA.5.1-CHD",
|
||||
category: { id: "402", name: "剧集" },
|
||||
sizeBytes: Math.round(45.2 * 1024 ** 3),
|
||||
seeders: 42,
|
||||
leechers: 3,
|
||||
snatched: 100,
|
||||
promotion: { type: "2xfree", downloadFactor: 0, uploadFactor: 2, expiresAt: "2026-09-30T04:00:00.000Z" },
|
||||
hr: "unknown",
|
||||
uploadedAt: "2026-09-25T00:00:00.000Z",
|
||||
});
|
||||
expect(a!.subtitle).toContain("最后生还者 第二季");
|
||||
expect(b).toMatchObject({
|
||||
siteReleaseId: "555002",
|
||||
category: { id: "401", name: "电影" },
|
||||
promotion: { type: "none", downloadFactor: 1, uploadFactor: 1, expiresAt: null },
|
||||
});
|
||||
});
|
||||
|
||||
it("登录页识别为登录/权限页,不产生结果", () => {
|
||||
const r = new SiteSpider(chdbitsDefinition, {}).parse(CHDBITS_LOGIN_PAGE);
|
||||
expect(r.loginPage).toBe(true);
|
||||
expect(r.torrents).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,279 @@
|
||||
{
|
||||
"id": "hdarea",
|
||||
"name": "高清视界 HDArea",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdarea.yaml"
|
||||
},
|
||||
"domain": "https://www.hdarea.club/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "300",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "410",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "411",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "412",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "413",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "414",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "415",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "416",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "417",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(5) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(9)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > div[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "高清视界 HDArea",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 60000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"300": "电影",
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "电影",
|
||||
"411": "电影",
|
||||
"412": "电影",
|
||||
"413": "电影",
|
||||
"414": "电影",
|
||||
"415": "电影",
|
||||
"416": "电影",
|
||||
"417": "电影"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
{
|
||||
"id": "hddolby",
|
||||
"name": "高清杜比 HDDolby",
|
||||
"enabled": false,
|
||||
"schema": "HDDolby",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hddolby.yaml"
|
||||
},
|
||||
"domain": "https://www.hddolby.com/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded span[style*='float:left']"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "高清杜比 HDDolby",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "游戏",
|
||||
"411": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"id": "hdfans",
|
||||
"name": "HDFans",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdfans.yaml"
|
||||
},
|
||||
"domain": "https://hdfans.org/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "416",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "HDFans",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "纪录片",
|
||||
"404": "其他",
|
||||
"405": "其他",
|
||||
"406": "音乐",
|
||||
"407": "音乐",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "其他",
|
||||
"416": "剧集",
|
||||
"417": "动漫",
|
||||
"418": "其他",
|
||||
"419": "其他",
|
||||
"421": "游戏",
|
||||
"423": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
{
|
||||
"id": "hdhome",
|
||||
"name": "高清家园",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdhome.yaml"
|
||||
},
|
||||
"domain": "https://hdhome.org/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "411",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "412",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "413",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "414",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "415",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "416",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "450",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "499",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "505",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "506",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "518",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "425",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "426",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "427",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "428",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "429",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "430",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "431",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "432",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "433",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "434",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "435",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "436",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "437",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "438",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "442",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "443",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "452",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "453",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "502",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "504",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "511",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "523",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "526",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "439",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "440",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "441",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "503",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "423",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "424",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > span:not([class])"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hr": {
|
||||
"selector": "img.hitandrun"
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "高清家园",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"409": "其他",
|
||||
"411": "电影",
|
||||
"412": "电影",
|
||||
"413": "电影",
|
||||
"414": "电影",
|
||||
"415": "电影",
|
||||
"416": "电影",
|
||||
"417": "纪录片",
|
||||
"418": "纪录片",
|
||||
"419": "纪录片",
|
||||
"420": "纪录片",
|
||||
"421": "纪录片",
|
||||
"422": "纪录片",
|
||||
"423": "音乐",
|
||||
"424": "音乐",
|
||||
"425": "剧集",
|
||||
"426": "剧集",
|
||||
"427": "剧集",
|
||||
"428": "剧集",
|
||||
"429": "剧集",
|
||||
"430": "剧集",
|
||||
"431": "剧集",
|
||||
"432": "剧集",
|
||||
"433": "剧集",
|
||||
"434": "剧集",
|
||||
"435": "剧集",
|
||||
"436": "剧集",
|
||||
"437": "剧集",
|
||||
"438": "剧集",
|
||||
"439": "音乐",
|
||||
"440": "音乐",
|
||||
"441": "音乐",
|
||||
"442": "剧集",
|
||||
"443": "剧集",
|
||||
"444": "动漫",
|
||||
"445": "动漫",
|
||||
"446": "动漫",
|
||||
"447": "动漫",
|
||||
"448": "动漫",
|
||||
"449": "动漫",
|
||||
"450": "电影",
|
||||
"451": "纪录片",
|
||||
"452": "剧集",
|
||||
"453": "剧集",
|
||||
"454": "动漫",
|
||||
"499": "电影",
|
||||
"500": "纪录片",
|
||||
"501": "动漫",
|
||||
"502": "剧集",
|
||||
"503": "音乐",
|
||||
"504": "剧集",
|
||||
"505": "电影",
|
||||
"506": "电影",
|
||||
"507": "纪录片",
|
||||
"508": "纪录片",
|
||||
"509": "动漫",
|
||||
"510": "动漫",
|
||||
"511": "剧集",
|
||||
"518": "电影",
|
||||
"523": "剧集",
|
||||
"526": "剧集",
|
||||
"529": "纪录片",
|
||||
"531": "动漫"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "a[href*='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus::next_sibling_text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding'] + *",
|
||||
"leeching_css": "img[alt='Torrents leeching'] + *"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
{
|
||||
"id": "hdsky",
|
||||
"name": "HDSky",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdsky.yaml"
|
||||
},
|
||||
"domain": "https://hdsky.me/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "410",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "411",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "412",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "413",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "414",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "415",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "416",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents.progresstable tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a[href*='details.php'] b span"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a[href*='details.php'] b span[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "table.torrentname a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "form[action*='download.php']",
|
||||
"attribute": "action"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "a[href*='dllist=1#seeders']"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "a[href*='dllist=1#leechers']"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "a[href*='viewsnatches.php'] b, td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_2up": 2,
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "table.torrentname br + span"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:first-child a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "HDSky",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "剧集",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "电影",
|
||||
"411": "剧集",
|
||||
"412": "剧集",
|
||||
"413": "剧集",
|
||||
"414": "剧集",
|
||||
"415": "剧集",
|
||||
"416": "剧集"
|
||||
},
|
||||
"loginSuccess": "a[href='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td.rowfollow",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow",
|
||||
"description": "#kdescr",
|
||||
"download": "form[action*='download.php']::attr(action)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
{
|
||||
"id": "hdtime",
|
||||
"name": "HDTime",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdtime.yaml"
|
||||
},
|
||||
"domain": "https://hdtime.org/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "424",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "HDTime",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "游戏",
|
||||
"411": "其他",
|
||||
"414": "其他",
|
||||
"424": "电影"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
{
|
||||
"id": "hdvideo",
|
||||
"name": "HDVIDEO",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hdvideo.yaml"
|
||||
},
|
||||
"domain": "https://hdvideo.top/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "span.tt-name a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "span.tt-name a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "span.tt-name a",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(5) span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "a[href*='dllist=1#seeders']"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "a[href*='dllist=1#leechers'], td:nth-child(8)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "a[href*='viewsnatches.php'] b"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_2up": 2,
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "span.tt-sub"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(2) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "HDVIDEO",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "剧集",
|
||||
"408": "音乐"
|
||||
},
|
||||
"loginSuccess": "a[href='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td.rowfollow",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
{
|
||||
"id": "hhanclub",
|
||||
"name": "憨憨",
|
||||
"enabled": true,
|
||||
"schema": "NexusHhanclub",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/hhanclub.yaml",
|
||||
"overrides": "scripts/mp-sync/movieclaw-overrides/hhanclub.json"
|
||||
},
|
||||
"domain": "https://hhanclub.net/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "电视剧"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "综艺"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "体育"
|
||||
},
|
||||
{
|
||||
"id": "412",
|
||||
"desc": "短剧"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "410",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "411",
|
||||
"desc": "MV"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "div.torrent-table-sub-info"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "div.torrent-title a.torrent-info-text-name"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "div.torrent-title a.torrent-info-text-name[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "div.torrent-title a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "div.torrent-manage a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "div.torrent-info-text-added"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "div.torrent-info-text-added > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "div.torrent-info-text-size"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "div.torrent-info-text-seeders"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "div.torrent-info-text-leechers"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "div.torrent-info-text-finished"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"span.promotion-tag-free": 0,
|
||||
"span.promotion-tag-free2up": 0,
|
||||
"span.promotion-tag-2xfree": 0,
|
||||
"span.promotion-tag-50": 0.5,
|
||||
"span.promotion-tag-50pctdown": 0.5,
|
||||
"span.promotion-tag-50pctdown2up": 0.5,
|
||||
"span.promotion-tag-30": 0.3,
|
||||
"span.promotion-tag-30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"span.promotion-tag-free2up": 2,
|
||||
"span.promotion-tag-50pctdown2up": 2,
|
||||
"span.promotion-tag-2up": 2,
|
||||
"span.promotion-tag-2xfree": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "div.torrent-info-text-small_name"
|
||||
},
|
||||
"category": {
|
||||
"selector": "div.torrent-cat a",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hr": {
|
||||
"selector": "div.torrent-info-hr"
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "憨憨",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "电视剧",
|
||||
"403": "综艺",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"407": "体育",
|
||||
"409": "其他",
|
||||
"410": "音乐",
|
||||
"411": "MV",
|
||||
"412": "短剧"
|
||||
},
|
||||
"loginSuccess": "a[href='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name']",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "img[alt='上传']::next_sibling_text",
|
||||
"downloaded_css": "img[alt='下载']::next_sibling_text",
|
||||
"ratio_css": "img[alt='分享率'] + div",
|
||||
"bonus_css": "img[alt='憨豆'] + a div",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='做种数']::next_sibling_text",
|
||||
"leeching_css": "img[alt='下载数']::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "div.font-bold.leading-6:contains('标题'):not(:contains('副标题')) + div.font-bold.leading-6",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "div.font-bold.leading-6:contains('标题'):not(:contains('副标题')) + div.font-bold.leading-6",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "div.font-bold.leading-6:contains('标题'):not(:contains('副标题')) + div.font-bold.leading-6",
|
||||
"subtitle": "div.font-bold.leading-6:contains('副标题') + div.font-bold.leading-6",
|
||||
"size": "span.font-bold:contains('大小') + span",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"id": "keepfrds",
|
||||
"name": "朋友",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/keepfrds.yaml"
|
||||
},
|
||||
"domain": "https://pt.keepfrds.com/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "420",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "421",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_nl": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_nl": 0,
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "朋友",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"300": "其他",
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "剧集",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"414": "其他",
|
||||
"415": "其他",
|
||||
"419": "成人",
|
||||
"420": "音乐",
|
||||
"421": "音乐",
|
||||
"422": "其他",
|
||||
"423": "游戏",
|
||||
"424": "其他",
|
||||
"425": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "a[href*='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "span.uploaded",
|
||||
"downloaded_css": "span.downloaded",
|
||||
"ratio_css": "td.rowhead:contains('分享率') + td::text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "td.rowhead:contains('当前做种') + td::text",
|
||||
"leeching_css": "td.rowhead:contains('当前下载') + td::text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// 由 scripts/mp-sync/movieclaw-import.mjs 生成,请勿手改(MovieClaw v0.27.0 c79bb1b0,MIT)
|
||||
import agsvptJson from "./agsvpt.json" with { type: "json" };
|
||||
import audiencesJson from "./audiences.json" with { type: "json" };
|
||||
import chdbitsJson from "./chdbits.json" with { type: "json" };
|
||||
import hdareaJson from "./hdarea.json" with { type: "json" };
|
||||
import hddolbyJson from "./hddolby.json" with { type: "json" };
|
||||
import hdfansJson from "./hdfans.json" with { type: "json" };
|
||||
import hdhomeJson from "./hdhome.json" with { type: "json" };
|
||||
import hdskyJson from "./hdsky.json" with { type: "json" };
|
||||
import hdtimeJson from "./hdtime.json" with { type: "json" };
|
||||
import hdvideoJson from "./hdvideo.json" with { type: "json" };
|
||||
import hhanclubJson from "./hhanclub.json" with { type: "json" };
|
||||
import keepfrdsJson from "./keepfrds.json" with { type: "json" };
|
||||
import mteamJson from "./mteam.json" with { type: "json" };
|
||||
import niceptJson from "./nicept.json" with { type: "json" };
|
||||
import ourbitsJson from "./ourbits.json" with { type: "json" };
|
||||
import piggoJson from "./piggo.json" with { type: "json" };
|
||||
import pterJson from "./pter.json" with { type: "json" };
|
||||
import pthomeJson from "./pthome.json" with { type: "json" };
|
||||
import pttimeJson from "./pttime.json" with { type: "json" };
|
||||
import soulvoiceJson from "./soulvoice.json" with { type: "json" };
|
||||
import ssdJson from "./ssd.json" with { type: "json" };
|
||||
import tjuptJson from "./tjupt.json" with { type: "json" };
|
||||
import ttgJson from "./ttg.json" with { type: "json" };
|
||||
|
||||
/** MovieClaw 转换来的站点定义原始 JSON(未校验;经 loadSiteDefinition 校验后使用) */
|
||||
export const MOVIECLAW_DEFINITION_JSON: Record<string, unknown> = {
|
||||
agsvpt: agsvptJson,
|
||||
audiences: audiencesJson,
|
||||
chdbits: chdbitsJson,
|
||||
hdarea: hdareaJson,
|
||||
hddolby: hddolbyJson,
|
||||
hdfans: hdfansJson,
|
||||
hdhome: hdhomeJson,
|
||||
hdsky: hdskyJson,
|
||||
hdtime: hdtimeJson,
|
||||
hdvideo: hdvideoJson,
|
||||
hhanclub: hhanclubJson,
|
||||
keepfrds: keepfrdsJson,
|
||||
mteam: mteamJson,
|
||||
nicept: niceptJson,
|
||||
ourbits: ourbitsJson,
|
||||
piggo: piggoJson,
|
||||
pter: pterJson,
|
||||
pthome: pthomeJson,
|
||||
pttime: pttimeJson,
|
||||
soulvoice: soulvoiceJson,
|
||||
ssd: ssdJson,
|
||||
tjupt: tjuptJson,
|
||||
ttg: ttgJson,
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"id": "mteam",
|
||||
"name": "馒头",
|
||||
"enabled": true,
|
||||
"schema": "MTorrent",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/mteam.yaml",
|
||||
"overrides": "scripts/mp-sync/movieclaw-overrides/mteam.json"
|
||||
},
|
||||
"domain": "https://tp.m-team.cc/",
|
||||
"parser": "mTorrent",
|
||||
"timeout": 15,
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "mteam",
|
||||
"displayName": "馒头",
|
||||
"apiBaseUrl": "https://api.m-team.cc",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 1000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "综艺",
|
||||
"404": "纪录",
|
||||
"405": "动画",
|
||||
"406": "音乐",
|
||||
"407": "体育",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "成人",
|
||||
"411": "成人",
|
||||
"412": "成人",
|
||||
"413": "成人",
|
||||
"419": "电影",
|
||||
"420": "电影",
|
||||
"421": "电影",
|
||||
"422": "其他",
|
||||
"423": "游戏",
|
||||
"424": "成人",
|
||||
"425": "成人",
|
||||
"426": "成人",
|
||||
"427": "其他",
|
||||
"429": "成人",
|
||||
"430": "成人",
|
||||
"431": "成人",
|
||||
"432": "成人",
|
||||
"433": "成人",
|
||||
"434": "音乐",
|
||||
"435": "剧集",
|
||||
"436": "成人",
|
||||
"437": "成人",
|
||||
"438": "剧集",
|
||||
"439": "电影"
|
||||
},
|
||||
"authSupported": ["apikey"],
|
||||
"customClass": "movieclaw_tracker.sites.custom.mteam.MTeamSite"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"id": "nicept",
|
||||
"name": "NicePT",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/nicept.yaml"
|
||||
},
|
||||
"domain": "https://www.nicept.net/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [],
|
||||
"tv": [],
|
||||
"music": []
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hr": {
|
||||
"selector": "img.hitandrun"
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "NicePT",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "成人",
|
||||
"402": "成人",
|
||||
"403": "成人",
|
||||
"404": "成人",
|
||||
"500": "成人",
|
||||
"501": "成人",
|
||||
"503": "成人",
|
||||
"504": "成人"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副標題') + td::text",
|
||||
"size": "td.rowhead:contains('基本資訊') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
{
|
||||
"id": "ourbits",
|
||||
"name": "OurBits",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/ourbits.yaml"
|
||||
},
|
||||
"domain": "https://ourbits.club/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "405",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "412",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "413",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "415",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "416",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "414",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "419",
|
||||
"desc": "音乐"
|
||||
}
|
||||
],
|
||||
"param": "cat[]"
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > div"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"hr": {
|
||||
"selector": "img.hitandrun"
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "OurBits",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "电影",
|
||||
"405": "剧集",
|
||||
"410": "纪录片",
|
||||
"411": "动漫",
|
||||
"412": "剧集",
|
||||
"413": "剧集",
|
||||
"414": "音乐",
|
||||
"415": "剧集",
|
||||
"416": "音乐",
|
||||
"419": "音乐"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "a[href*='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "td.rowhead:contains('分享率') + td::text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding'] + *",
|
||||
"leeching_css": "img[alt='Torrents leeching'] + *"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
},
|
||||
"customClass": "movieclaw_tracker.sites.custom.ourbits.OurBitsSite"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
{
|
||||
"id": "piggo",
|
||||
"name": "猪猪网 Piggo",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/piggo.yaml"
|
||||
},
|
||||
"domain": "https://piggo.me/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "猪猪网 Piggo",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 8000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"912": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
{
|
||||
"id": "pter",
|
||||
"name": "猫站",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/pter.yaml"
|
||||
},
|
||||
"domain": "https://pterclub.net/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "404",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "405",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "418",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "猫站",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "纪录片",
|
||||
"403": "动漫",
|
||||
"404": "剧集",
|
||||
"405": "剧集",
|
||||
"406": "音乐",
|
||||
"409": "游戏",
|
||||
"418": "音乐"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "a[href*='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding'] + *",
|
||||
"leeching_css": "img[alt='Torrents leeching'] + *"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
{
|
||||
"id": "pthome",
|
||||
"name": "铂金家",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/pthome.yaml"
|
||||
},
|
||||
"domain": "https://pthome.net/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "407",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > span:not([class])"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "铂金家",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"407": "剧集",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"410": "游戏",
|
||||
"411": "其他",
|
||||
"412": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href*='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href*='userdetails.php?id=']",
|
||||
"class_css": "a[href*='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus::next_sibling_text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding'] + *",
|
||||
"leeching_css": "img[alt='Torrents leeching'] + *"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
{
|
||||
"id": "pttime",
|
||||
"name": "PTTime",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/pttime.yaml"
|
||||
},
|
||||
"domain": "https://www.pttime.org/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(5) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(9)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"font.promotion.free": 0,
|
||||
"font.promotion.twoupfree": 0,
|
||||
"font.promotion.halfdown": 0.5,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"font.promotion.twoupfree": 2,
|
||||
"font.promotion.twoup": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded font[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "PTTime",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"100": "其他",
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "其他",
|
||||
"406": "动漫",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"411": "其他",
|
||||
"412": "其他",
|
||||
"420": "其他",
|
||||
"421": "游戏",
|
||||
"422": "其他",
|
||||
"423": "其他",
|
||||
"430": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "#info_block span.medium a[href*='userdetails.php']::attr(href)",
|
||||
"username_css": "#info_block span.medium a[href*='userdetails.php'] b",
|
||||
"class_css": "td.rowhead:contains('用户等级') + td b::text",
|
||||
"uploaded_css": "#info_block font:contains('上传:')::next_sibling_text",
|
||||
"downloaded_css": "#info_block font:contains('下载:')::next_sibling_text",
|
||||
"ratio_css": "#info_block font:contains('分享率:')::next_sibling_text",
|
||||
"bonus_css": "#info_block a[href='mybonus.php']::next_sibling_text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "#info_block font[title='当前做种']::next_sibling_text",
|
||||
"leeching_css": "#info_block font[title='当前下载']::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* 站点定义 zod schema(加载时校验)。
|
||||
*
|
||||
* 键名按 MoviePilot e6820a8 `app/application/site/sites.pyi` `SitesHelper.get_indexer(domain) -> dict` 与
|
||||
* `app/modules/indexer/spider/__init__.py` `SiteSpider` / 专用 spider 读取的 indexer dict 键整理
|
||||
* (id、name、domain、encoding、public、proxy、language、parser、result_num、timeout、media_type、search、batch、
|
||||
* browse、category、torrents),MP 的真实定义在加密 user.sites.v3.bin 中不可读;
|
||||
* `enabled` / `schema`(MP 用户信息解析器 SiteSchema)/ `provenance` / `umt` 为本项目扩展。
|
||||
* TS 类型仍以 spider/schema.ts `IndexerDefinition`、mteam/definition.ts `MteamDefinition` 为准,
|
||||
* 本文件保证 JSON 与之一致(见 schema.test.ts)。
|
||||
*/
|
||||
import { z } from "zod";
|
||||
import type { MteamDefinition } from "../mteam/definition.ts";
|
||||
import type { IndexerDefinition } from "../spider/schema.ts";
|
||||
import type { SpecializedSiteDefinition } from "../spiders/types.ts";
|
||||
import { SiteSchema } from "../user-parsers/types.ts";
|
||||
|
||||
const SITE_SCHEMA_VALUES = Object.values(SiteSchema) as [string, ...string[]];
|
||||
|
||||
export const DefinitionProvenanceSchema = z.strictObject({
|
||||
source: z.enum(["movieclaw", "handwritten"]),
|
||||
ref: z.string().optional(),
|
||||
commit: z.string().optional(),
|
||||
license: z.string().optional(),
|
||||
file: z.string().optional(),
|
||||
overrides: z.string().optional(),
|
||||
note: z.string().optional(),
|
||||
});
|
||||
|
||||
export const SpiderFilterSchema = z.discriminatedUnion("name", [
|
||||
z.strictObject({ name: z.literal("re_search"), args: z.tuple([z.string(), z.number().int()]) }),
|
||||
z.strictObject({ name: z.literal("split"), args: z.tuple([z.string(), z.number().int()]) }),
|
||||
z.strictObject({ name: z.literal("replace"), args: z.tuple([z.string(), z.string()]) }),
|
||||
z.strictObject({ name: z.literal("dateparse"), args: z.string() }),
|
||||
z.strictObject({ name: z.literal("strip"), args: z.unknown().optional() }),
|
||||
z.strictObject({ name: z.literal("appendleft"), args: z.string() }),
|
||||
z.strictObject({ name: z.literal("querystring"), args: z.string() }),
|
||||
]);
|
||||
|
||||
export const SpiderFieldSelectorSchema = z.strictObject({
|
||||
selector: z.string().min(1).optional(),
|
||||
selectors: z.string().min(1).optional(),
|
||||
attribute: z.string().min(1).optional(),
|
||||
index: z.number().int().optional(),
|
||||
contents: z.number().int().optional(),
|
||||
remove: z.string().optional(),
|
||||
filters: z.array(SpiderFilterSchema).optional(),
|
||||
text: z.string().optional(),
|
||||
case: z.record(z.string(), z.number()).optional(),
|
||||
});
|
||||
|
||||
const CategoryItemSchema = z.strictObject({
|
||||
id: z.union([z.string(), z.number()]),
|
||||
cat: z.string().optional(),
|
||||
desc: z.string().optional(),
|
||||
param: z.string().optional(),
|
||||
value: z.union([z.string(), z.number()]).optional(),
|
||||
params: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
||||
});
|
||||
|
||||
const CategoryConfigSchema = z.strictObject({
|
||||
movie: z.array(CategoryItemSchema).optional(),
|
||||
tv: z.array(CategoryItemSchema).optional(),
|
||||
music: z.array(CategoryItemSchema).optional(),
|
||||
field: z.string().optional(),
|
||||
delimiter: z.string().optional(),
|
||||
param: z.string().optional(),
|
||||
});
|
||||
|
||||
const CapabilitiesSchema = z.strictObject({
|
||||
list: z.boolean(),
|
||||
search: z.boolean(),
|
||||
detail: z.boolean(),
|
||||
download: z.boolean(),
|
||||
rss: z.boolean(),
|
||||
});
|
||||
const RateLimitSchema = z.strictObject({ minIntervalMs: z.number().int().min(0), burst: z.number().int().min(1) });
|
||||
const TimezoneSchema = z.string().regex(/^[+-]\d{2}:\d{2}$/, "时区须为 ±HH:MM 偏移");
|
||||
const PairSchema = z.tuple([z.string(), z.string()]);
|
||||
|
||||
const UmtNexusSchema = z.strictObject({
|
||||
version: z.string().min(1),
|
||||
kind: z.literal("nexusphp"),
|
||||
displayName: z.string().optional(),
|
||||
customClass: z.string().optional(),
|
||||
hrSeedHours: z.number().positive().optional(),
|
||||
authSupported: z.array(z.enum(["cookie", "credential", "apikey"])).optional(),
|
||||
timezone: TimezoneSchema,
|
||||
rateLimit: RateLimitSchema,
|
||||
capabilities: CapabilitiesSchema,
|
||||
categoryNames: z.record(z.string(), z.string()).optional(),
|
||||
loginSuccess: z.string().optional(),
|
||||
emptyMarkers: z.array(z.string()).optional(),
|
||||
pagination: z.string().optional(),
|
||||
login: z
|
||||
.strictObject({
|
||||
path: z.string(),
|
||||
usernameField: z.string(),
|
||||
passwordField: z.string(),
|
||||
errorCss: z.string(),
|
||||
extraFormData: z.array(PairSchema).optional(),
|
||||
selectDefaults: z.array(PairSchema).optional(),
|
||||
})
|
||||
.optional(),
|
||||
profile: z.record(z.string(), z.string()).optional(),
|
||||
detail: z
|
||||
.strictObject({
|
||||
path: z.string(),
|
||||
title: z.string(),
|
||||
rowLabel: z.string(),
|
||||
rowValue: z.string(),
|
||||
labels: z.strictObject({
|
||||
subtitle: z.array(z.string()),
|
||||
basicInfo: z.array(z.string()),
|
||||
peers: z.array(z.string()),
|
||||
}),
|
||||
description: z.string(),
|
||||
headerScope: z.string(),
|
||||
notFoundMarkers: z.array(z.string()),
|
||||
fields: z
|
||||
.strictObject({
|
||||
title: z.string().optional(),
|
||||
subtitle: z.string().optional(),
|
||||
size: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
download: z.string().optional(),
|
||||
imdb: z.string().optional(),
|
||||
douban: z.string().optional(),
|
||||
fileList: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
downloadPath: z.string().min(1),
|
||||
detailPath: z.string().min(1),
|
||||
});
|
||||
|
||||
const BaseDefinitionShape = {
|
||||
id: z.string().regex(/^[a-z0-9_]+$/, "id 只能是小写字母/数字/下划线"),
|
||||
name: z.string().min(1),
|
||||
enabled: z.boolean().optional(),
|
||||
schema: z.enum(SITE_SCHEMA_VALUES).optional(),
|
||||
provenance: DefinitionProvenanceSchema.optional(),
|
||||
domain: z
|
||||
.string()
|
||||
.url()
|
||||
.refine((s) => s.endsWith("/"), "domain 须以 / 结尾"),
|
||||
timeout: z.number().positive().optional(),
|
||||
proxy: z.boolean().optional(),
|
||||
};
|
||||
|
||||
const FieldsSchema = z.record(z.string(), SpiderFieldSelectorSchema);
|
||||
|
||||
export const IndexerDefinitionSchema = z.strictObject({
|
||||
...BaseDefinitionShape,
|
||||
encoding: z.string().optional(),
|
||||
public: z.boolean().optional(),
|
||||
language: z.string().optional(),
|
||||
parser: z.string().optional(),
|
||||
result_num: z.number().int().positive().optional(),
|
||||
media_type: z.string().optional(),
|
||||
search: z
|
||||
.strictObject({
|
||||
paths: z.array(z.strictObject({ path: z.string(), type: z.enum(["all", "movie", "tv", "music"]).optional() })),
|
||||
params: z.record(z.string(), z.union([z.string(), z.number()])).optional(),
|
||||
imdbid_format: z.string().optional(),
|
||||
result_media_type: z.literal("requested").optional(),
|
||||
})
|
||||
.optional(),
|
||||
batch: z.strictObject({ delimiter: z.string().optional(), space_replace: z.string().optional() }).optional(),
|
||||
browse: z
|
||||
.strictObject({
|
||||
path: z.string(),
|
||||
start: z.number().int().optional(),
|
||||
list: z.strictObject({ selector: z.string() }).optional(),
|
||||
fields: FieldsSchema.optional(),
|
||||
})
|
||||
.optional(),
|
||||
category: CategoryConfigSchema.optional(),
|
||||
torrents: z.strictObject({
|
||||
list: z.strictObject({ selector: z.string().min(1) }),
|
||||
fields: FieldsSchema.refine((f) => Boolean(f.title || f.title_default), "torrents.fields 缺少 title"),
|
||||
}),
|
||||
umt: UmtNexusSchema,
|
||||
});
|
||||
|
||||
export const MteamDefinitionSchema = z.strictObject({
|
||||
...BaseDefinitionShape,
|
||||
parser: z.literal("mTorrent"),
|
||||
timeout: z.number().positive(),
|
||||
umt: z.strictObject({
|
||||
version: z.string().min(1),
|
||||
kind: z.literal("mteam"),
|
||||
displayName: z.string(),
|
||||
apiBaseUrl: z.string().url().optional(),
|
||||
timezone: TimezoneSchema,
|
||||
rateLimit: RateLimitSchema,
|
||||
capabilities: CapabilitiesSchema,
|
||||
categoryNames: z.record(z.string(), z.string()),
|
||||
authSupported: z.array(z.enum(["cookie", "credential", "apikey"])).optional(),
|
||||
customClass: z.string().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
/** MP 专用 spider(`SPIDER_PARSER_CLASSES` 中除 mTorrent 外的 7 个)站点定义 */
|
||||
export const SpecializedSiteDefinitionSchema = z.strictObject({
|
||||
...BaseDefinitionShape,
|
||||
parser: z.enum(["Haidan", "HDDolby", "RousiPro", "SunnyPT", "TNodeSpider", "TorrentLeech", "Yema"]),
|
||||
public: z.boolean().optional(),
|
||||
category: CategoryConfigSchema.optional(),
|
||||
api_url: z.string().url().optional(),
|
||||
umt: z.strictObject({
|
||||
version: z.string().min(1),
|
||||
kind: z.literal("api"),
|
||||
displayName: z.string(),
|
||||
timezone: TimezoneSchema,
|
||||
rateLimit: RateLimitSchema,
|
||||
capabilities: CapabilitiesSchema,
|
||||
categoryNames: z.record(z.string(), z.string()).optional(),
|
||||
apiBaseUrl: z.string().url().optional(),
|
||||
}),
|
||||
});
|
||||
|
||||
function formatIssues(id: unknown, e: z.ZodError): string {
|
||||
const issues = e.issues.map((i) => `${i.path.join(".") || "<root>"}: ${i.message}`).join("; ");
|
||||
return `站点定义 ${typeof id === "string" ? id : "<unknown>"} 校验失败:${issues}`;
|
||||
}
|
||||
|
||||
/** NexusPHP(通用 SiteSpider)定义校验 */
|
||||
export function parseIndexerDefinition(json: unknown): IndexerDefinition {
|
||||
const r = IndexerDefinitionSchema.safeParse(json);
|
||||
if (!r.success) throw new Error(formatIssues((json as { id?: unknown })?.id, r.error));
|
||||
return r.data as IndexerDefinition;
|
||||
}
|
||||
|
||||
/** 馒头(M-Team API)定义校验 */
|
||||
export function parseMteamDefinition(json: unknown): MteamDefinition {
|
||||
const r = MteamDefinitionSchema.safeParse(json);
|
||||
if (!r.success) throw new Error(formatIssues((json as { id?: unknown })?.id, r.error));
|
||||
return r.data as MteamDefinition;
|
||||
}
|
||||
|
||||
/** 专用 API spider 定义校验 */
|
||||
export function parseSpecializedSiteDefinition(json: unknown): SpecializedSiteDefinition {
|
||||
const r = SpecializedSiteDefinitionSchema.safeParse(json);
|
||||
if (!r.success) throw new Error(formatIssues((json as { id?: unknown })?.id, r.error));
|
||||
return r.data as SpecializedSiteDefinition;
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
{
|
||||
"id": "soulvoice",
|
||||
"name": "聆音",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/soulvoice.yaml"
|
||||
},
|
||||
"domain": "https://pt.soulvoice.club/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "401",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "424",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "402",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "403",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "406",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "408",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr, table.torrents > tbody > tr"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "table.torrentname a b"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "table.torrentname a b[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td:nth-child(4)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(4) > span",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded br"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) a[href*='cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "聆音",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"401": "电影",
|
||||
"402": "剧集",
|
||||
"403": "剧集",
|
||||
"404": "纪录片",
|
||||
"405": "动漫",
|
||||
"406": "音乐",
|
||||
"407": "其他",
|
||||
"408": "音乐",
|
||||
"409": "其他",
|
||||
"424": "电影",
|
||||
"499": "其他",
|
||||
"500": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href*='logout']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[class*='_Name']::attr(href)",
|
||||
"username_css": "a[class*='_Name'] b",
|
||||
"class_css": "a[class*='_Name']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "font.color_bonus",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img.arrowup::next_sibling_text",
|
||||
"leeching_css": "img.arrowdown::next_sibling_text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "h1#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "h1#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "h1#top",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('基本信息') + td.rowfollow > b::next_sibling_text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
{
|
||||
"id": "ssd",
|
||||
"name": "不可说",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/ssd.yaml"
|
||||
},
|
||||
"domain": "https://springsunday.net/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 0
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "501",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "502",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "505",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "506",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "507",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "508",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:has(table.torrentname)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_elapsed": {
|
||||
"selector": "td.rowfollow:nth-last-child(6)"
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td.rowfollow:nth-last-child(6) > span[title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td.rowfollow:nth-last-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td.rowfollow:nth-last-child(4)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td.rowfollow:nth-last-child(3)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td.rowfollow:nth-last-child(2)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"span.torrent-pro-free": 0,
|
||||
"span.torrent-pro-free2up": 0,
|
||||
"span.torrent-pro-50pctdown": 0.5,
|
||||
"span.torrent-pro-50pctdown2up": 0.5,
|
||||
"span.torrent-pro-30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"span.torrent-pro-free2up": 2,
|
||||
"span.torrent-pro-50pctdown2up": 2,
|
||||
"span.torrent-pro-2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "div.torrent-smalldescr > span:not([class])"
|
||||
},
|
||||
"category": {
|
||||
"selector": "a[href^='?cat=']",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"freedate": {
|
||||
"selector": "span.torrent-pro-free ~ span > span[title]",
|
||||
"attribute": "title",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "不可说",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"501": "电影",
|
||||
"502": "剧集",
|
||||
"503": "纪录片",
|
||||
"504": "动漫",
|
||||
"505": "剧集",
|
||||
"506": "剧集",
|
||||
"507": "音乐",
|
||||
"508": "音乐",
|
||||
"509": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href^='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a[href^='userdetails.php?id=']::attr(href)",
|
||||
"username_css": "a[href^='userdetails.php?id=']",
|
||||
"class_css": "a[href^='userdetails.php?id=']::attr(class)",
|
||||
"uploaded_css": "font.color_uploaded::next_sibling_text",
|
||||
"downloaded_css": "font.color_downloaded::next_sibling_text",
|
||||
"ratio_css": "font.color_ratio::next_sibling_text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "img[alt='Torrents seeding'] + *",
|
||||
"leeching_css": "img[alt='Torrents leeching'] + *",
|
||||
"vip_css": "a[class^='VIP']"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"id": "tjupt",
|
||||
"name": "北洋园",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/tjupt.yaml"
|
||||
},
|
||||
"domain": "https://tjupt.org/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "torrents.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "torrents.php?page={page}",
|
||||
"start": 1
|
||||
},
|
||||
"category": {
|
||||
"movie": [],
|
||||
"tv": [],
|
||||
"music": []
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table.torrents > tr:not(:first-child)"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": ":scope > td:nth-child(2) a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": ":scope > td:nth-child(2) a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_added": {
|
||||
"selector": ":scope > td:nth-child(4)"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": ":scope > td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": ":scope > td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": ":scope > td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": ":scope > td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free": 0,
|
||||
"img.pro_free2up": 0,
|
||||
"img.pro_50pctdown": 0.5,
|
||||
"img.pro_50pctdown2up": 0.5,
|
||||
"img.pro_30pctdown": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img.pro_free2up": 2,
|
||||
"img.pro_50pctdown2up": 2,
|
||||
"img.pro_2up": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > span"
|
||||
},
|
||||
"category": {
|
||||
"selector": ":scope > td:nth-child(1) a",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "北洋园",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 5000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {},
|
||||
"loginSuccess": "a[href*='logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"authSupported": ["cookie", "credential"],
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text",
|
||||
"selectDefaults": [["logout", "7"]]
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"uid_css": "a.User_Name::attr(href)",
|
||||
"username_css": "a.User_Name b",
|
||||
"class_css": "td.rowhead:contains('等级') + td img::attr(title)",
|
||||
"uploaded_css": "td.rowhead:contains('上传量') + td::text",
|
||||
"bonus_css": "td.rowhead:contains('魔力值') + td",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
{
|
||||
"id": "ttg",
|
||||
"name": "听听歌",
|
||||
"enabled": false,
|
||||
"schema": "NexusPhp",
|
||||
"provenance": {
|
||||
"source": "movieclaw",
|
||||
"ref": "v0.27.0",
|
||||
"commit": "c79bb1b0",
|
||||
"license": "MIT",
|
||||
"file": "src/movieclaw_tracker/sites/configs/ttg.yaml"
|
||||
},
|
||||
"domain": "https://totheglory.im/",
|
||||
"encoding": "UTF-8",
|
||||
"public": false,
|
||||
"proxy": false,
|
||||
"language": "zh",
|
||||
"result_num": 100,
|
||||
"timeout": 30,
|
||||
"search": {
|
||||
"paths": [
|
||||
{
|
||||
"path": "browse.php",
|
||||
"type": "all"
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
"search": "{keyword}"
|
||||
}
|
||||
},
|
||||
"batch": {
|
||||
"delimiter": " ",
|
||||
"space_replace": "_"
|
||||
},
|
||||
"browse": {
|
||||
"path": "browse.php?page={page}",
|
||||
"start": 1
|
||||
},
|
||||
"category": {
|
||||
"movie": [
|
||||
{
|
||||
"id": "电影DVDRip",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "电影720p",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "电影1080i/p",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "BluRay原盘",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "影视2160p",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "UHD原盘",
|
||||
"desc": "电影"
|
||||
},
|
||||
{
|
||||
"id": "iPhone/iPad视频",
|
||||
"desc": "电影"
|
||||
}
|
||||
],
|
||||
"tv": [
|
||||
{
|
||||
"id": "欧美剧720p",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "欧美剧1080i/p",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "高清日剧",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "大陆港台剧720p",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "高清韩剧",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "大陆港台剧1080i/p",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "欧美剧包",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "日剧包",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "华语剧包",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "韩剧包",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "高清体育节目",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "韩国综艺",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "日本综艺",
|
||||
"desc": "剧集"
|
||||
},
|
||||
{
|
||||
"id": "高清综艺",
|
||||
"desc": "剧集"
|
||||
}
|
||||
],
|
||||
"music": [
|
||||
{
|
||||
"id": "(电影原声&Game)OST",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "无损音乐FLAC&APE",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "MV&演唱会",
|
||||
"desc": "音乐"
|
||||
},
|
||||
{
|
||||
"id": "补充音轨",
|
||||
"desc": "音乐"
|
||||
}
|
||||
]
|
||||
},
|
||||
"torrents": {
|
||||
"list": {
|
||||
"selector": "table#torrent_table > tr[id]"
|
||||
},
|
||||
"fields": {
|
||||
"title_default": {
|
||||
"selector": "a[href*='details.php']"
|
||||
},
|
||||
"title_optional": {
|
||||
"selector": "a[href*='details.php'][title]",
|
||||
"attribute": "title"
|
||||
},
|
||||
"title": {
|
||||
"text": "{% if fields['title_optional'] %}{{ fields['title_optional'] }}{% else %}{{ fields['title_default'] }}{% endif %}"
|
||||
},
|
||||
"details": {
|
||||
"selector": "a[href*='details.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"download": {
|
||||
"selector": "a[href*='download.php']",
|
||||
"attribute": "href"
|
||||
},
|
||||
"imdbid": {
|
||||
"selector": "a[href*=\"imdb.com/title/tt\"]",
|
||||
"attribute": "href",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["tt\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"date_added": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"date": {
|
||||
"text": "{% if fields['date_elapsed'] or fields['date_added'] %}{{ fields['date_added'] if fields['date_added'] else fields['date_elapsed'] }}{% else %}now{% endif %}",
|
||||
"filters": [
|
||||
{
|
||||
"name": "dateparse",
|
||||
"args": "%Y-%m-%d %H:%M:%S"
|
||||
}
|
||||
]
|
||||
},
|
||||
"size": {
|
||||
"selector": "td:nth-child(5)"
|
||||
},
|
||||
"seeders": {
|
||||
"selector": "td:nth-child(6)"
|
||||
},
|
||||
"leechers": {
|
||||
"selector": "td:nth-child(7)"
|
||||
},
|
||||
"grabs": {
|
||||
"selector": "td:nth-child(8)"
|
||||
},
|
||||
"downloadvolumefactor": {
|
||||
"case": {
|
||||
"img[alt=\"free\"]": 0,
|
||||
"img[alt=\"50%\"]": 0.5,
|
||||
"img[alt=\"30%\"]": 0.3,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"uploadvolumefactor": {
|
||||
"case": {
|
||||
"img[alt=\"200%\"]": 2,
|
||||
"*": 1
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"selector": "td.embedded > span"
|
||||
},
|
||||
"category": {
|
||||
"selector": "td:nth-child(1) img",
|
||||
"attribute": "class",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+", 0]
|
||||
}
|
||||
]
|
||||
},
|
||||
"freedate": {
|
||||
"selector": "span[onclick]",
|
||||
"attribute": "onclick",
|
||||
"filters": [
|
||||
{
|
||||
"name": "re_search",
|
||||
"args": ["\\d+年\\d+月\\d+日\\d+点\\d+分", 0]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"umt": {
|
||||
"version": "[email protected]",
|
||||
"kind": "nexusphp",
|
||||
"displayName": "听听歌",
|
||||
"timezone": "+08:00",
|
||||
"rateLimit": {
|
||||
"minIntervalMs": 3000,
|
||||
"burst": 1
|
||||
},
|
||||
"capabilities": {
|
||||
"list": true,
|
||||
"search": true,
|
||||
"detail": true,
|
||||
"download": true,
|
||||
"rss": false
|
||||
},
|
||||
"categoryNames": {
|
||||
"电影DVDRip": "电影",
|
||||
"电影720p": "电影",
|
||||
"电影1080i/p": "电影",
|
||||
"BluRay原盘": "电影",
|
||||
"影视2160p": "电影",
|
||||
"UHD原盘": "电影",
|
||||
"iPhone/iPad视频": "电影",
|
||||
"纪录片720p": "纪录片",
|
||||
"纪录片1080i/p": "纪录片",
|
||||
"纪录片BluRay原盘": "纪录片",
|
||||
"欧美剧720p": "剧集",
|
||||
"欧美剧1080i/p": "剧集",
|
||||
"高清日剧": "剧集",
|
||||
"大陆港台剧720p": "剧集",
|
||||
"高清韩剧": "剧集",
|
||||
"大陆港台剧1080i/p": "剧集",
|
||||
"欧美剧包": "剧集",
|
||||
"日剧包": "剧集",
|
||||
"华语剧包": "剧集",
|
||||
"韩剧包": "剧集",
|
||||
"高清体育节目": "剧集",
|
||||
"韩国综艺": "剧集",
|
||||
"日本综艺": "剧集",
|
||||
"高清综艺": "剧集",
|
||||
"(电影原声&Game)OST": "音乐",
|
||||
"无损音乐FLAC&APE": "音乐",
|
||||
"MV&演唱会": "音乐",
|
||||
"补充音轨": "音乐",
|
||||
"高清动漫": "动漫",
|
||||
"MiniVideo": "其他"
|
||||
},
|
||||
"loginSuccess": "a[href='/logout.php']",
|
||||
"emptyMarkers": ["没有种子", "没有结果", "Nothing found"],
|
||||
"pagination": "a[href*=\"page=\"]",
|
||||
"detailPath": "details.php",
|
||||
"downloadPath": "download.php",
|
||||
"login": {
|
||||
"path": "login.php",
|
||||
"usernameField": "username",
|
||||
"passwordField": "password",
|
||||
"errorCss": "td.text"
|
||||
},
|
||||
"profile": {
|
||||
"path": "userdetails.php",
|
||||
"username_css": "h1::text",
|
||||
"class_css": "td.rowhead:contains('等级') + td::text",
|
||||
"uploaded_css": "td.rowhead:contains('上传量') + td::text",
|
||||
"downloaded_css": "td.rowhead:contains('下载量') + td::text",
|
||||
"ratio_css": "td.rowhead:contains('分享率') + td::text",
|
||||
"bonus_css": "td.rowhead:contains('魔力') + td::text",
|
||||
"join_date_css": "td.rowhead:contains('加入日期') + td::text",
|
||||
"seeding_css": "td.rowhead:contains('当前做种') + td::text",
|
||||
"leeching_css": "td.rowhead:contains('当前下载') + td::text"
|
||||
},
|
||||
"detail": {
|
||||
"path": "details.php",
|
||||
"title": "#top",
|
||||
"rowLabel": "td.rowhead",
|
||||
"rowValue": "td.rowfollow",
|
||||
"labels": {
|
||||
"subtitle": ["副标题", "Small Description"],
|
||||
"basicInfo": ["基本信息", "Basic Info"],
|
||||
"peers": ["同伴", "Peers"]
|
||||
},
|
||||
"description": "#kdescr",
|
||||
"headerScope": "#top",
|
||||
"notFoundMarkers": ["没有该ID的种子", "No torrent with ID"],
|
||||
"fields": {
|
||||
"title": "#top::text",
|
||||
"subtitle": "td.rowhead:contains('副标题') + td::text",
|
||||
"size": "td.rowhead:contains('大小') + td::text",
|
||||
"description": "#kdescr",
|
||||
"download": "a[href*='download.php']::attr(href)",
|
||||
"imdb": "a[href*='imdb.com']::attr(href)",
|
||||
"douban": "a[href*='douban.com']::attr(href)",
|
||||
"fileList": "td.rowfollow > ul > li::text"
|
||||
}
|
||||
},
|
||||
"customClass": "movieclaw_tracker.sites.custom.ttg.TTGSite"
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user