diff --git a/app/modules/qbittorrent/qbittorrent.py b/app/modules/qbittorrent/qbittorrent.py index f4d9f20d..d341f38e 100644 --- a/app/modules/qbittorrent/qbittorrent.py +++ b/app/modules/qbittorrent/qbittorrent.py @@ -106,6 +106,8 @@ class Qbittorrent(metaclass=Singleton): :param ids: 种子Hash列表 :param tag: 标签内容 """ + if not self.qbc: + return False try: self.qbc.torrents_delete_tags(torrent_hashes=ids, tags=tag) return True @@ -129,6 +131,8 @@ class Qbittorrent(metaclass=Singleton): """ 设置强制作种 """ + if not self.qbc: + return try: self.qbc.torrents_set_force_start(enable=True, torrent_hashes=ids) except Exception as err: @@ -266,6 +270,8 @@ class Qbittorrent(metaclass=Singleton): """ 获取种子文件清单 """ + if not self.qbc: + return None try: return self.qbc.torrents_files(torrent_hash=tid) except Exception as err: @@ -276,6 +282,8 @@ class Qbittorrent(metaclass=Singleton): """ 设置下载文件的状态,priority为0为不下载,priority为1为下载 """ + if not self.qbc: + return False if not kwargs.get("torrent_hash") or not kwargs.get("file_ids"): return False try: @@ -291,6 +299,8 @@ class Qbittorrent(metaclass=Singleton): """ 获取传输信息 """ + if not self.qbc: + return None try: return self.qbc.transfer_info() except Exception as err: diff --git a/app/modules/transmission/transmission.py b/app/modules/transmission/transmission.py index 3d6577ab..e0dfe222 100644 --- a/app/modules/transmission/transmission.py +++ b/app/modules/transmission/transmission.py @@ -115,6 +115,8 @@ class Transmission(metaclass=Singleton): """ 设置种子标签 """ + if not self.trc: + return False if not ids or not tags: return False try: @@ -138,6 +140,8 @@ class Transmission(metaclass=Singleton): :param cookie: 站点Cookie用于辅助下载种子 :return: Torrent """ + if not self.trc: + return None try: return self.trc.add_torrent(torrent=content, download_dir=download_dir, @@ -193,6 +197,8 @@ class Transmission(metaclass=Singleton): """ 获取种子文件列表 """ + if not self.trc: + return None if not tid: return None try: @@ -209,6 +215,8 @@ class Transmission(metaclass=Singleton): """ 设置下载文件的状态 """ + if not self.trc: + return False try: self.trc.change_torrent(ids=tid, files_wanted=file_ids) return True @@ -220,6 +228,8 @@ class Transmission(metaclass=Singleton): """ 获取传输信息 """ + if not self.trc: + return None try: return self.trc.session_stats() except Exception as err: diff --git a/app/plugins/cloudflarespeedtest/__init__.py b/app/plugins/cloudflarespeedtest/__init__.py index fe11f290..aedb0bf6 100644 --- a/app/plugins/cloudflarespeedtest/__init__.py +++ b/app/plugins/cloudflarespeedtest/__init__.py @@ -87,8 +87,9 @@ class CloudflareSpeedTest(_PluginBase): if self._onlyonce: logger.info(f"Cloudflare CDN优选服务启动,立即运行一次") - self._scheduler.add_job(self.__cloudflareSpeedTest, 'date', - run_date=datetime.now(tz=pytz.timezone(settings.TZ)) + timedelta(seconds=3)) + self._scheduler.add_job(func=self.__cloudflareSpeedTest, trigger='date', + run_date=datetime.now(tz=pytz.timezone(settings.TZ)) + timedelta(seconds=3), + name="Cloudflare优选") # 关闭一次性开关 self._onlyonce = False self.__update_config() diff --git a/app/plugins/doubanrank/__init__.py b/app/plugins/doubanrank/__init__.py index dd9b2f4d..35709df9 100644 --- a/app/plugins/doubanrank/__init__.py +++ b/app/plugins/doubanrank/__init__.py @@ -88,13 +88,16 @@ class DoubanRank(_PluginBase): if self._cron: logger.info(f"豆瓣榜单订阅服务启动,周期:{self._cron}") try: - self._scheduler.add_job(self.__refresh_rss, - CronTrigger.from_crontab(self._cron)) + self._scheduler.add_job(func=self.__refresh_rss, + trigger=CronTrigger.from_crontab(self._cron), + name="豆瓣榜单订阅") except Exception as e: logger.error(f"豆瓣榜单订阅服务启动失败,错误信息:{str(e)}") self.systemmessage.put(f"豆瓣榜单订阅服务启动失败,错误信息:{str(e)}") else: - self._scheduler.add_job(self.__refresh_rss, CronTrigger.from_crontab("0 8 * * *")) + self._scheduler.add_job(func=self.__refresh_rss, + trigger=CronTrigger.from_crontab("0 8 * * *"), + name="豆瓣榜单订阅") logger.info("豆瓣榜单订阅服务启动,周期:每天 08:00") if self._scheduler.get_jobs(): diff --git a/app/plugins/libraryscraper/__init__.py b/app/plugins/libraryscraper/__init__.py index ef3ae102..3efe8e7a 100644 --- a/app/plugins/libraryscraper/__init__.py +++ b/app/plugins/libraryscraper/__init__.py @@ -66,15 +66,17 @@ class LibraryScraper(_PluginBase): if self._cron: logger.info(f"媒体库刮削服务启动,周期:{self._cron}") try: - self._scheduler.add_job(self.__libraryscraper, - CronTrigger.from_crontab(self._cron)) + self._scheduler.add_job(func=self.__libraryscraper, + trigger=CronTrigger.from_crontab(self._cron), + name="媒体库刮削") except Exception as e: logger.error(f"媒体库刮削服务启动失败,原因:{e}") self.systemmessage.put(f"媒体库刮削服务启动失败,原因:{e}") else: logger.info(f"媒体库刮削服务启动,周期:每7天") - self._scheduler.add_job(self.__libraryscraper, - CronTrigger.from_crontab("0 0 */7 * *")) + self._scheduler.add_job(func=self.__libraryscraper, + trigger=CronTrigger.from_crontab("0 0 */7 * *"), + name="媒体库刮削") if self._scheduler.get_jobs(): # 启动服务 self._scheduler.print_jobs() diff --git a/app/plugins/speedlimiter/__init__.py b/app/plugins/speedlimiter/__init__.py index 5a85045b..8da88fd9 100644 --- a/app/plugins/speedlimiter/__init__.py +++ b/app/plugins/speedlimiter/__init__.py @@ -4,6 +4,8 @@ from apscheduler.schedulers.background import BackgroundScheduler from app.core.config import settings from app.log import logger +from app.modules.qbittorrent import Qbittorrent +from app.modules.transmission import Transmission from app.plugins import _PluginBase @@ -31,22 +33,32 @@ class SpeedLimiter(_PluginBase): # 私有属性 _scheduler = None + _qb = None + _tr = None _enabled: bool = False _notify: bool = False - _bandwidth: int = 0 _interval: int = 60 + _downloader: list = [] + _play_up_speed: float = 0 + _play_down_speed: float = 0 + _noplay_up_speed: float = 0 + _noplay_down_speed: float = 0 def init_plugin(self, config: dict = None): # 读取配置 if config: self._enabled = config.get("enabled") self._notify = config.get("notify") - try: - # 总带宽 - self._bandwidth = int(float(config.get("bandwidth") or 0)) * 1000000 - except Exception as e: - logger.error(f"总带宽配置错误:{e}") - self._bandwidth = 0 + self._play_up_speed = float(config.get("play_up_speed")) if config.get("play_up_speed") else 0 + self._play_down_speed = float(config.get("play_down_speed")) if config.get("play_down_speed") else 0 + self._noplay_up_speed = float(config.get("noplay_up_speed")) if config.get("noplay_up_speed") else 0 + self._noplay_down_speed = float(config.get("noplay_down_speed")) if config.get("noplay_down_speed") else 0 + self._downloader = config.get("downloader") or [] + if self._downloader: + if 'qbittorrent' in self._downloader: + self._qb = Qbittorrent() + if 'transmission' in self._downloader: + self._tr = Transmission() # 移出现有任务 self.stop_service() @@ -56,10 +68,11 @@ class SpeedLimiter(_PluginBase): self._scheduler = BackgroundScheduler(timezone=settings.TZ) self._scheduler.add_job(func=self.__check_playing_sessions, trigger='interval', - seconds=self._interval) + seconds=self._interval, + name="播放限速检查") self._scheduler.print_jobs() self._scheduler.start() - logger.info("播放限速服务启动") + logger.info("播放限速检查服务启动") def get_state(self) -> bool: return self._enabled @@ -72,7 +85,159 @@ class SpeedLimiter(_PluginBase): pass def get_form(self) -> Tuple[List[dict], Dict[str, Any]]: - pass + return [ + { + 'component': 'VForm', + 'content': [ + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'enabled', + 'label': '启用插件', + } + } + ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'notify', + 'label': '发送通知', + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'chips': True, + 'multiple': True, + 'model': 'sign_sites', + 'label': '下载器', + 'items': [ + {'title': 'Qbittorrent', 'value': 'qbittorrent'}, + {'title': 'Transmission', 'value': 'transmission'}, + ] + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'play_up_speed', + 'label': '播放限速(上传)', + 'placeholder': 'KB/s' + } + } + ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'play_down_speed', + 'label': '播放限速(下载)', + 'placeholder': 'KB/s' + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'noplay_up_speed', + 'label': '未播放限速(上传)', + 'placeholder': 'KB/s' + } + } + ] + }, + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'noplay_down_speed', + 'label': '未播放限速(下载)', + 'placeholder': 'KB/s' + } + } + ] + } + ] + } + ] + } + ], { + "enabled": False, + "notify": True, + "downloader": [], + "play_up_speed": 0, + "play_down_speed": 0, + "noplay_up_speed": 0, + "noplay_down_speed": 0, + } def get_page(self) -> List[dict]: pass @@ -81,6 +246,13 @@ class SpeedLimiter(_PluginBase): """ 检查播放会话 """ + if not self._qb and not self._tr: + return + + def __set_limiter(self): + """ + 设置限速 + """ pass def stop_service(self):