fix: normalize downloader return paths

Fixes #5773
This commit is contained in:
jxxghp
2026-05-15 18:15:42 +08:00
parent 51229204c9
commit 1f49f9b454
5 changed files with 428 additions and 18 deletions

View File

@@ -291,7 +291,38 @@ class _DownloaderBase(ServiceBase[TService, DownloaderConf]):
重置默认配置名称
"""
self._default_config_name = None
@staticmethod
def __replace_path_prefix(path: Union[Path, str], source: str, target: str) -> Optional[str]:
"""
按完整路径段替换路径前缀,避免 /media 误匹配 /media2 这类相邻目录。
"""
if not source or not source.strip() or not target or not target.strip():
return None
path_text = Path(path).as_posix()
source_path = Path(source.strip()).as_posix()
target_path = Path(target.strip()).as_posix()
if path_text == source_path:
return target_path
source_prefix = f"{source_path.rstrip('/')}/"
if path_text.startswith(source_prefix):
suffix = path_text[len(source_prefix):]
return (Path(target_path) / suffix).as_posix()
return None
@staticmethod
def __strip_storage_prefix(path: str) -> str:
"""
去掉存储协议前缀 if any下载器无法识别本地存储协议。
"""
for s in StorageSchema:
prefix = f"{s.value}:"
if path.startswith(prefix):
return path[len(prefix):]
return path
def normalize_path(self, path: Path, downloader: Optional[str]) -> str:
"""
根据下载器配置和路径映射,规范化下载路径
@@ -300,21 +331,33 @@ class _DownloaderBase(ServiceBase[TService, DownloaderConf]):
:param downloader: 下载器名称
:return: 规范化后发送给下载器的路径
"""
dir = path.as_posix()
normalized_path = path.as_posix()
conf = self.get_config(downloader)
if conf and conf.path_mapping:
for (storage_path, download_path) in conf.path_mapping:
storage_path = Path(storage_path.strip()).as_posix()
download_path = Path(download_path.strip()).as_posix()
if dir.startswith(storage_path):
dir = dir.replace(storage_path, download_path, 1)
mapped_path = self.__replace_path_prefix(normalized_path, storage_path, download_path)
if mapped_path:
normalized_path = mapped_path
break
# 去掉存储协议前缀 if any, 下载器无法识别
for s in StorageSchema:
prefix = f"{s.value}:"
if dir.startswith(prefix):
return dir[len(prefix):]
return dir
return self.__strip_storage_prefix(normalized_path)
def normalize_return_path(self, path: Path, downloader: Optional[str]) -> str:
"""
将下载器返回的路径反向映射为 MoviePilot 可访问的存储路径。
:param path: 下载器返回的路径
:param downloader: 下载器名称
:return: MoviePilot 可访问的路径
"""
normalized_path = path.as_posix()
conf = self.get_config(downloader)
if conf and conf.path_mapping:
for (storage_path, download_path) in conf.path_mapping:
mapped_path = self.__replace_path_prefix(normalized_path, download_path, storage_path)
if mapped_path:
normalized_path = mapped_path
break
return self.__strip_storage_prefix(normalized_path)
class _MediaServerBase(ServiceBase[TService, MediaServerConf]):