mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-03-20 12:08:09 +08:00
support path_mapping for downloader
This commit is contained in:
@@ -707,19 +707,17 @@ class ChainBase(metaclass=ABCMeta):
|
||||
cookie=cookie, episodes=episodes, category=category, label=label,
|
||||
downloader=downloader)
|
||||
|
||||
def download_added(self, context: Context, download_dir: Path, storage: str, torrent_content: Union[str, bytes] = None) -> None:
|
||||
def download_added(self, context: Context, download_dir: Path, torrent_content: Union[str, bytes] = None) -> None:
|
||||
"""
|
||||
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
||||
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
||||
:param download_dir: 下载目录
|
||||
:param storage: 存储类型
|
||||
:param torrent_content: 种子内容,如果有则直接使用该内容,否则从context中获取种子文件路径
|
||||
:return: None,该方法可被多个模块同时处理
|
||||
"""
|
||||
return self.run_module("download_added", context=context,
|
||||
torrent_content=torrent_content,
|
||||
download_dir=download_dir,
|
||||
storage=storage)
|
||||
download_dir=download_dir)
|
||||
|
||||
def list_torrents(self, status: TorrentStatus = None,
|
||||
hashs: Union[list, str] = None,
|
||||
|
||||
@@ -19,7 +19,7 @@ from app.db.mediaserver_oper import MediaServerOper
|
||||
from app.helper.directory import DirectoryHelper
|
||||
from app.helper.torrent import TorrentHelper
|
||||
from app.log import logger
|
||||
from app.schemas import ExistMediaInfo, NotExistMediaInfo, DownloadingTorrent, Notification, ResourceSelectionEventData, \
|
||||
from app.schemas import ExistMediaInfo, FileURI, NotExistMediaInfo, DownloadingTorrent, Notification, ResourceSelectionEventData, \
|
||||
ResourceDownloadEventData
|
||||
from app.schemas.types import MediaType, TorrentStatus, EventType, MessageChannel, NotificationType, ContentType, \
|
||||
ChainEventType
|
||||
@@ -235,10 +235,7 @@ class DownloadChain(ChainBase):
|
||||
storage = 'local'
|
||||
# 下载目录
|
||||
if save_path:
|
||||
uri = schemas.FileURI.from_uri(save_path)
|
||||
# 下载目录使用自定义的
|
||||
download_dir = Path(uri.path)
|
||||
storage = uri.storage
|
||||
download_dir = Path(save_path)
|
||||
else:
|
||||
# 根据媒体信息查询下载目录配置
|
||||
dir_info = DirectoryHelper().get_dir(_media, include_unsorted=True)
|
||||
@@ -263,6 +260,8 @@ class DownloadChain(ChainBase):
|
||||
self.messagehelper.put(f"{_media.type.value} {_media.title_year} 未找到下载目录!",
|
||||
title="下载失败", role="system")
|
||||
return None
|
||||
fileURI = FileURI(storage=storage, path=download_dir.as_posix())
|
||||
download_dir = Path(fileURI.uri)
|
||||
|
||||
# 添加下载
|
||||
result: Optional[tuple] = self.download(content=torrent_content,
|
||||
@@ -362,7 +361,7 @@ class DownloadChain(ChainBase):
|
||||
username=username,
|
||||
)
|
||||
# 下载成功后处理
|
||||
self.download_added(context=context, download_dir=download_dir, storage=storage, torrent_content=torrent_content)
|
||||
self.download_added(context=context, download_dir=download_dir, torrent_content=torrent_content)
|
||||
# 广播事件
|
||||
self.eventmanager.send_event(EventType.DownloadAdded, {
|
||||
"hash": _hash,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from abc import abstractmethod, ABCMeta
|
||||
from typing import Generic, Tuple, Union, TypeVar, Type, Dict, Optional, Callable
|
||||
from pathlib import Path
|
||||
|
||||
from app.helper.service import ServiceConfigHelper
|
||||
from app.schemas import Notification, NotificationConf, MediaServerConf, DownloaderConf
|
||||
@@ -290,6 +291,30 @@ class _DownloaderBase(ServiceBase[TService, DownloaderConf]):
|
||||
重置默认配置名称
|
||||
"""
|
||||
self._default_config_name = None
|
||||
|
||||
def normalize_path(self, path: Path, downloader: Optional[str]) -> str:
|
||||
"""
|
||||
根据下载器配置和路径映射,规范化下载路径
|
||||
|
||||
:param path: 原始路径
|
||||
:param conf: 下载器配置
|
||||
:return: 规范化后的路径
|
||||
"""
|
||||
dir = path.as_posix()
|
||||
conf = self.get_config(downloader)
|
||||
if conf and conf.path_mapping:
|
||||
for (src, dst) in conf.path_mapping:
|
||||
src = Path(src.strip()).as_posix()
|
||||
dst = Path(dst.strip()).as_posix()
|
||||
if dir.startswith(src):
|
||||
dir = dir.replace(src, dst, 1)
|
||||
break
|
||||
# 处理存储协议前缀
|
||||
for s in StorageSchema:
|
||||
prefix = f"{s.value}:"
|
||||
if dir.startswith(prefix):
|
||||
return dir[len(prefix):]
|
||||
return dir
|
||||
|
||||
|
||||
class _MediaServerBase(ServiceBase[TService, MediaServerConf]):
|
||||
|
||||
@@ -150,7 +150,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
|
||||
# 添加任务
|
||||
state = server.add_torrent(
|
||||
content=content,
|
||||
download_dir=download_dir.as_posix(),
|
||||
download_dir=self.normalize_path(download_dir, downloader),
|
||||
is_paused=is_paused,
|
||||
tag=tags,
|
||||
cookie=cookie,
|
||||
|
||||
@@ -11,7 +11,7 @@ from app.core.context import Context
|
||||
from app.helper.torrent import TorrentHelper
|
||||
from app.log import logger
|
||||
from app.modules import _ModuleBase
|
||||
from app.schemas.file import FileItem
|
||||
from app.schemas.file import FileURI
|
||||
from app.schemas.types import ModuleType, OtherModulesType
|
||||
from app.utils.http import RequestUtils
|
||||
from app.utils.string import StringUtils
|
||||
@@ -65,12 +65,11 @@ class SubtitleModule(_ModuleBase):
|
||||
def test(self):
|
||||
pass
|
||||
|
||||
def download_added(self, context: Context, download_dir: Path, storage: str, torrent_content: Union[str, bytes] = None):
|
||||
def download_added(self, context: Context, download_dir: Path, torrent_content: Union[str, bytes] = None):
|
||||
"""
|
||||
添加下载任务成功后,从站点下载字幕,保存到下载目录
|
||||
:param context: 上下文,包括识别信息、媒体信息、种子信息
|
||||
:param download_dir: 下载目录
|
||||
:param storage: 存储类型
|
||||
:param torrent_content: 种子内容,如果是种子文件,则为文件内容,否则为种子字符串
|
||||
:return: None,该方法可被多个模块同时处理
|
||||
"""
|
||||
@@ -93,6 +92,10 @@ class SubtitleModule(_ModuleBase):
|
||||
storageChain = StorageChain()
|
||||
# 等待目录存在
|
||||
working_dir_item = None
|
||||
# split download_dir into storage and path
|
||||
fileURI = FileURI.from_uri(download_dir.as_posix())
|
||||
storage = fileURI.storage
|
||||
download_dir = Path(fileURI.path)
|
||||
for _ in range(30):
|
||||
found = storageChain.get_file_item(storage, download_dir / folder_name)
|
||||
if found:
|
||||
|
||||
@@ -151,7 +151,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
|
||||
# 添加任务
|
||||
torrent = server.add_torrent(
|
||||
content=content,
|
||||
download_dir=download_dir.as_posix(),
|
||||
download_dir=self.normalize_path(download_dir, downloader),
|
||||
is_paused=is_paused,
|
||||
labels=labels,
|
||||
cookie=cookie
|
||||
|
||||
@@ -51,6 +51,8 @@ class DownloaderConf(BaseModel):
|
||||
config: Optional[dict] = Field(default_factory=dict)
|
||||
# 是否启用
|
||||
enabled: Optional[bool] = False
|
||||
# 路径映射
|
||||
path_mapping: Optional[list[tuple[str, str]]] = Field(default_factory=list)
|
||||
|
||||
|
||||
class NotificationConf(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user