From 7536a8782ec820aabbdf79197926b27bb1cf9386 Mon Sep 17 00:00:00 2001 From: xslidi Date: Tue, 18 Nov 2025 20:34:16 +0800 Subject: [PATCH] Support GPW url --- package.json | 3 +- package.v2.json | 3 +- plugins.v2/iyuuautoseed/__init__.py | 76 ++++++++++++++++++++++++++++- plugins/iyuuautoseed/__init__.py | 75 +++++++++++++++++++++++++++- 4 files changed, 153 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 20d82e2..9096ede 100644 --- a/package.json +++ b/package.json @@ -321,11 +321,12 @@ "name": "IYUU自动辅种", "description": "基于IYUU官方Api实现自动辅种。", "labels": "做种,IYUU", - "version": "1.9.11", + "version": "1.9.12", "icon": "IYUU.png", "author": "jxxghp", "level": 2, "history": { + "v1.9.12": "修复海豹不能辅种的问题", "v1.9.11": "修复馒头不能辅种的问题", "v1.9.10": "Revert 辅种结束后,一起开始所有辅种后暂停的种子(排除了出错的种子)", "v1.9.9": "修复qb辅种结束后自动开始暂停的种子", diff --git a/package.v2.json b/package.v2.json index 8808789..76546c2 100644 --- a/package.v2.json +++ b/package.v2.json @@ -244,11 +244,12 @@ "name": "IYUU自动辅种", "description": "基于IYUU官方Api实现自动辅种。", "labels": "做种,IYUU", - "version": "2.14", + "version": "2.15", "icon": "IYUU.png", "author": "jxxghp,CKun", "level": 2, "history": { + "v2.15": "修复海豹不能辅种的问题", "v2.14": "修复馒头不能辅种的问题", "v2.13": "开启跳过校验后需手动开启自动开始", "v2.12": "增加qb下载器分类复用配置", diff --git a/plugins.v2/iyuuautoseed/__init__.py b/plugins.v2/iyuuautoseed/__init__.py index c64cde1..7e2480b 100644 --- a/plugins.v2/iyuuautoseed/__init__.py +++ b/plugins.v2/iyuuautoseed/__init__.py @@ -3,6 +3,7 @@ import re from datetime import datetime, timedelta from threading import Event from typing import Any, Dict, List, Optional, Tuple +from urllib.parse import urljoin import pytz from apscheduler.schedulers.background import BackgroundScheduler @@ -33,7 +34,7 @@ class IYUUAutoSeed(_PluginBase): # 插件图标 plugin_icon = "IYUU.png" # 插件版本 - plugin_version = "2.14" + plugin_version = "2.15" # 插件作者 plugin_author = "jxxghp,CKun" # 作者主页 @@ -1224,6 +1225,12 @@ class IYUUAutoSeed(_PluginBase): """ return True if "monikadesign." in url else False + def __is_gpw(url: str): + """ + 判断是否为gpw站点 + """ + return True if "greatposterwall." in url else False + def __get_mteam_enclosure(tid: str, apikey: str): """ 获取mteam种子下载链接 @@ -1264,6 +1271,69 @@ class IYUUAutoSeed(_PluginBase): rsskey = rss_match.group(1) return f"{site.get('url')}torrents/download/{tid}.{rsskey}" + def __get_gpw_torrent_url_from_page(seed: dict, site: dict): + """ + 从详情页面获取下载链接 + """ + if not site.get('url'): + logger.warn(f"站点 {site.get('name')} 未获取站点地址,无法获取种子下载链接") + return None + + try: + page_url = f"{site.get('url')}torrents.php?torrentid={seed.get('torrent_id')}&hit=1" + logger.info(f"正在获取种子下载链接:{page_url} ...") + + res = RequestUtils( + cookies=site.get("cookie"), + ua=site.get("ua") or settings.USER_AGENT, + proxies=settings.PROXY if site.get("proxy") else None + ).get_res(url=page_url) + + + if res is None or res.status_code not in (200, 500): + logger.error(f"获取种子下载链接失败,请求失败:{page_url},{res.status_code if res else ''}") + return None + # Fix encoding + if "charset=utf-8" in res.text or "charset=UTF-8" in res.text: + res.encoding = "UTF-8" + else: + res.encoding = res.apparent_encoding + + if not res.text: + logger.warn(f"获取种子下载链接失败,页面内容为空:{page_url}") + return None + # 使用xpath从页面中获取下载链接 + html = etree.HTML(res.text) + if html is None: + logger.warning(f"解析页面失败:{page_url}") + return None + + xpath = "//a[contains(@href, 'torrents.php?action=download')]/@href" + urls = html.xpath(xpath) + + if not urls: + logger.warning(f"获取种子下载链接失败,未找到下载链接:{page_url}") + return None + + torrent_id = str(seed.get("torrent_id")) + matched_url = None + # Strict match using regex id=xxxx + for u in urls: + if re.search(rf"id={torrent_id}(?:&|$)", u): + matched_url = u + break + if not matched_url: + logger.warning(f"未找到与 torrent_id={torrent_id} 对应的下载链接") + return None + + final_url = urljoin(site['url'], matched_url) + + logger.info(f"获取种子下载链接成功:{final_url}") + return final_url + except Exception as e: + logger.warn(f"获取种子下载链接失败:{str(e)}") + return None + def __is_special_site(url: str): """ 判断是否为特殊站点 @@ -1288,6 +1358,10 @@ class IYUUAutoSeed(_PluginBase): if __is_monika(site.get('url')): # 返回种子id和站点配置中所Monika的rss链接 return __get_monika_torrent(tid=seed.get("torrent_id"), rssurl=site.get("rss")) + if __is_gpw(site.get('url')): + # 从详情页面获取下载链接 + return __get_gpw_torrent_url_from_page(seed=seed, site=site) + elif __is_special_site(site.get('url')): # 从详情页面获取下载链接 return self.__get_torrent_url_from_page(seed=seed, site=site) diff --git a/plugins/iyuuautoseed/__init__.py b/plugins/iyuuautoseed/__init__.py index 0086e4d..d419530 100644 --- a/plugins/iyuuautoseed/__init__.py +++ b/plugins/iyuuautoseed/__init__.py @@ -3,6 +3,7 @@ import re from datetime import datetime, timedelta from threading import Event from typing import Any, List, Dict, Tuple, Optional +from urllib.parse import urljoin import pytz from apscheduler.schedulers.background import BackgroundScheduler @@ -34,7 +35,7 @@ class IYUUAutoSeed(_PluginBase): # 插件图标 plugin_icon = "IYUU.png" # 插件版本 - plugin_version = "1.9.11" + plugin_version = "1.9.12" # 插件作者 plugin_author = "jxxghp" # 作者主页 @@ -1051,6 +1052,12 @@ class IYUUAutoSeed(_PluginBase): 判断是否为monika站点 """ return True if "monikadesign." in url else False + + def __is_gpw(url: str): + """ + 判断是否为gpw站点 + """ + return True if "greatposterwall." in url else False def __get_mteam_enclosure(tid: str, apikey: str): """ @@ -1092,6 +1099,69 @@ class IYUUAutoSeed(_PluginBase): rsskey = rss_match.group(1) return f"{site.get('url')}torrents/download/{tid}.{rsskey}" + def __get_gpw_torrent_url_from_page(seed: dict, site: dict): + """ + 从详情页面获取下载链接 + """ + if not site.get('url'): + logger.warn(f"站点 {site.get('name')} 未获取站点地址,无法获取种子下载链接") + return None + + try: + page_url = f"{site.get('url')}torrents.php?torrentid={seed.get('torrent_id')}&hit=1" + logger.info(f"正在获取种子下载链接:{page_url} ...") + + res = RequestUtils( + cookies=site.get("cookie"), + ua=site.get("ua") or settings.USER_AGENT, + proxies=settings.PROXY if site.get("proxy") else None + ).get_res(url=page_url) + + + if res is None or res.status_code not in (200, 500): + logger.error(f"获取种子下载链接失败,请求失败:{page_url},{res.status_code if res else ''}") + return None + # Fix encoding + if "charset=utf-8" in res.text or "charset=UTF-8" in res.text: + res.encoding = "UTF-8" + else: + res.encoding = res.apparent_encoding + + if not res.text: + logger.warn(f"获取种子下载链接失败,页面内容为空:{page_url}") + return None + # 使用xpath从页面中获取下载链接 + html = etree.HTML(res.text) + if html is None: + logger.warning(f"解析页面失败:{page_url}") + return None + + xpath = "//a[contains(@href, 'torrents.php?action=download')]/@href" + urls = html.xpath(xpath) + + if not urls: + logger.warning(f"获取种子下载链接失败,未找到下载链接:{page_url}") + return None + + torrent_id = str(seed.get("torrent_id")) + matched_url = None + # Strict match using regex id=xxxx + for u in urls: + if re.search(rf"id={torrent_id}(?:&|$)", u): + matched_url = u + break + if not matched_url: + logger.warning(f"未找到与 torrent_id={torrent_id} 对应的下载链接") + return None + + final_url = urljoin(site['url'], matched_url) + + logger.info(f"获取种子下载链接成功:{final_url}") + return final_url + except Exception as e: + logger.warn(f"获取种子下载链接失败:{str(e)}") + return None + def __is_special_site(url: str): """ 判断是否为特殊站点 @@ -1116,6 +1186,9 @@ class IYUUAutoSeed(_PluginBase): if __is_monika(site.get('url')): # 返回种子id和站点配置中所Monika的rss链接 return __get_monika_torrent(tid=seed.get("torrent_id"), rssurl=site.get("rss")) + if __is_gpw(site.get('url')): + # 从详情页面获取下载链接 + return __get_gpw_torrent_url_from_page(seed=seed, site=site) elif __is_special_site(site.get('url')): # 从详情页面获取下载链接 return self.__get_torrent_url_from_page(seed=seed, site=site)