feat:新增同盘优先设置
This commit is contained in:
parent
be11ef72a9
commit
eb4e4b5141
@ -233,7 +233,7 @@ class DownloadChain(ChainBase):
|
|||||||
if not save_path:
|
if not save_path:
|
||||||
# 获取下载目录
|
# 获取下载目录
|
||||||
dir_info = self.directoryhelper.get_download_dir(_media)
|
dir_info = self.directoryhelper.get_download_dir(_media)
|
||||||
if not dir_info or not dir_info.path:
|
if not dir_info:
|
||||||
logger.error(f"未找到下载目录:{_media.type.value} {_media.title_year}")
|
logger.error(f"未找到下载目录:{_media.type.value} {_media.title_year}")
|
||||||
self.messagehelper.put(f"{_media.type.value} {_media.title_year} 未找到下载目录!",
|
self.messagehelper.put(f"{_media.type.value} {_media.title_year} 未找到下载目录!",
|
||||||
title="下载失败", role="system")
|
title="下载失败", role="system")
|
||||||
|
@ -185,6 +185,8 @@ class Settings(BaseSettings):
|
|||||||
PLEX_TOKEN: Optional[str] = None
|
PLEX_TOKEN: Optional[str] = None
|
||||||
# 转移方式 link/copy/move/softlink
|
# 转移方式 link/copy/move/softlink
|
||||||
TRANSFER_TYPE: str = "copy"
|
TRANSFER_TYPE: str = "copy"
|
||||||
|
# 是否同盘优先
|
||||||
|
TRANSFER_SAME_DISK: bool = True
|
||||||
# CookieCloud是否启动本地服务
|
# CookieCloud是否启动本地服务
|
||||||
COOKIECLOUD_ENABLE_LOCAL: Optional[bool] = False
|
COOKIECLOUD_ENABLE_LOCAL: Optional[bool] = False
|
||||||
# CookieCloud服务器地址
|
# CookieCloud服务器地址
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
from pathlib import Path
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from app import schemas
|
from app import schemas
|
||||||
@ -5,6 +6,7 @@ from app.core.config import settings
|
|||||||
from app.core.context import MediaInfo
|
from app.core.context import MediaInfo
|
||||||
from app.db.systemconfig_oper import SystemConfigOper
|
from app.db.systemconfig_oper import SystemConfigOper
|
||||||
from app.schemas.types import SystemConfigKey, MediaType
|
from app.schemas.types import SystemConfigKey, MediaType
|
||||||
|
from app.utils.system import SystemUtils
|
||||||
|
|
||||||
|
|
||||||
class DirectoryHelper:
|
class DirectoryHelper:
|
||||||
@ -41,6 +43,8 @@ class DirectoryHelper:
|
|||||||
media_dirs = self.get_download_dirs()
|
media_dirs = self.get_download_dirs()
|
||||||
# 按照配置顺序查找(保存后的数据已经排序)
|
# 按照配置顺序查找(保存后的数据已经排序)
|
||||||
for media_dir in media_dirs:
|
for media_dir in media_dirs:
|
||||||
|
if not media_dir.path:
|
||||||
|
continue
|
||||||
# 没有媒体信息时,返回第一个类型为全部的目录
|
# 没有媒体信息时,返回第一个类型为全部的目录
|
||||||
if (not media or media.type == MediaType.UNKNOWN) and not media_dir.media_type:
|
if (not media or media.type == MediaType.UNKNOWN) and not media_dir.media_type:
|
||||||
return media_dir
|
return media_dir
|
||||||
@ -62,20 +66,24 @@ class DirectoryHelper:
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_library_dir(self, media: MediaInfo = None) -> Optional[schemas.MediaDirectory]:
|
def get_library_dir(self, media: MediaInfo = None, in_path: Path = None) -> Optional[schemas.MediaDirectory]:
|
||||||
"""
|
"""
|
||||||
根据媒体信息获取媒体库目录
|
根据媒体信息获取媒体库目录,需判断是否同盘优先
|
||||||
:param media: 媒体信息
|
:param media: 媒体信息
|
||||||
|
:param in_path: 源目录
|
||||||
"""
|
"""
|
||||||
|
matched_dirs = []
|
||||||
library_dirs = self.get_library_dirs()
|
library_dirs = self.get_library_dirs()
|
||||||
# 按照配置顺序查找(保存后的数据已经排序)
|
# 按照配置顺序查找(保存后的数据已经排序)
|
||||||
for library_dir in library_dirs:
|
for library_dir in library_dirs:
|
||||||
|
if not library_dir.path:
|
||||||
|
continue
|
||||||
# 没有媒体信息时,返回第一个类型为全部的目录
|
# 没有媒体信息时,返回第一个类型为全部的目录
|
||||||
if (not media or media.type == MediaType.UNKNOWN) and not library_dir.media_type:
|
if (not media or media.type == MediaType.UNKNOWN) and not library_dir.media_type:
|
||||||
return library_dir
|
matched_dirs.append(library_dir)
|
||||||
# 目录类型为全部的,符合条件
|
# 目录类型为全部的,符合条件
|
||||||
if not library_dir.media_type:
|
if not library_dir.media_type:
|
||||||
return library_dir
|
matched_dirs.append(library_dir)
|
||||||
# 处理类型
|
# 处理类型
|
||||||
if media.genre_ids \
|
if media.genre_ids \
|
||||||
and set(media.genre_ids).intersection(set(settings.ANIME_GENREIDS)):
|
and set(media.genre_ids).intersection(set(settings.ANIME_GENREIDS)):
|
||||||
@ -84,9 +92,22 @@ class DirectoryHelper:
|
|||||||
media_type = media.type.value
|
media_type = media.type.value
|
||||||
# 目录类型相等,目录类别为全部,符合条件
|
# 目录类型相等,目录类别为全部,符合条件
|
||||||
if library_dir.media_type == media_type and not library_dir.category:
|
if library_dir.media_type == media_type and not library_dir.category:
|
||||||
return library_dir
|
matched_dirs.append(library_dir)
|
||||||
# 目录类型相等,目录类别相等,符合条件
|
# 目录类型相等,目录类别相等,符合条件
|
||||||
if library_dir.media_type == media_type and library_dir.category == media.category:
|
if library_dir.media_type == media_type and library_dir.category == media.category:
|
||||||
return library_dir
|
matched_dirs.append(library_dir)
|
||||||
|
|
||||||
return None
|
# 未匹配到
|
||||||
|
if not matched_dirs:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 优先同盘
|
||||||
|
if in_path and settings.TRANSFER_SAME_DISK:
|
||||||
|
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 SystemUtils.is_same_disk(matched_path, in_path):
|
||||||
|
return matched_dir
|
||||||
|
|
||||||
|
return matched_dirs[0]
|
||||||
|
@ -72,9 +72,9 @@ class FileTransferModule(_ModuleBase):
|
|||||||
for d_path in download_paths:
|
for d_path in download_paths:
|
||||||
download_path = Path(d_path.path)
|
download_path = Path(d_path.path)
|
||||||
if l_path.media_type == d_path.media_type and l_path.category == d_path.category:
|
if l_path.media_type == d_path.media_type and l_path.category == d_path.category:
|
||||||
if library_path.stat().st_dev != download_path.stat().st_dev:
|
if not SystemUtils.is_same_disk(library_path, download_path):
|
||||||
return False, f"媒体库目录 {library_path} " \
|
return False, f"媒体库目录 {library_path} " \
|
||||||
f"与下载目录 {download_path} 不在同一设备,将无法硬链接"
|
f"与下载目录 {download_path} 不在同一磁盘/存储空间/映射路径,将无法硬链接"
|
||||||
return True, ""
|
return True, ""
|
||||||
|
|
||||||
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
def init_setting(self) -> Tuple[str, Union[str, bool]]:
|
||||||
@ -98,8 +98,8 @@ class FileTransferModule(_ModuleBase):
|
|||||||
# 获取目标路径
|
# 获取目标路径
|
||||||
if not target:
|
if not target:
|
||||||
# 未指定目的目录,选择一个媒体库
|
# 未指定目的目录,选择一个媒体库
|
||||||
dir_info = DirectoryHelper().get_library_dir(mediainfo)
|
dir_info = DirectoryHelper().get_library_dir(mediainfo, in_path=path)
|
||||||
if not dir_info or not dir_info.path:
|
if not dir_info:
|
||||||
logger.error(f"{mediainfo.type.value} {mediainfo.title_year} 未找到有效的媒体库目录,无法转移文件,源路径:{path}")
|
logger.error(f"{mediainfo.type.value} {mediainfo.title_year} 未找到有效的媒体库目录,无法转移文件,源路径:{path}")
|
||||||
return TransferInfo(success=False,
|
return TransferInfo(success=False,
|
||||||
path=path,
|
path=path,
|
||||||
|
@ -465,3 +465,14 @@ class SystemUtils:
|
|||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(str(err))
|
print(str(err))
|
||||||
return False, f"重启时发生错误:{str(err)}"
|
return False, f"重启时发生错误:{str(err)}"
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_same_disk(src: Path, dest: Path) -> bool:
|
||||||
|
"""
|
||||||
|
判断两个路径是否在同一磁盘
|
||||||
|
"""
|
||||||
|
if not src.exists() or not dest.exists():
|
||||||
|
return False
|
||||||
|
if os.name == "nt":
|
||||||
|
return src.drive == dest.drive
|
||||||
|
return os.stat(src).st_dev == os.stat(dest).st_dev
|
||||||
|
Loading…
x
Reference in New Issue
Block a user