From 741badf9e660268d4cb9e9ddbab4b9650e7ee9d6 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Thu, 1 May 2025 21:16:21 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E6=94=AF=E6=8C=81=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E6=95=B4=E7=90=86=E5=AD=98=E5=82=A8=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/api/endpoints/media.py | 2 +- app/chain/storage.py | 9 +++++++++ app/chain/transfer.py | 34 ++++++++++++++++++++++++++++++++-- app/schemas/event.py | 20 +++++++++++++++++++- app/schemas/types.py | 2 ++ 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/app/api/endpoints/media.py b/app/api/endpoints/media.py index a96d35dc..83c4eab1 100644 --- a/app/api/endpoints/media.py +++ b/app/api/endpoints/media.py @@ -198,7 +198,7 @@ def seasons(mediaid: Optional[str] = None, @router.get("/{mediaid}", summary="查询媒体详情", response_model=schemas.MediaInfo) -def detail(mediaid: str, type_name: str, title: Optional[str] = None, year: int = None, +def detail(mediaid: str, type_name: str, title: Optional[str] = None, year: str = None, _: schemas.TokenPayload = Depends(verify_token)) -> Any: """ 根据媒体ID查询themoviedb或豆瓣媒体信息,type_name: 电影/电视剧 diff --git a/app/chain/storage.py b/app/chain/storage.py index 24a39bc3..5719cf23 100644 --- a/app/chain/storage.py +++ b/app/chain/storage.py @@ -7,6 +7,7 @@ from app.core.config import settings from app.helper.directory import DirectoryHelper from app.log import logger from app.schemas import MediaType +from helper.storage import StorageHelper class StorageChain(ChainBase): @@ -17,6 +18,7 @@ class StorageChain(ChainBase): def __init__(self): super().__init__() self.directoryhelper = DirectoryHelper() + self.storagehelper = StorageHelper() def save_config(self, storage: str, conf: dict) -> None: """ @@ -181,3 +183,10 @@ class StorageChain(ChainBase): return self.delete_file(dir_item) return True + + def get_storage(self, storage: str) -> Optional[schemas.StorageConf]: + """ + 获取存储对象 + """ + return self.storagehelper.get_storage(storage=storage) + diff --git a/app/chain/transfer.py b/app/chain/transfer.py index 09cc1dc4..9fdfb974 100644 --- a/app/chain/transfer.py +++ b/app/chain/transfer.py @@ -29,9 +29,11 @@ from app.log import logger from app.schemas import TransferInfo, TransferTorrent, Notification, EpisodeFormat, FileItem, TransferDirectoryConf, \ TransferTask, TransferQueue, TransferJob, TransferJobTask from app.schemas.types import TorrentStatus, EventType, MediaType, ProgressKey, NotificationType, MessageChannel, \ - SystemConfigKey + SystemConfigKey, ChainEventType from app.utils.singleton import Singleton from app.utils.string import StringUtils +from core.event import eventmanager +from schemas import StorageOperSelectionEventData downloader_lock = threading.Lock() job_lock = threading.Lock() @@ -703,6 +705,32 @@ class TransferChain(ChainBase, metaclass=Singleton): # 正在处理 self.jobview.running_task(task) + # 广播事件,请示额外的源存储支持 + source_oper = None + source_storage = self.storagechain.get_storage(task.fileitem.storage) + source_event_data = StorageOperSelectionEventData( + storage_name=source_storage.name, + ) + source_event = eventmanager.send_event(ChainEventType.StorageOperSelection, source_event_data) + # 使用事件返回的上下文数据 + if source_event and source_event.event_data: + source_event_data: StorageOperSelectionEventData = source_event.event_data + if source_event_data.storage_oper: + source_oper = source_event_data.storage_oper + + # 广播事件,请示额外的目标存储支持 + target_oper = None + target_storage = self.storagechain.get_storage(task.target_storage) + target_event_data = StorageOperSelectionEventData( + storage_name=target_storage.name, + ) + target_event = eventmanager.send_event(ChainEventType.StorageOperSelection, target_event_data) + # 使用事件返回的上下文数据 + if target_event and target_event.event_data: + target_event_data: StorageOperSelectionEventData = target_event.event_data + if target_event_data.storage_oper: + target_oper = target_event_data.storage_oper + # 执行整理 transferinfo: TransferInfo = self.transfer(fileitem=task.fileitem, meta=task.meta, @@ -714,7 +742,9 @@ class TransferChain(ChainBase, metaclass=Singleton): episodes_info=task.episodes_info, scrape=task.scrape, library_type_folder=task.library_type_folder, - library_category_folder=task.library_category_folder) + library_category_folder=task.library_category_folder, + source_oper=source_oper, + target_oper=target_oper) if not transferinfo: logger.error("文件整理模块运行失败") return False, "文件整理模块运行失败" diff --git a/app/schemas/event.py b/app/schemas/event.py index 00ee18f2..8ee1f181 100644 --- a/app/schemas/event.py +++ b/app/schemas/event.py @@ -1,5 +1,5 @@ from pathlib import Path -from typing import Optional, Dict, Any, List, Set +from typing import Optional, Dict, Any, List, Set, Callable from pydantic import BaseModel, Field, root_validator @@ -307,3 +307,21 @@ class MediaRecognizeConvertEventData(ChainEventData): # 输出参数 media_dict: dict = Field(default=dict, description="转换后的媒体信息(TheMovieDb/豆瓣)") + + +class StorageOperSelectionEventData(ChainEventData): + """ + StorageOperSelect 事件的数据模型 + + Attributes: + # 输入参数 + storage_name (str): 存储名称 + + # 输出参数 + storage_oper (Callable): 存储操作对象 + """ + # 输入参数 + storage_name: str = Field(..., description="存储名称") + + # 输出参数 + storage_oper: Optional[Callable] = Field(default=None, description="存储操作对象") diff --git a/app/schemas/types.py b/app/schemas/types.py index 3355f8e9..c159613a 100644 --- a/app/schemas/types.py +++ b/app/schemas/types.py @@ -89,6 +89,8 @@ class ChainEventType(Enum): RecommendSource = "recommend.source" # 工作流执行 WorkflowExecution = "workflow.execution" + # 存储操作选择 + StorageOperSelection = "storage.operation" # 系统配置Key字典