mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-08-28 03:27:31 +08:00
fix directories
This commit is contained in:
+46
-124
@@ -2,12 +2,9 @@ from pathlib import Path
|
||||
from typing import List, Optional
|
||||
|
||||
from app import schemas
|
||||
from app.core.config import settings
|
||||
from app.core.context import MediaInfo
|
||||
from app.db.systemconfig_oper import SystemConfigOper
|
||||
from app.log import logger
|
||||
from app.schemas.types import SystemConfigKey, MediaType
|
||||
from app.utils.system import SystemUtils
|
||||
|
||||
|
||||
class DirectoryHelper:
|
||||
@@ -18,147 +15,72 @@ class DirectoryHelper:
|
||||
def __init__(self):
|
||||
self.systemconfig = SystemConfigOper()
|
||||
|
||||
def get_download_dirs(self) -> List[schemas.MediaDirectory]:
|
||||
def get_download_dirs(self) -> List[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
获取下载目录
|
||||
获取所有下载目录
|
||||
"""
|
||||
dir_conf: List[dict] = self.systemconfig.get(SystemConfigKey.DownloadDirectories)
|
||||
if not dir_conf:
|
||||
dir_confs: List[dict] = self.systemconfig.get(SystemConfigKey.Directories)
|
||||
if not dir_confs:
|
||||
return []
|
||||
return [schemas.MediaDirectory(**d) for d in dir_conf]
|
||||
dirs = [schemas.TransferDirectoryConf(**d) for d in dir_confs]
|
||||
return sorted([d for d in dirs if d.download_path], key=lambda x: x.priority)
|
||||
|
||||
def get_library_dirs(self) -> List[schemas.MediaDirectory]:
|
||||
def get_local_download_dirs(self) -> List[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
获取媒体库目录
|
||||
获取所有本地的可下载目录
|
||||
"""
|
||||
dir_conf: List[dict] = self.systemconfig.get(SystemConfigKey.LibraryDirectories)
|
||||
if not dir_conf:
|
||||
return [d for d in self.get_download_dirs() if d.storage == "local"]
|
||||
|
||||
def get_library_dirs(self) -> List[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
获取所有媒体库目录
|
||||
"""
|
||||
dir_confs: List[dict] = self.systemconfig.get(SystemConfigKey.Directories)
|
||||
if not dir_confs:
|
||||
return []
|
||||
return [schemas.MediaDirectory(**d) for d in dir_conf]
|
||||
dirs = [schemas.TransferDirectoryConf(**d) for d in dir_confs]
|
||||
return sorted([d for d in dirs if d.library_path], key=lambda x: x.priority)
|
||||
|
||||
def get_download_dir(self, media: MediaInfo = None, to_path: Path = None) -> Optional[schemas.MediaDirectory]:
|
||||
def get_local_library_dirs(self) -> List[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
根据媒体信息获取下载目录
|
||||
获取所有本地的媒体库目录
|
||||
"""
|
||||
return [d for d in self.get_library_dirs() if d.library_storage == "local"]
|
||||
|
||||
def get_dir(self, media: MediaInfo, src_path: Path = None, dest_path: Path = None,
|
||||
local: bool = False) -> Optional[schemas.TransferDirectoryConf]:
|
||||
"""
|
||||
根据媒体信息获取下载目录、媒体库目录配置
|
||||
:param media: 媒体信息
|
||||
:param to_path: 目标目录
|
||||
:param src_path: 源目录,有值时直接匹配
|
||||
:param dest_path: 目标目录,有值时直接匹配
|
||||
:param local: 是否本地目录
|
||||
"""
|
||||
# 处理类型
|
||||
if media:
|
||||
media_type = media.type.value
|
||||
else:
|
||||
media_type = MediaType.UNKNOWN.value
|
||||
download_dirs = self.get_download_dirs()
|
||||
# 按照配置顺序查找(保存后的数据已经排序)
|
||||
for download_dir in download_dirs:
|
||||
if not download_dir.path:
|
||||
dirs = self.get_download_dirs()
|
||||
# 按照配置顺序查找
|
||||
for d in dirs:
|
||||
download_path = Path(d.download_path)
|
||||
# 有目录时直接匹配
|
||||
if src_path and download_path != src_path:
|
||||
continue
|
||||
download_path = Path(download_dir.path)
|
||||
# 有目标目录,但目标目录与当前目录不相等时不要
|
||||
if to_path and download_path != to_path:
|
||||
if dest_path and download_path != dest_path:
|
||||
continue
|
||||
# 本地目录
|
||||
if local and d.storage != "local":
|
||||
continue
|
||||
# 目录类型为全部的,符合条件
|
||||
if not download_dir.media_type:
|
||||
return download_dir
|
||||
if not d.media_type:
|
||||
return d
|
||||
# 目录类型相等,目录类别为全部,符合条件
|
||||
if download_dir.media_type == media_type and not download_dir.category:
|
||||
return download_dir
|
||||
if d.media_type == media_type and not d.media_category:
|
||||
return d
|
||||
# 目录类型相等,目录类别相等,符合条件
|
||||
if download_dir.media_type == media_type and download_dir.category == media.category:
|
||||
return download_dir
|
||||
if d.media_type == media_type and d.media_category == media.category:
|
||||
return d
|
||||
|
||||
return None
|
||||
|
||||
def get_library_dir(self, media: MediaInfo = None, in_path: Path = None,
|
||||
to_path: Path = None) -> Optional[schemas.MediaDirectory]:
|
||||
"""
|
||||
根据媒体信息获取媒体库目录,需判断是否同盘优先
|
||||
:param media: 媒体信息
|
||||
:param in_path: 源目录
|
||||
:param to_path: 目标目录
|
||||
"""
|
||||
|
||||
def __comman_parts(path1: Path, path2: Path) -> int:
|
||||
"""
|
||||
计算两个路径的公共路径长度
|
||||
"""
|
||||
parts1 = path1.parts
|
||||
parts2 = path2.parts
|
||||
root_flag = parts1[0] == '/' and parts2[0] == '/'
|
||||
length = min(len(parts1), len(parts2))
|
||||
for i in range(length):
|
||||
if parts1[i] == '/' and parts2[i] == '/':
|
||||
continue
|
||||
if parts1[i] != parts2[i]:
|
||||
return i - 1 if root_flag else i
|
||||
return length - 1 if root_flag else length
|
||||
|
||||
# 处理类型
|
||||
if media:
|
||||
media_type = media.type.value
|
||||
else:
|
||||
media_type = MediaType.UNKNOWN.value
|
||||
|
||||
# 匹配的目录
|
||||
matched_dirs = []
|
||||
library_dirs = self.get_library_dirs()
|
||||
# 按照配置顺序查找(保存后的数据已经排序)
|
||||
for library_dir in library_dirs:
|
||||
if not library_dir.path:
|
||||
continue
|
||||
# 有目标目录,但目标目录与当前目录不相等时不要
|
||||
if to_path and Path(library_dir.path) != to_path:
|
||||
continue
|
||||
# 目录类型为全部的,符合条件
|
||||
if not library_dir.media_type:
|
||||
matched_dirs.append(library_dir)
|
||||
# 目录类型相等,目录类别为全部,符合条件
|
||||
if library_dir.media_type == media_type and not library_dir.category:
|
||||
matched_dirs.append(library_dir)
|
||||
# 目录类型相等,目录类别相等,符合条件
|
||||
if library_dir.media_type == media_type and library_dir.category == media.category:
|
||||
matched_dirs.append(library_dir)
|
||||
|
||||
# 未匹配到
|
||||
if not matched_dirs:
|
||||
return None
|
||||
|
||||
# 没有目录则创建
|
||||
for matched_dir in matched_dirs:
|
||||
matched_path = Path(matched_dir.path)
|
||||
if not matched_path.exists():
|
||||
matched_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# 只匹配到一项
|
||||
if len(matched_dirs) == 1:
|
||||
return matched_dirs[0]
|
||||
|
||||
# 有源路径,且开启同盘/同目录优先时
|
||||
if in_path and settings.TRANSFER_SAME_DISK:
|
||||
# 优先同根路径
|
||||
max_length = 0
|
||||
target_dirs = []
|
||||
for matched_dir in matched_dirs:
|
||||
try:
|
||||
# 计算in_path和path的公共路径长度
|
||||
relative_len = __comman_parts(in_path, Path(matched_dir.path))
|
||||
if relative_len and relative_len >= max_length:
|
||||
max_length = relative_len
|
||||
target_dirs.append({
|
||||
'path': matched_dir,
|
||||
'relative_len': relative_len
|
||||
})
|
||||
except Exception as e:
|
||||
logger.debug(f"计算目标路径时出错:{str(e)}")
|
||||
continue
|
||||
if target_dirs:
|
||||
target_dirs.sort(key=lambda x: x['relative_len'], reverse=True)
|
||||
matched_dirs = [x['path'] for x in target_dirs]
|
||||
|
||||
# 优先同盘
|
||||
for matched_dir in matched_dirs:
|
||||
matched_path = Path(matched_dir.path)
|
||||
if SystemUtils.is_same_disk(matched_path, in_path):
|
||||
return matched_dir
|
||||
|
||||
# 返回最优先的匹配
|
||||
return matched_dirs[0]
|
||||
|
||||
Reference in New Issue
Block a user