From d69884c6f32b391b740ba26017fb761a6cbf6812 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 20 May 2024 20:48:32 +0800 Subject: [PATCH 1/6] fix yema --- plugins/sitestatistic/siteuserinfo/yema.py | 47 +++++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/plugins/sitestatistic/siteuserinfo/yema.py b/plugins/sitestatistic/siteuserinfo/yema.py index 1cddf6b..251bc00 100644 --- a/plugins/sitestatistic/siteuserinfo/yema.py +++ b/plugins/sitestatistic/siteuserinfo/yema.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- import json from typing import Optional, Tuple +from urllib.parse import urljoin +from app.log import logger from app.plugins.sitestatistic.siteuserinfo import ISiteUserInfo, SITE_BASE_ORDER, SiteSchema from app.utils.string import StringUtils @@ -25,7 +27,11 @@ class TYemaSiteUserInfo(ISiteUserInfo): self._sys_mail_unread_page = None self._user_mail_unread_page = None self._mail_unread_params = {} - self._torrent_seeding_page = None + self._torrent_seeding_page = "api/torrent/fetchUserTorrentList" + self.__torrent_seeding_params = { + "status": "seeding", + "pageParam": {"current": 1, "pageSize": 40, "total": 40} + } self._torrent_seeding_headers = {} self._addition_headers = { "Content-Type": "application/json", @@ -78,7 +84,44 @@ class TYemaSiteUserInfo(ISiteUserInfo): """ 解析用户做种信息 """ - pass + if not html_text: + return None + seeding_info = json.loads(html_text) + if not seeding_info or not seeding_info.get("success"): + return None + torrents = seeding_info.get("data") or [] + page_seeding_size = 0 + page_seeding_info = [] + for info in torrents: + size = info.get("promotionUploadSize") + seeders = '0' + page_seeding_size += size + page_seeding_info.append([seeders, size]) + self.seeding += len(torrents) + self.seeding_size += page_seeding_size + self.seeding_info.extend(page_seeding_info) + + # 查询总做种数 + seeder_count = 0 + try: + result = self._get_page_content( + url=urljoin(self.site_url, "api/torrent/fetchUserTorrentCount"), + params={ + "status": "seeding", + } + ) + if result: + seeder_info = json.loads(result) + seeder_count = seeder_info.get("data") or 0 + except Exception as e: + logger.error(f"获取做种数失败: {str(e)}") + if not seeder_count: + return None + if self.seeding >= seeder_count: + return None + # 还有下一页 + self._torrent_seeding_params["pageParam"]["current"] += 1 + return "" def _parse_message_unread_links(self, html_text: str, msg_links: list) -> Optional[str]: """ From 2f595c6ba738c3d8974bb228b8ecad9b1250caad Mon Sep 17 00:00:00 2001 From: John Connor Date: Mon, 20 May 2024 22:56:18 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20IYUU=20=E8=BE=85=E7=A7=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81=20qBittorrent=20=E8=B7=B3=E8=BF=87=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- plugins/iyuuautoseed/__init__.py | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 434c879..de6a714 100644 --- a/package.json +++ b/package.json @@ -246,11 +246,12 @@ "name": "IYUU自动辅种", "description": "基于IYUU官方Api实现自动辅种。", "labels": "做种,IYUU", - "version": "1.8.1", + "version": "1.8.2", "icon": "IYUU.png", "author": "jxxghp", "level": 2, "history": { + "v1.8.2": "qBittorrent 支持跳过校验", "v1.8.1": "判断辅种失败的情况下,是否是由于token未进行站点绑定导致的", "v1.8": "适配新版本IYUU开发版", "v1.7": "适配馒头最新变化,需要升级至v1.8.5+版本且维护好Authorization", diff --git a/plugins/iyuuautoseed/__init__.py b/plugins/iyuuautoseed/__init__.py index fc49dfe..e72634e 100644 --- a/plugins/iyuuautoseed/__init__.py +++ b/plugins/iyuuautoseed/__init__.py @@ -57,6 +57,7 @@ class IYUUAutoSeed(_PluginBase): # 开关 _enabled = False _cron = None + _skipverify = False _onlyonce = False _token = None _downloaders = [] @@ -100,6 +101,7 @@ class IYUUAutoSeed(_PluginBase): # 读取配置 if config: self._enabled = config.get("enabled") + self._skipverify = config.get("skipverify") self._onlyonce = config.get("onlyonce") self._cron = config.get("cron") self._token = config.get("token") @@ -388,7 +390,23 @@ class IYUUAutoSeed(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 6 + 'md': 4 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'skipverify', + 'label': '跳过校验(仅qB有效)', + } + } + ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 4 }, 'content': [ { @@ -404,7 +422,7 @@ class IYUUAutoSeed(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 6 + 'md': 4 }, 'content': [ { @@ -422,6 +440,7 @@ class IYUUAutoSeed(_PluginBase): } ], { "enabled": False, + "skipverify": False, "onlyonce": False, "notify": False, "clearcache": False, @@ -440,6 +459,7 @@ class IYUUAutoSeed(_PluginBase): def __update_config(self): self.update_config({ "enabled": self._enabled, + "skipverify": self._skipverify, "onlyonce": self._onlyonce, "clearcache": self._clearcache, "cron": self._cron, @@ -738,7 +758,8 @@ class IYUUAutoSeed(_PluginBase): state = self.qb.add_torrent(content=content, download_dir=save_path, is_paused=True, - tag=["已整理", "辅种", tag]) + tag=["已整理", "辅种", tag], + is_skip_checking=self._skipverify) if not state: return None else: From e6549bfc8014d7b186139f73fa4955ec7f2ee29c Mon Sep 17 00:00:00 2001 From: John Connor Date: Mon, 20 May 2024 23:05:12 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E8=B7=B3=E8=BF=87=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E4=B8=8D=E8=BF=BD=E5=8A=A0=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/iyuuautoseed/__init__.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/plugins/iyuuautoseed/__init__.py b/plugins/iyuuautoseed/__init__.py index e72634e..0ef4966 100644 --- a/plugins/iyuuautoseed/__init__.py +++ b/plugins/iyuuautoseed/__init__.py @@ -880,17 +880,21 @@ class IYUUAutoSeed(_PluginBase): return False else: self.success += 1 - # 追加校验任务 - logger.info(f"添加校验检查任务:{download_id} ...") - if not self._recheck_torrents.get(downloader): - self._recheck_torrents[downloader] = [] - self._recheck_torrents[downloader].append(download_id) + if self._skipverify: + # 跳过校验 + logger.info(f"{download_id} 跳过校验,请自行检查...") + else: + # 追加校验任务 + logger.info(f"添加校验检查任务:{download_id} ...") + if not self._recheck_torrents.get(downloader): + self._recheck_torrents[downloader] = [] + self._recheck_torrents[downloader].append(download_id) + # TR会自动校验 + if downloader == "qbittorrent": + # 开始校验种子 + downloader_obj.recheck_torrents(ids=[download_id]) # 下载成功 logger.info(f"成功添加辅种下载,站点:{site_info.get('name')},种子链接:{torrent_url}") - # TR会自动校验 - if downloader == "qbittorrent": - # 开始校验种子 - downloader_obj.recheck_torrents(ids=[download_id]) # 成功也加入缓存,有一些改了路径校验不通过的,手动删除后,下一次又会辅上 self._success_caches.append(seed.get("info_hash")) return True From bed7f191f683bb7e333ee7dc4487784ee99c47ae Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Mon, 20 May 2024 23:30:48 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81QB=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E7=A7=8D=E5=AD=90=E6=97=B6=E5=BC=BA=E5=88=B6=E6=B1=87?= =?UTF-8?q?=E6=8A=A5Tracker=EF=BC=8C=E7=AB=99=E7=82=B9=E7=8B=AC=E7=AB=8B?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=A2=9E=E5=8A=A0=E3=80=8C=E7=AB=99=E7=82=B9?= =?UTF-8?q?=E5=85=A8=E5=B1=80H&R=E3=80=8D=E9=85=8D=E7=BD=AE=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- plugins/brushflow/__init__.py | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8fa30ac..71760a3 100644 --- a/package.json +++ b/package.json @@ -315,11 +315,12 @@ "name": "站点刷流", "description": "自动托管刷流,将会提高对应站点的访问频率。", "labels": "刷流", - "version": "3.2", + "version": "3.3", "icon": "brush.jpg", "author": "jxxghp,InfinityPacer", "level": 2, "history": { + "v3.3": "支持QB删除种子时强制汇报Tracker,站点独立配置增加「站点全局H&R」配置项", "v3.2": "支持推送QB种子时启用「先下载首尾文件块」选项", "v3.1": "支持仪表板显示站点刷流数据,需要主程序升级v1.8.7+版本", "v3.0": "优化不同站点刷流到相同种子的逻辑,修复数据页滚动闪烁,部分日志优化", diff --git a/plugins/brushflow/__init__.py b/plugins/brushflow/__init__.py index 74a1c7a..e41bea4 100644 --- a/plugins/brushflow/__init__.py +++ b/plugins/brushflow/__init__.py @@ -77,6 +77,7 @@ class BrushConfig: self.qb_category = config.get("qb_category") self.auto_qb_category = config.get("auto_qb_category", False) self.qb_first_last_piece = config.get("qb_first_last_piece", False) + self.site_hr_active = config.get("site_hr_active", False) self.brush_tag = "刷流" # 站点独立配置 @@ -121,6 +122,7 @@ class BrushConfig: "qb_category", "auto_qb_category", "qb_first_last_piece", + "site_hr_active" # 当新增支持字段时,仅在此处添加字段名 } try: @@ -188,7 +190,8 @@ class BrushConfig: "proxy_delete": false, "qb_category": "刷流", "auto_qb_category": true, - "qb_first_last_piece": true + "qb_first_last_piece": true, + "site_hr_active": true }]""" return desc + config @@ -254,7 +257,7 @@ class BrushFlow(_PluginBase): # 插件图标 plugin_icon = "brush.jpg" # 插件版本 - plugin_version = "3.2" + plugin_version = "3.3" # 插件作者 plugin_author = "jxxghp,InfinityPacer" # 作者主页 @@ -2048,6 +2051,12 @@ class BrushFlow(_PluginBase): brush_config = self.__get_brush_config(sitename=siteinfo.name) + if brush_config.site_hr_active: + logger.info(f"站点 {siteinfo.name} 已开启全站H&R选项,所有种子设置为H&R种子") + # 由于缓存原因,这里不能直接改torrents,在后续加入任务中调整 + # for torrent in torrents: + # torrent.hit_and_run = True + # 排除包含订阅的种子 if brush_config.except_subscribe: torrents = self.__filter_torrents_contains_subscribe(torrents=torrents, subscribe_titles=subscribe_titles) @@ -2109,7 +2118,7 @@ class BrushFlow(_PluginBase): "freedate": torrent.freedate, "uploadvolumefactor": torrent.uploadvolumefactor, "downloadvolumefactor": torrent.downloadvolumefactor, - "hit_and_run": torrent.hit_and_run, + "hit_and_run": torrent.hit_and_run or brush_config.site_hr_active, "volume_factor": torrent.volume_factor, "freedate_diff": torrent.freedate_diff, # "labels": torrent.labels, @@ -2382,6 +2391,10 @@ class BrushFlow(_PluginBase): need_delete_hashes.extend(not_proxy_delete_hashes) if need_delete_hashes: + # 如果是QB,则重新汇报Tracker + if brush_config.downloader == "qbittorrent": + self.__qb_torrents_reannounce(torrent_hashes=need_delete_hashes) + # 删除种子 if downloader.delete_torrents(ids=need_delete_hashes, delete_file=True): for torrent_hash in need_delete_hashes: torrent_tasks[torrent_hash]["deleted"] = True @@ -3280,6 +3293,20 @@ class BrushFlow(_PluginBase): logger.error(f"添加种子出错:{str(err)}") return False + def __qb_torrents_reannounce(self, torrent_hashes: List[str]): + """强制重新汇报""" + if not self.qb.qbc: + return + + if not torrent_hashes: + return + + try: + # 重新汇报 + self.qb.qbc.torrents_reannounce(torrent_hashes=torrent_hashes) + except Exception as err: + logger.error(f"强制重新汇报失败:{str(err)}") + def __get_hash(self, torrent: Any): """ 获取种子hash From 72d03c5658a470b8815e3ee5145be7fddfd2e100 Mon Sep 17 00:00:00 2001 From: John Connor Date: Tue, 21 May 2024 00:03:22 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix=20=E6=9B=B4=E6=96=B0=20iyuuautoseed=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/iyuuautoseed/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/iyuuautoseed/__init__.py b/plugins/iyuuautoseed/__init__.py index 0ef4966..5351e81 100644 --- a/plugins/iyuuautoseed/__init__.py +++ b/plugins/iyuuautoseed/__init__.py @@ -34,7 +34,7 @@ class IYUUAutoSeed(_PluginBase): # 插件图标 plugin_icon = "IYUU.png" # 插件版本 - plugin_version = "1.8.1" + plugin_version = "1.8.2" # 插件作者 plugin_author = "jxxghp" # 作者主页 From 838ade49ac9cb889f8f56f290781f7e121b36cbf Mon Sep 17 00:00:00 2001 From: ljmeng Date: Tue, 21 May 2024 00:57:40 +0800 Subject: [PATCH 6/6] =?UTF-8?q?feat:=20=E8=BD=AC=E7=A7=BB=E5=81=9A?= =?UTF-8?q?=E7=A7=8D=E6=94=AF=E6=8C=81=E5=88=A0=E9=99=A4=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=A7=8D=E5=AD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 7 +++-- plugins/torrenttransfer/__init__.py | 45 ++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 434c879..e15186c 100644 --- a/package.json +++ b/package.json @@ -287,10 +287,13 @@ "name": "自动转移做种", "description": "定期转移下载器中的做种任务到另一个下载器。", "labels": "做种", - "version": "1.3", + "version": "1.4", "icon": "seed.png", "author": "jxxghp", - "level": 2 + "level": 2, + "history": { + "v1.4": "支持自动删除源下载器在目的下载器中存在的种子" + } }, "RssSubscribe": { "name": "自定义订阅", diff --git a/plugins/torrenttransfer/__init__.py b/plugins/torrenttransfer/__init__.py index d21296e..c304a59 100644 --- a/plugins/torrenttransfer/__init__.py +++ b/plugins/torrenttransfer/__init__.py @@ -27,7 +27,7 @@ class TorrentTransfer(_PluginBase): # 插件图标 plugin_icon = "seed.png" # 插件版本 - plugin_version = "1.3" + plugin_version = "1.4" # 插件作者 plugin_author = "jxxghp" # 作者主页 @@ -57,6 +57,7 @@ class TorrentTransfer(_PluginBase): _includelabels = None _nopaths = None _deletesource = False + _deleteduplicate = False _fromtorrentpath = None _autostart = False _transferemptylabel = False @@ -83,6 +84,7 @@ class TorrentTransfer(_PluginBase): self._fromdownloader = config.get("fromdownloader") self._todownloader = config.get("todownloader") self._deletesource = config.get("deletesource") + self._deleteduplicate = config.get("deleteduplicate") self._fromtorrentpath = config.get("fromtorrentpath") self._nopaths = config.get("nopaths") self._autostart = config.get("autostart") @@ -131,6 +133,7 @@ class TorrentTransfer(_PluginBase): "fromdownloader": self._fromdownloader, "todownloader": self._todownloader, "deletesource": self._deletesource, + "deleteduplicate": self._deleteduplicate, "fromtorrentpath": self._fromtorrentpath, "nopaths": self._nopaths, "autostart": self._autostart, @@ -420,7 +423,7 @@ class TorrentTransfer(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 }, 'content': [ { @@ -436,7 +439,7 @@ class TorrentTransfer(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 }, 'content': [ { @@ -452,7 +455,23 @@ class TorrentTransfer(_PluginBase): 'component': 'VCol', 'props': { 'cols': 12, - 'md': 4 + 'md': 3 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'deleteduplicate', + 'label': '删除重复种子', + } + } + ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 3 }, 'content': [ { @@ -480,6 +499,7 @@ class TorrentTransfer(_PluginBase): "fromdownloader": "", "todownloader": "", "deletesource": False, + "deleteduplicate": False, "fromtorrentpath": "", "nopaths": "", "autostart": True, @@ -630,6 +650,8 @@ class TorrentTransfer(_PluginBase): fail = 0 # 跳过数 skip = 0 + # 删除重复数 + del_dup = 0 for torrent_item in trans_torrents: # 检查种子文件是否存在 @@ -644,9 +666,15 @@ class TorrentTransfer(_PluginBase): todownloader_obj = self.__get_downloader(todownloader) torrent_info, _ = todownloader_obj.get_torrents(ids=[torrent_item.get('hash')]) if torrent_info: - logger.info(f"{torrent_item.get('hash')} 已在目的下载器中,跳过 ...") - # 跳过计数 - skip += 1 + # 删除重复的源种子,不能删除文件! + if self._deleteduplicate: + logger.info(f"删除重复的源下载器任务(不含文件):{torrent_item.get('hash')} ...") + downloader_obj.delete_torrents(delete_file=False, ids=[torrent_item.get('hash')]) + del_dup += 1 + else: + logger.info(f"{torrent_item.get('hash')} 已在目的下载器中,跳过 ...") + # 跳过计数 + skip += 1 continue # 转换保存路径 @@ -744,6 +772,7 @@ class TorrentTransfer(_PluginBase): "to_download": self._todownloader, "to_download_id": download_id, "delete_source": self._deletesource, + "delete_duplicate": self._deleteduplicate, }) # 触发校验任务 if success > 0 and self._autostart: @@ -754,7 +783,7 @@ class TorrentTransfer(_PluginBase): self.post_message( mtype=NotificationType.SiteMessage, title="【转移做种任务执行完成】", - text=f"总数:{total},成功:{success},失败:{fail},跳过:{skip}" + text=f"总数:{total},成功:{success},失败:{fail},跳过:{skip},删除重复:{del_dup}" ) else: logger.info(f"没有需要转移的种子")