From cf62ad5e8e58abab4ba73d5167b6161f7ad30e05 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Fri, 28 Feb 2025 11:15:24 +0800 Subject: [PATCH] fix actions --- app/actions/__init__.py | 23 +++--- app/actions/add_download.py | 9 ++- app/actions/add_subscribe.py | 29 ++++--- app/actions/fetch_downloads.py | 19 ++--- app/actions/fetch_medias.py | 136 ++++++++++++++++++--------------- app/actions/fetch_rss.py | 9 ++- app/actions/fetch_torrents.py | 9 ++- app/actions/filter_medias.py | 9 ++- app/actions/filter_torrents.py | 9 ++- app/actions/scrape_file.py | 9 ++- app/actions/send_event.py | 9 ++- app/actions/send_message.py | 9 ++- app/actions/transfer_file.py | 9 ++- app/core/workflow.py | 17 ++--- 14 files changed, 174 insertions(+), 131 deletions(-) diff --git a/app/actions/__init__.py b/app/actions/__init__.py index a28aab55..eefebb0b 100644 --- a/app/actions/__init__.py +++ b/app/actions/__init__.py @@ -16,28 +16,24 @@ class BaseAction(ABC): # 完成标志 _done_flag = False + @classmethod @property @abstractmethod - def name(self) -> str: + def name(cls) -> str: pass + @classmethod @property @abstractmethod - def description(self) -> str: + def description(cls) -> str: pass + @classmethod @property @abstractmethod - def data(self) -> dict: + def data(cls) -> dict: pass - @abstractmethod - def execute(self, params: ActionParams, context: ActionContext) -> ActionContext: - """ - 执行动作 - """ - raise NotImplementedError - @property def done(self) -> bool: """ @@ -58,3 +54,10 @@ class BaseAction(ABC): 标记动作完成 """ self._done_flag = True + + @abstractmethod + def execute(self, params: ActionParams, context: ActionContext) -> ActionContext: + """ + 执行动作 + """ + raise NotImplementedError diff --git a/app/actions/add_download.py b/app/actions/add_download.py index e1e14413..000af4e7 100644 --- a/app/actions/add_download.py +++ b/app/actions/add_download.py @@ -29,16 +29,19 @@ class AddDownloadAction(BaseAction): self.downloadchain = DownloadChain() self.mediachain = MediaChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "添加下载" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "根据资源列表添加下载任务" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return AddDownloadParams().dict() @property diff --git a/app/actions/add_subscribe.py b/app/actions/add_subscribe.py index c9f6736f..d8a906b2 100644 --- a/app/actions/add_subscribe.py +++ b/app/actions/add_subscribe.py @@ -1,6 +1,7 @@ from app.actions import BaseAction from app.chain.subscribe import SubscribeChain from app.core.config import settings +from app.core.context import MediaInfo from app.db.subscribe_oper import SubscribeOper from app.log import logger from app.schemas import ActionParams, ActionContext @@ -25,16 +26,19 @@ class AddSubscribeAction(BaseAction): self.subscribechain = SubscribeChain() self.subscribeoper = SubscribeOper() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "添加订阅" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "根据媒体列表添加订阅" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return AddSubscribeParams().dict() @property @@ -46,18 +50,19 @@ class AddSubscribeAction(BaseAction): 将medias中的信息添加订阅,如果订阅不存在的话 """ for media in context.medias: - if self.subscribechain.exists(media): + mediainfo = MediaInfo() + mediainfo.from_dict(media.dict()) + if self.subscribechain.exists(mediainfo): logger.info(f"{media.title} 已存在订阅") continue # 添加订阅 - sid, message = self.subscribechain.add(mtype=media.type, - title=media.title, - year=media.year, - tmdbid=media.tmdb_id, - season=media.season, - doubanid=media.douban_id, - bangumiid=media.bangumi_id, - mediaid=media.media_id, + sid, message = self.subscribechain.add(mtype=mediainfo.type, + title=mediainfo.title, + year=mediainfo.year, + tmdbid=mediainfo.tmdb_id, + season=mediainfo.season, + doubanid=mediainfo.douban_id, + bangumiid=mediainfo.bangumi_id, username=settings.SUPERUSER) if sid: self._added_subscribes.append(sid) diff --git a/app/actions/fetch_downloads.py b/app/actions/fetch_downloads.py index 77e6d40d..fb7fbb15 100644 --- a/app/actions/fetch_downloads.py +++ b/app/actions/fetch_downloads.py @@ -21,29 +21,30 @@ class FetchDownloadsAction(BaseAction): super().__init__() self.chain = ActionChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "获取下载任务" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "获取下载任务,更新任务状态" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FetchDownloadsParams().dict() @property def success(self) -> bool: - if not self._downloads: - return True - return True if all([d.completed for d in self._downloads]) else False + return self.done def execute(self, params: dict, context: ActionContext) -> ActionContext: """ 更新downloads中的下载任务状态 """ - self._downloads = context.downloads + __all_complete = False for download in self._downloads: logger.info(f"获取下载任务 {download.download_id} 状态 ...") torrents = self.chain.list_torrents(hashs=[download.download_id]) @@ -55,6 +56,6 @@ class FetchDownloadsAction(BaseAction): if t.progress >= 100: logger.info(f"下载任务 {download.download_id} 已完成") download.completed = True - - self.job_done() + if all([d.completed for d in self._downloads]): + self.job_done() return context diff --git a/app/actions/fetch_medias.py b/app/actions/fetch_medias.py index 082be386..bee0a94e 100644 --- a/app/actions/fetch_medias.py +++ b/app/actions/fetch_medias.py @@ -3,6 +3,7 @@ from typing import List from pydantic import Field from app.actions import BaseAction +from app.chain.recommend import RecommendChain from app.schemas import ActionParams, ActionContext from app.core.config import settings from app.core.event import eventmanager @@ -24,65 +25,68 @@ class FetchMediasAction(BaseAction): 获取媒体数据 """ - __inner_sources = [ - { - "api_path": 'recommend/tmdb_trending', - "name": '流行趋势', - }, - { - "api_path": 'recommend/douban_showing', - "name": '正在热映', - }, - { - "api_path": 'bangumi/calendar', - "name": 'Bangumi每日放送', - }, - { - "api_path": 'recommend/tmdb_movies', - "name": 'TMDB热门电影', - }, - { - "api_path": 'recommend/tmdb_tvs?with_original_language=zh|en|ja|ko', - "name": 'TMDB热门电视剧', - }, - { - "api_path": 'recommend/douban_movie_hot', - "name": '豆瓣热门电影', - }, - { - "api_path": 'recommend/douban_tv_hot', - "name": '豆瓣热门电视剧', - }, - { - "api_path": 'recommend/douban_tv_animation', - "name": '豆瓣热门动漫', - }, - { - "api_path": 'recommend/douban_movies', - "name": '豆瓣最新电影', - }, - { - "api_path": 'recommend/douban_tvs', - "name": '豆瓣最新电视剧', - }, - { - "api_path": 'recommend/douban_movie_top250', - "name": '豆瓣电影TOP250', - }, - { - "api_path": 'recommend/douban_tv_weekly_chinese', - "name": '豆瓣国产剧集榜', - }, - { - "api_path": 'recommend/douban_tv_weekly_global', - "name": '豆瓣全球剧集榜', - } - ] + __inner_sources = [] __medias = [] def __init__(self): super().__init__() + + self.__inner_sources = [ + { + "func": RecommendChain().tmdb_trending, + "name": '流行趋势', + }, + { + "func": RecommendChain().douban_movie_showing, + "name": '正在热映', + }, + { + "func": RecommendChain().bangumi_calendar, + "name": 'Bangumi每日放送', + }, + { + "func": RecommendChain().tmdb_movies, + "name": 'TMDB热门电影', + }, + { + "func": RecommendChain().tmdb_tvs, + "name": 'TMDB热门电视剧', + }, + { + "func": RecommendChain().douban_movie_hot, + "name": '豆瓣热门电影', + }, + { + "func": RecommendChain().douban_tv_hot, + "name": '豆瓣热门电视剧', + }, + { + "func": RecommendChain().douban_tv_animation, + "name": '豆瓣热门动漫', + }, + { + "func": RecommendChain().douban_movies, + "name": '豆瓣最新电影', + }, + { + "func": RecommendChain().douban_tvs, + "name": '豆瓣最新电视剧', + }, + { + "func": RecommendChain().douban_movie_top250, + "name": '豆瓣电影TOP250', + }, + { + "func": RecommendChain().douban_tv_weekly_chinese, + "name": '豆瓣国产剧集榜', + }, + { + "func": RecommendChain().douban_tv_weekly_global, + "name": '豆瓣全球剧集榜', + } + ] + # 广播事件,请示额外的推荐数据源支持 event_data = RecommendSourceEventData() event = eventmanager.send_event(ChainEventType.RecommendSource, event_data) @@ -92,16 +96,19 @@ class FetchMediasAction(BaseAction): if event_data.extra_sources: self.__inner_sources.extend([s.dict() for s in event_data.extra_sources]) + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "获取媒体数据" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "获取榜单等媒体数据列表" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FetchMediasParams().dict() @property @@ -127,11 +134,16 @@ class FetchMediasAction(BaseAction): if not source: continue logger.info(f"获取媒体数据 {source} ...") - # 调用内部API获取数据 - api_url = f"http://127.0.0.1:{settings.PORT}/api/v1/{source['api_path']}?token={settings.API_TOKEN}" - res = RequestUtils(timeout=15).post_res(api_url) - if res: - results = res.json() + results = [] + if source.get("func"): + results = source['func']() + else: + # 调用内部API获取数据 + api_url = f"http://127.0.0.1:{settings.PORT}/api/v1/{source['api_path']}?token={settings.API_TOKEN}" + res = RequestUtils(timeout=15).post_res(api_url) + if res: + results = res.json() + if results: logger.info(f"{name} 获取到 {len(results)} 条数据") self.__medias.extend([MediaInfo(**r) for r in results]) else: diff --git a/app/actions/fetch_rss.py b/app/actions/fetch_rss.py index 681a4604..32268309 100644 --- a/app/actions/fetch_rss.py +++ b/app/actions/fetch_rss.py @@ -35,16 +35,19 @@ class FetchRssAction(BaseAction): self.rsshelper = RssHelper() self.chain = ActionChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "获取RSS资源" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "订阅RSS地址获取资源" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FetchRssParams().dict() @property diff --git a/app/actions/fetch_torrents.py b/app/actions/fetch_torrents.py index 6b786261..36f5bfba 100644 --- a/app/actions/fetch_torrents.py +++ b/app/actions/fetch_torrents.py @@ -30,16 +30,19 @@ class FetchTorrentsAction(BaseAction): super().__init__() self.searchchain = SearchChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "搜索站点资源" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "根据关键字搜索站点种子资源" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FetchTorrentsParams().dict() @property diff --git a/app/actions/filter_medias.py b/app/actions/filter_medias.py index 66d0338c..d991a588 100644 --- a/app/actions/filter_medias.py +++ b/app/actions/filter_medias.py @@ -24,16 +24,19 @@ class FilterMediasAction(BaseAction): __medias = [] + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "过滤媒体数据" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "对媒体数据列表进行过滤" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FilterMediasParams().dict() @property diff --git a/app/actions/filter_torrents.py b/app/actions/filter_torrents.py index 910e73c5..ce96771a 100644 --- a/app/actions/filter_torrents.py +++ b/app/actions/filter_torrents.py @@ -32,16 +32,19 @@ class FilterTorrentsAction(BaseAction): self.torrenthelper = TorrentHelper() self.chain = ActionChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "过滤资源" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "对资源列表数据进行过滤" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return FilterTorrentsParams().dict() @property diff --git a/app/actions/scrape_file.py b/app/actions/scrape_file.py index 65f4f221..cb3a0d52 100644 --- a/app/actions/scrape_file.py +++ b/app/actions/scrape_file.py @@ -27,16 +27,19 @@ class ScrapeFileAction(BaseAction): self.storagechain = StorageChain() self.mediachain = MediaChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "刮削文件" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "刮削媒体信息和图片" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return ScrapeFileParams().dict() @property diff --git a/app/actions/send_event.py b/app/actions/send_event.py index 4eb3adca..376d5405 100644 --- a/app/actions/send_event.py +++ b/app/actions/send_event.py @@ -17,16 +17,19 @@ class SendEventAction(BaseAction): 发送事件 """ + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "发送事件" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "发送队列中的所有事件" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return SendEventParams().dict() @property diff --git a/app/actions/send_message.py b/app/actions/send_message.py index 50f2d91e..1d706a51 100644 --- a/app/actions/send_message.py +++ b/app/actions/send_message.py @@ -24,16 +24,19 @@ class SendMessageAction(BaseAction): super().__init__() self.chain = ActionChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "发送消息" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "发送队列中的所有消息" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return SendMessageParams().dict() @property diff --git a/app/actions/transfer_file.py b/app/actions/transfer_file.py index d302fe26..04d9f980 100644 --- a/app/actions/transfer_file.py +++ b/app/actions/transfer_file.py @@ -26,16 +26,19 @@ class TransferFileAction(BaseAction): self.transferchain = TransferChain() self.storagechain = StorageChain() + @classmethod @property - def name(self) -> str: + def name(cls) -> str: return "整理文件" + @classmethod @property - def description(self) -> str: + def description(cls) -> str: return "整理下载队列中的文件" + @classmethod @property - def data(self) -> dict: + def data(cls) -> dict: return TransferFileParams().dict() @property diff --git a/app/core/workflow.py b/app/core/workflow.py index 080ffa94..8bdb86ce 100644 --- a/app/core/workflow.py +++ b/app/core/workflow.py @@ -44,7 +44,7 @@ class WorkFlowManager(metaclass=Singleton): for action in actions: logger.debug(f"加载动作: {action.__name__}") try: - self._actions[action.__name__] = action() + self._actions[action.__name__] = action except Exception as err: logger.error(f"加载动作失败: {action.__name__} - {err}") @@ -62,7 +62,7 @@ class WorkFlowManager(metaclass=Singleton): context = ActionContext() if action.type in self._actions: # 实例化 - action_obj = self._actions[action.type] + action_obj = self._actions[action.type]() # 执行 logger.info(f"执行动作: {action.id} - {action.name}") try: @@ -70,10 +70,6 @@ class WorkFlowManager(metaclass=Singleton): except Exception as err: logger.error(f"{action.name} 执行失败: {err}") return False, context - if action_obj.success: - logger.info(f"{action.name} 执行成功") - else: - logger.error(f"{action.name} 执行失败") loop = action.data.get("loop") loop_interval = action.data.get("loop_interval") if loop and loop_interval: @@ -84,11 +80,10 @@ class WorkFlowManager(metaclass=Singleton): # 执行 logger.info(f"继续执行动作: {action.id} - {action.name}") result_context = action_obj.execute(action.data, result_context) - if action_obj.success: - logger.info(f"{action.name} 执行成功") - else: - logger.error(f"{action.name} 执行失败") - logger.info(f"{action.name} 执行完成") + if action_obj.success: + logger.info(f"{action.name} 执行成功") + else: + logger.error(f"{action.name} 执行失败!") return action_obj.success, result_context else: logger.error(f"未找到动作: {action.type} - {action.name}")