refactor(downloader): 新增支持种子文件布局处理

- 在 `DownloadChain` 中根据`种子文件布局`拼接`savepath`
- 在 `QbittorrentModule` 和 `TransmissionModule` 中添加种子文件布局信息
- 修改 `download` 方法的返回值,增加种子文件布局参数
This commit is contained in:
Attente
2024-12-21 04:50:10 +08:00
parent 03a0bc907b
commit 9756bf6ac8
4 changed files with 56 additions and 31 deletions

View File

@@ -342,7 +342,7 @@ class ChainBase(metaclass=ABCMeta):
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
episodes: Set[int] = None, category: str = None,
downloader: str = None
) -> Optional[Tuple[Optional[str], Optional[str], str]]:
) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]:
"""
根据种子文件,选择并添加下载任务
:param content: 种子文件地址或者磁力链接
@@ -351,7 +351,7 @@ class ChainBase(metaclass=ABCMeta):
:param episodes: 需要下载的集数
:param category: 种子分类
:param downloader: 下载器
:return: 下载器名称、种子Hash、错误信息
:return: 下载器名称、种子Hash、种子文件布局、错误原因
"""
return self.run_module("download", content=content, download_dir=download_dir,
cookie=cookie, episodes=episodes, category=category,

View File

@@ -313,16 +313,21 @@ class DownloadChain(ChainBase):
category=_media.category,
downloader=downloader or _site_downloader)
if result:
_downloader, _hash, error_msg = result
_downloader, _hash, _layout, error_msg = result
else:
_downloader, _hash, error_msg = None, None, "未找到下载器"
_downloader, _hash, _layout, error_msg = None, None, None, "未找到下载器"
if _hash:
# 下载文件路径
if _folder_name:
if _layout == "NoSubfolder" or not _folder_name:
# `不创建子文件夹` 或 `不存在子文件夹` 则记录至文件
download_path = download_dir / _file_list[0] if _file_list else download_dir
elif _folder_name:
# 原始布局
download_path = download_dir / _folder_name
else:
download_path = download_dir / _file_list[0] if _file_list else download_dir
# 创建子文件夹
download_path = download_dir / Path(_file_list[0]).stem if _file_list else download_dir
# 登记下载记录
self.downloadhis.add(
@@ -362,11 +367,23 @@ class DownloadChain(ChainBase):
if not Path(file).suffix \
or Path(file).suffix.lower() not in settings.RMT_MEDIAEXT:
continue
# savepath 包含子文件夹, 不含文件
if _layout == "NoSubfolder" or not _folder_name:
# `不创建子文件夹` 或 `不存在子文件夹` 则记录至文件
_save_path = download_dir
elif _folder_name:
# 原始布局
_save_path = download_dir / _folder_name
else:
# 创建子文件夹
_save_path = download_dir / Path(_file_list[0]).stem if _file_list else download_dir
files_to_add.append({
"download_hash": _hash,
"downloader": _downloader,
"fullpath": str(download_dir / _folder_name / file),
"savepath": str(download_dir / _folder_name),
"fullpath": str(_save_path / file),
"savepath": str(_save_path),
"filepath": file,
"torrentname": _meta.org_string,
})

View File

@@ -79,7 +79,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
episodes: Set[int] = None, category: str = None,
downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], str]]:
downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]:
"""
根据种子文件,选择并添加下载任务
:param content: 种子文件地址或者磁力链接
@@ -88,7 +88,7 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
:param episodes: 需要下载的集数
:param category: 分类
:param downloader: 下载器
:return: 种子Hash错误信息
:return: 下载器名称、种子Hash、种子文件布局、错误原因
"""
def __get_torrent_info() -> Tuple[str, int]:
@@ -106,10 +106,10 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
return "", 0
if not content:
return None, None, "下载内容为空"
return None, None, None, "下载内容为空"
if isinstance(content, Path) and not content.exists():
logger.error(f"种子文件不存在:{content}")
return None, None, f"种子文件不存在:{content}"
return None, None, None, f"种子文件不存在:{content}"
# 获取下载器
server: Qbittorrent = self.get_instance(downloader)
@@ -134,15 +134,20 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
category=category,
ignore_category_check=False
)
# 获取下载器全局设置
application = server.qbc.application.preferences
# 获取种子内容布局: `Original: 原始, Subfolder: 创建子文件夹, NoSubfolder: 不创建子文件夹`
torrent_layout = application.get("torrent_content_layout", "Original")
if not state:
# 读取种子的名称
torrent_name, torrent_size = __get_torrent_info()
if not torrent_name:
return None, None, f"添加种子任务失败:无法读取种子文件"
return None, None, None, f"添加种子任务失败:无法读取种子文件"
# 查询所有下载器的种子
torrents, error = server.get_torrents()
if error:
return None, None, "无法连接qbittorrent下载器"
return None, None, None, "无法连接qbittorrent下载器"
if torrents:
for torrent in torrents:
# 名称与大小相等则认为是同一个种子
@@ -156,19 +161,19 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
if settings.TORRENT_TAG and settings.TORRENT_TAG not in torrent_tags:
logger.info(f"给种子 {torrent_hash} 打上标签:{settings.TORRENT_TAG}")
server.set_torrents_tag(ids=torrent_hash, tags=[settings.TORRENT_TAG])
return downloader or self.get_default_config_name(), torrent_hash, f"下载任务已存在"
return None, None, f"添加种子任务失败:{content}"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, f"下载任务已存在"
return None, None, None, f"添加种子任务失败:{content}"
else:
# 获取种子Hash
torrent_hash = server.get_torrent_id_by_tag(tags=tag)
if not torrent_hash:
return None, None, f"下载任务添加成功但获取Qbittorrent任务信息失败{content}"
return None, None, None, f"下载任务添加成功但获取Qbittorrent任务信息失败{content}"
else:
if is_paused:
# 种子文件
torrent_files = server.get_files(torrent_hash)
if not torrent_files:
return downloader or self.get_default_config_name(), torrent_hash, "获取种子文件失败,下载任务可能在暂停状态"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, "获取种子文件失败,下载任务可能在暂停状态"
# 不需要的文件ID
file_ids = []
@@ -193,11 +198,11 @@ class QbittorrentModule(_ModuleBase, _DownloaderBase[Qbittorrent]):
server.torrents_set_force_start(torrent_hash)
else:
server.start_torrents(torrent_hash)
return downloader or self.get_default_config_name(), torrent_hash, f"添加下载成功,已选择集数:{sucess_epidised}"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, f"添加下载成功,已选择集数:{sucess_epidised}"
else:
if server.is_force_resume():
server.torrents_set_force_start(torrent_hash)
return downloader or self.get_default_config_name(), torrent_hash, "添加下载成功"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, "添加下载成功"
def list_torrents(self, status: TorrentStatus = None,
hashs: Union[list, str] = None,

View File

@@ -80,7 +80,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
def download(self, content: Union[Path, str], download_dir: Path, cookie: str,
episodes: Set[int] = None, category: str = None,
downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], str]]:
downloader: str = None) -> Optional[Tuple[Optional[str], Optional[str], Optional[str], str]]:
"""
根据种子文件,选择并添加下载任务
:param content: 种子文件地址或者磁力链接
@@ -89,7 +89,7 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
:param episodes: 需要下载的集数
:param category: 分类TR中未使用
:param downloader: 下载器
:return: 下载器名称、种子Hash、错误原因
:return: 下载器名称、种子Hash、种子文件布局、错误原因
"""
def __get_torrent_info() -> Tuple[str, int]:
@@ -107,9 +107,9 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
return "", 0
if not content:
return None, None, "下载内容为空"
return None, None, None, "下载内容为空"
if isinstance(content, Path) and not content.exists():
return None, None, f"种子文件不存在:{content}"
return None, None, None, f"种子文件不存在:{content}"
# 获取下载器
server: Transmission = self.get_instance(downloader)
@@ -131,15 +131,18 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
labels=labels,
cookie=cookie
)
# TR 始终使用原始种子布局, 返回"Original"
torrent_layout = "Original"
if not torrent:
# 读取种子的名称
torrent_name, torrent_size = __get_torrent_info()
if not torrent_name:
return None, None, f"添加种子任务失败:无法读取种子文件"
return None, None, None, f"添加种子任务失败:无法读取种子文件"
# 查询所有下载器的种子
torrents, error = server.get_torrents()
if error:
return None, None, "无法连接transmission下载器"
return None, None, None, "无法连接transmission下载器"
if torrents:
for torrent in torrents:
# 名称与大小相等则认为是同一个种子
@@ -158,15 +161,15 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
if settings.TORRENT_TAG and settings.TORRENT_TAG not in labels:
labels.append(settings.TORRENT_TAG)
server.set_torrent_tag(ids=torrent_hash, tags=labels)
return downloader or self.get_default_config_name(), torrent_hash, f"下载任务已存在"
return None, None, f"添加种子任务失败:{content}"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, f"下载任务已存在"
return None, None, None, f"添加种子任务失败:{content}"
else:
torrent_hash = torrent.hashString
if is_paused:
# 选择文件
torrent_files = server.get_files(torrent_hash)
if not torrent_files:
return downloader or self.get_default_config_name(), torrent_hash, "获取种子文件失败,下载任务可能在暂停状态"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, "获取种子文件失败,下载任务可能在暂停状态"
# 需要的文件信息
file_ids = []
unwanted_file_ids = []
@@ -187,9 +190,9 @@ class TransmissionModule(_ModuleBase, _DownloaderBase[Transmission]):
server.set_unwanted_files(torrent_hash, unwanted_file_ids)
# 开始任务
server.start_torrents(torrent_hash)
return downloader or self.get_default_config_name(), torrent_hash, "添加下载任务成功"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, "添加下载任务成功"
else:
return downloader or self.get_default_config_name(), torrent_hash, "添加下载任务成功"
return downloader or self.get_default_config_name(), torrent_hash, torrent_layout, "添加下载任务成功"
def list_torrents(self, status: TorrentStatus = None,
hashs: Union[list, str] = None,