Merge pull request #5197 from stkevintan/default-samba

This commit is contained in:
jxxghp
2025-11-28 19:42:43 +08:00
committed by GitHub
4 changed files with 63 additions and 23 deletions

View File

@@ -707,17 +707,19 @@ class ChainBase(metaclass=ABCMeta):
cookie=cookie, episodes=episodes, category=category, label=label,
downloader=downloader)
def download_added(self, context: Context, download_dir: Path, torrent_content: Union[str, bytes] = None) -> None:
def download_added(self, context: Context, download_dir: Path, storage: str, 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)
download_dir=download_dir,
storage=storage)
def list_torrents(self, status: TorrentStatus = None,
hashs: Union[list, str] = None,

View File

@@ -232,13 +232,18 @@ class DownloadChain(ChainBase):
# 获取种子文件的文件夹名和文件清单
_folder_name, _file_list = TorrentHelper().get_fileinfo_from_torrent_content(torrent_content)
storage = 'local'
# 下载目录
if save_path:
# 下载目录使用自定义的
download_dir = Path(save_path)
# Check if the download_dir matches any configured dirs
dir_info = DirectoryHelper().get_dir(dest_path=download_dir)
storage = dir_info.storage if dir_info else storage
else:
# 根据媒体信息查询下载目录配置
dir_info = DirectoryHelper().get_dir(_media, storage="local", include_unsorted=True)
dir_info = DirectoryHelper().get_dir(_media, include_unsorted=True)
storage = dir_info.storage if dir_info else storage
# 拼装子目录
if dir_info:
# 一级目录
@@ -358,7 +363,7 @@ class DownloadChain(ChainBase):
username=username,
)
# 下载成功后处理
self.download_added(context=context, download_dir=download_dir, torrent_content=torrent_content)
self.download_added(context=context, download_dir=download_dir, storage=storage, torrent_content=torrent_content)
# 广播事件
self.eventmanager.send_event(EventType.DownloadAdded, {
"hash": _hash,

View File

@@ -1,6 +1,6 @@
import re
from pathlib import Path
from typing import List, Optional
from typing import List, Optional, Tuple
from app import schemas
from app.core.context import MediaInfo
@@ -51,7 +51,7 @@ class DirectoryHelper:
"""
return [d for d in self.get_library_dirs() if d.library_storage == "local"]
def get_dir(self, media: MediaInfo, include_unsorted: Optional[bool] = False,
def get_dir(self, media: Optional[MediaInfo], include_unsorted: Optional[bool] = False,
storage: Optional[str] = None, src_path: Path = None,
target_storage: Optional[str] = None, dest_path: Path = None
) -> Optional[schemas.TransferDirectoryConf]:
@@ -64,11 +64,8 @@ class DirectoryHelper:
:param src_path: 源目录,有值时直接匹配
:param dest_path: 目标目录,有值时直接匹配
"""
# 处理类型
if not media:
return None
# 电影/电视剧
media_type = media.type.value
media_type = media.type.value if media else None
dirs = self.get_dirs()
# 如果存在源目录,并源目录为任一下载目录的子目录时,则进行源目录匹配,否则,允许源目录按同盘优先的逻辑匹配
@@ -93,7 +90,7 @@ class DirectoryHelper:
if dest_path and dest_path != Path(d.library_path):
continue
# 目录类型为全部的,符合条件
if not d.media_type:
if not media_type or not d.media_type:
matched_dirs.append(d)
continue
# 目录类型相等,目录类别为全部,符合条件
@@ -109,11 +106,27 @@ class DirectoryHelper:
# 优先源目录同盘
for matched_dir in matched_dirs:
matched_path = Path(matched_dir.download_path)
if SystemUtils.is_same_disk(matched_path, src_path):
if self._is_same_source((src_path, storage or "local"), (matched_path, matched_dir.library_storage)):
return matched_dir
return matched_dirs[0]
return None
@staticmethod
def _is_same_source(src: Tuple[Path, str], tar: Tuple[Path, str]) -> bool:
"""
判断源目录和目标目录是否在同一存储盘
:param src: 源目录路径和存储类型
:param tar: 目标目录路径和存储类型
:return: 是否在同一存储盘
"""
src_path, src_storage = src
tar_path, tar_storage = tar
if "local" == tar_storage == src_storage:
return SystemUtils.is_same_disk(src_path, tar_path)
# 网络存储,直接比较类型
return src_storage == tar_storage
@staticmethod
def get_media_root_path(rename_format: str, rename_path: Path) -> Optional[Path]:
"""

View File

@@ -5,11 +5,13 @@ from typing import Tuple, Union
from lxml import etree
from app.chain.storage import StorageChain
from app.core.config import settings
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.types import ModuleType, OtherModulesType
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
@@ -63,11 +65,12 @@ class SubtitleModule(_ModuleBase):
def test(self):
pass
def download_added(self, context: Context, download_dir: Path, torrent_content: Union[str, bytes] = None):
def download_added(self, context: Context, download_dir: Path, storage: str, torrent_content: Union[str, bytes] = None):
"""
添加下载任务成功后,从站点下载字幕,保存到下载目录
:param context: 上下文,包括识别信息、媒体信息、种子信息
:param download_dir: 下载目录
:param storage: 存储类型
:param torrent_content: 种子内容,如果是种子文件,则为文件内容,否则为种子字符串
:return: None该方法可被多个模块同时处理
"""
@@ -87,15 +90,29 @@ class SubtitleModule(_ModuleBase):
# 获取种子信息
folder_name, _ = TorrentHelper().get_fileinfo_from_torrent_content(torrent_content)
# 文件保存目录如果是单文件种子则folder_name是空此时文件保存目录就是下载目录
download_dir = download_dir / folder_name
storageChain = StorageChain()
# 等待目录存在
working_dir_item = None
for _ in range(30):
if download_dir.exists():
found = storageChain.get_file_item(storage, download_dir / folder_name)
if found:
working_dir_item = found
break
time.sleep(1)
# 目录仍然不存在,且有文件夹名,则创建目录
if not download_dir.exists() and folder_name:
download_dir.mkdir(parents=True, exist_ok=True)
if not working_dir_item and folder_name:
parent_dir_item = storageChain.get_file_item(storage, download_dir)
if parent_dir_item:
working_dir_item = storageChain.create_folder(
parent_dir_item,
folder_name
)
else:
logger.error(f"下载根目录不存在,无法创建字幕文件夹:{download_dir}")
return
if not working_dir_item:
logger.error(f"下载目录不存在,无法保存字幕:{download_dir / folder_name}")
return
# 读取网站代码
request = RequestUtils(cookies=torrent.site_cookie, ua=torrent.site_ua)
res = request.get_res(torrent.page_url)
@@ -144,12 +161,12 @@ class SubtitleModule(_ModuleBase):
shutil.unpack_archive(zip_file, zip_path, format='zip')
# 遍历转移文件
for sub_file in SystemUtils.list_files(zip_path, settings.RMT_SUBEXT):
target_sub_file = download_dir / sub_file.name
if target_sub_file.exists():
target_sub_file = Path(working_dir_item.path) / Path(sub_file.name)
if storageChain.get_file_item(storage, target_sub_file):
logger.info(f"字幕文件已存在:{target_sub_file}")
continue
logger.info(f"转移字幕 {sub_file}{target_sub_file} ...")
SystemUtils.copy(sub_file, target_sub_file)
storageChain.upload_file(working_dir_item, sub_file)
# 删除临时文件
try:
shutil.rmtree(zip_path)
@@ -160,9 +177,12 @@ class SubtitleModule(_ModuleBase):
sub_file = settings.TEMP_PATH / file_name
# 保存
sub_file.write_bytes(ret.content)
target_sub_file = download_dir / sub_file.name
logger.info(f"转移字幕 {sub_file}{target_sub_file}")
SystemUtils.copy(sub_file, target_sub_file)
target_sub_file = Path(working_dir_item.path) / Path(sub_file.name)
if storageChain.get_file_item(storage, target_sub_file):
logger.info(f"字幕文件已存在:{target_sub_file}")
continue
logger.info(f"转移字幕 {sub_file}{target_sub_file} ...")
storageChain.upload_file(working_dir_item, sub_file)
else:
logger.error(f"下载字幕文件失败:{sublink}")
continue