From d33739b7a72abf59a28e9ff157635defab54d0c2 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Sun, 20 Oct 2024 00:10:38 +0800 Subject: [PATCH] =?UTF-8?q?refactor=EF=BC=9A=E8=87=AA=E5=8A=A8=E5=88=A0?= =?UTF-8?q?=E7=A7=8D=20v2=20refactor=EF=BC=9AIYUU=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=BE=85=E7=A7=8D=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.v2.json | 24 +++++ plugins.v2/iyuuautoseed/__init__.py | 121 +++++++++++++------------- plugins.v2/torrentremover/__init__.py | 58 +++++++----- 3 files changed, 124 insertions(+), 79 deletions(-) diff --git a/package.v2.json b/package.v2.json index 079036a..a59e5a6 100644 --- a/package.v2.json +++ b/package.v2.json @@ -188,5 +188,29 @@ "v2.6": "支持DOH相关配置项", "v2.5": "增加Github加速服务器设置项" } + }, + "TorrentRemover": { + "name": "自动删种", + "description": "自动删除下载器中的下载任务。", + "labels": "做种", + "version": "2.0", + "icon": "delete.jpg", + "author": "jxxghp", + "level": 2, + "history": { + "v2.0": "兼容MoviePilot V2 版本" + } + }, + "IYUUAutoSeed": { + "name": "IYUU自动辅种", + "description": "基于IYUU官方Api实现自动辅种。", + "labels": "做种,IYUU", + "version": "2.0", + "icon": "IYUU.png", + "author": "jxxghp", + "level": 2, + "history": { + "v2.0": "兼容MoviePilot V2 版本" + } } } \ No newline at end of file diff --git a/plugins.v2/iyuuautoseed/__init__.py b/plugins.v2/iyuuautoseed/__init__.py index 64e4f2f..3e2567b 100644 --- a/plugins.v2/iyuuautoseed/__init__.py +++ b/plugins.v2/iyuuautoseed/__init__.py @@ -13,14 +13,13 @@ from ruamel.yaml import CommentedMap from app.core.config import settings from app.core.event import eventmanager from app.db.site_oper import SiteOper +from app.helper.downloader import DownloaderHelper from app.helper.sites import SitesHelper from app.helper.torrent import TorrentHelper from app.log import logger -from app.modules.qbittorrent import Qbittorrent -from app.modules.transmission import Transmission from app.plugins import _PluginBase from app.plugins.iyuuautoseed.iyuu_helper import IyuuHelper -from app.schemas import NotificationType +from app.schemas import NotificationType, ServiceInfo from app.schemas.types import EventType from app.utils.http import RequestUtils from app.utils.string import StringUtils @@ -34,7 +33,7 @@ class IYUUAutoSeed(_PluginBase): # 插件图标 plugin_icon = "IYUU.png" # 插件版本 - plugin_version = "1.9.5" + plugin_version = "2.0" # 插件作者 plugin_author = "jxxghp" # 作者主页 @@ -49,11 +48,10 @@ class IYUUAutoSeed(_PluginBase): # 私有属性 _scheduler = None iyuuhelper = None - qb = None - tr = None sites = None siteoper = None torrent = None + downloader_helper = None # 开关 _enabled = False _cron = None @@ -100,6 +98,7 @@ class IYUUAutoSeed(_PluginBase): self.sites = SitesHelper() self.siteoper = SiteOper() self.torrent = TorrentHelper() + self.downloader_helper = DownloaderHelper() # 读取配置 if config: self._enabled = config.get("enabled") @@ -134,8 +133,6 @@ class IYUUAutoSeed(_PluginBase): if self.get_state() or self._onlyonce: self.iyuuhelper = IyuuHelper(token=self._token) self._scheduler = BackgroundScheduler(timezone=settings.TZ) - self.qb = Qbittorrent() - self.tr = Transmission() if self._onlyonce: logger.info(f"辅种服务启动,立即运行一次") @@ -305,38 +302,19 @@ class IYUUAutoSeed(_PluginBase): { 'component': 'VCol', 'props': { - 'cols': 12, - 'md': 6 + 'cols': 12 }, 'content': [ { 'component': 'VSelect', 'props': { - 'chips': True, 'multiple': True, + 'chips': True, + 'clearable': True, 'model': 'downloaders', - 'label': '辅种下载器', - 'items': [ - {'title': 'Qbittorrent', 'value': 'qbittorrent'}, - {'title': 'Transmission', 'value': 'transmission'} - ] - } - } - ] - }, - { - 'component': 'VCol', - 'props': { - 'cols': 12, - 'md': 6 - }, - 'content': [ - { - 'component': 'VTextField', - 'props': { - 'model': 'size', - 'label': '辅种体积大于(GB)', - 'placeholder': '只有大于该值的才辅种' + 'label': '下载器', + 'items': [{"title": config.name, "value": config.name} + for config in self.downloader_helper.get_configs().values()] } } ] @@ -515,6 +493,33 @@ class IYUUAutoSeed(_PluginBase): def get_page(self) -> List[dict]: pass + @property + def service_infos(self) -> Optional[Dict[str, ServiceInfo]]: + """ + 服务信息 + """ + if not self._downloaders: + logger.warning("尚未配置下载器,请检查配置") + return None + + services = self.downloader_helper.get_services(name_filters=self._downloaders) + if not services: + logger.warning("获取下载器实例失败,请检查配置") + return None + + active_services = {} + for service_name, service_info in services.items(): + if service_info.instance.is_inactive(): + logger.warning(f"下载器 {service_name} 未连接,请检查配置") + else: + active_services[service_name] = service_info + + if not active_services: + logger.warning("没有已连接的下载器,请检查配置") + return None + + return active_services + def __update_config(self): self.update_config({ "enabled": self._enabled, @@ -537,16 +542,11 @@ class IYUUAutoSeed(_PluginBase): "permanent_error_caches": self._permanent_error_caches }) - def __get_downloader(self, dtype: str): + def __get_downloader(self, name: str): """ 根据类型返回下载器实例 """ - if dtype == "qbittorrent": - return self.qb - elif dtype == "transmission": - return self.tr - else: - return None + return self.service_infos.get(name).instance def auto_seed(self): """ @@ -821,33 +821,37 @@ class IYUUAutoSeed(_PluginBase): """ 添加下载任务 """ - if downloader == "qbittorrent": + service = self.service_infos.get(downloader) + if not service: + logger.error(f"下载器 {downloader} 未连接,添加下载任务失败!") + return None + if service.type == "qbittorrent": # 生成随机Tag tag = StringUtils.generate_random_str(10) torrent_tags.append(tag) - state = self.qb.add_torrent(content=content, - download_dir=save_path, - is_paused=True, - tag=torrent_tags, - category=self._categoryafterseed, - is_skip_checking=self._skipverify) + state = service.instance.add_torrent(content=content, + download_dir=save_path, + is_paused=True, + tag=torrent_tags, + category=self._categoryafterseed, + is_skip_checking=self._skipverify) if not state: return None else: # 获取种子Hash - torrent_hash = self.qb.get_torrent_id_by_tag(tags=tag) + torrent_hash = service.instance.get_torrent_id_by_tag(tags=tag) if not torrent_hash: logger.error(f"{downloader} 下载任务添加成功,但获取任务信息失败!") return None return torrent_hash - elif downloader == "transmission": + elif service.type == "transmission": # 添加任务 - torrent = self.tr.add_torrent(content=content, - download_dir=save_path, - is_paused=True, - labels=torrent_tags) + torrent = service.instance.add_torrent(content=content, + download_dir=save_path, + is_paused=True, + labels=torrent_tags) if not torrent: return None else: @@ -1044,7 +1048,7 @@ class IYUUAutoSeed(_PluginBase): 判断是否为mteam站点 """ return True if "m-team." in url else False - + def __is_monika(url: str): """ 判断是否为monika站点 @@ -1063,7 +1067,7 @@ class IYUUAutoSeed(_PluginBase): 将mteam种子下载链接域名替换为使用API """ api_url = re.sub(r'//[^/]+\.m-team', '//api.m-team', site.get('url')) - + res = RequestUtils( headers={ 'Content-Type': 'application/json', @@ -1078,7 +1082,7 @@ class IYUUAutoSeed(_PluginBase): logger.warn(f"m-team 获取种子下载链接失败:{tid}") return None return res.json().get("data") - + def __get_monika_torrent(tid: str, rssurl: str): """ Monika下载需要使用rsskey从站点配置中获取并拼接下载链接 @@ -1086,11 +1090,10 @@ class IYUUAutoSeed(_PluginBase): if not rssurl: logger.error("Monika站点的rss链接未配置") return None - + rss_match = re.search(r'/rss/\d+\.(\w+)', rssurl) rsskey = rss_match.group(1) - download_url = f"{site.get('url')}torrents/download/{tid}.{rsskey}" - return download_url + return f"{site.get('url')}torrents/download/{tid}.{rsskey}" def __is_special_site(url: str): """ diff --git a/plugins.v2/torrentremover/__init__.py b/plugins.v2/torrentremover/__init__.py index 73848e0..8a87421 100644 --- a/plugins.v2/torrentremover/__init__.py +++ b/plugins.v2/torrentremover/__init__.py @@ -9,11 +9,10 @@ from apscheduler.schedulers.background import BackgroundScheduler from apscheduler.triggers.cron import CronTrigger from app.core.config import settings +from app.helper.downloader import DownloaderHelper from app.log import logger -from app.modules.qbittorrent import Qbittorrent -from app.modules.transmission import Transmission from app.plugins import _PluginBase -from app.schemas import NotificationType +from app.schemas import NotificationType, ServiceInfo from app.utils.string import StringUtils lock = threading.Lock() @@ -27,7 +26,7 @@ class TorrentRemover(_PluginBase): # 插件图标 plugin_icon = "delete.jpg" # 插件版本 - plugin_version = "1.2.2" + plugin_version = "2.0" # 插件作者 plugin_author = "jxxghp" # 作者主页 @@ -40,8 +39,7 @@ class TorrentRemover(_PluginBase): auth_level = 2 # 私有属性 - qb = None - tr = None + downloader_helper = None _event = threading.Event() _scheduler = None _enabled = False @@ -65,6 +63,7 @@ class TorrentRemover(_PluginBase): _torrentcategorys = None def init_plugin(self, config: dict = None): + self.downloader_helper = DownloaderHelper() if config: self._enabled = config.get("enabled") self._onlyonce = config.get("onlyonce") @@ -88,8 +87,6 @@ class TorrentRemover(_PluginBase): self.stop_service() if self.get_state() or self._onlyonce: - self.qb = Qbittorrent() - self.tr = Transmission() if self._onlyonce: self._scheduler = BackgroundScheduler(timezone=settings.TZ) logger.info(f"自动删种服务启动,立即运行一次") @@ -254,14 +251,13 @@ class TorrentRemover(_PluginBase): { 'component': 'VSelect', 'props': { - 'chips': True, 'multiple': True, + 'chips': True, + 'clearable': True, 'model': 'downloaders', 'label': '下载器', - 'items': [ - {'title': 'Qbittorrent', 'value': 'qbittorrent'}, - {'title': 'Transmission', 'value': 'transmission'} - ] + 'items': [{"title": config.name, "value": config.name} + for config in self.downloader_helper.get_configs().values()] } } ] @@ -588,16 +584,38 @@ class TorrentRemover(_PluginBase): except Exception as e: print(str(e)) - def __get_downloader(self, dtype: str): + @property + def service_infos(self) -> Optional[Dict[str, ServiceInfo]]: + """ + 服务信息 + """ + if not self._downloaders: + logger.warning("尚未配置下载器,请检查配置") + return None + + services = self.downloader_helper.get_services(name_filters=self._downloaders) + if not services: + logger.warning("获取下载器实例失败,请检查配置") + return None + + active_services = {} + for service_name, service_info in services.items(): + if service_info.instance.is_inactive(): + logger.warning(f"下载器 {service_name} 未连接,请检查配置") + else: + active_services[service_name] = service_info + + if not active_services: + logger.warning("没有已连接的下载器,请检查配置") + return None + + return active_services + + def __get_downloader(self, name: str): """ 根据类型返回下载器实例 """ - if dtype == "qbittorrent": - return self.qb - elif dtype == "transmission": - return self.tr - else: - return None + return self.service_infos.get(name).instance def delete_torrents(self): """