feat 多媒体库目录支持
This commit is contained in:
parent
94a5c5e2e2
commit
085409049d
@ -49,7 +49,7 @@ docker pull jxxghp/moviepilot:latest
|
||||
- **PROXY_HOST:** 网络代理(可选),访问themoviedb需要使用代理访问,格式为`ip:port`
|
||||
- **TMDB_API_DOMAIN:** TMDB API地址,默认`api.themoviedb.org`,也可配置为`api.tmdb.org`或其它中转代理服务地址,能连通即可
|
||||
- **DOWNLOAD_PATH:** 下载保存目录,**注意:需要将`moviepilot`及`下载器`的映射路径与宿主机`真实路径`保持一致**,例如群晖中下载路程径为`/volume1/downloads`,则需要将`moviepilot`及`下载器`的映射路径均设置为`/volume1/downloads`,否则会导致下载文件无法转移
|
||||
- **LIBRARY_PATH:** 媒体库目录,**注意:需要将`moviepilot`的映射路径与宿主机`真实路径`保持一致**
|
||||
- **LIBRARY_PATH:** 媒体库目录,**注意:需要将`moviepilot`的映射路径与宿主机`真实路径`保持一致**,多个目录使用`,`分隔
|
||||
- **LIBRARY_CATEGORY:** 二级分类开关,`true`/`false`,开启后会根据配置自动在媒体库目录下建立二级目录分类
|
||||
- **DOUBAN_USER_IDS:** 豆瓣用户ID,用于同步豆瓣标记的`想看`数据,自动添加订阅,多个用户使用,分隔
|
||||
- **TRANSFER_TYPE:** 转移方式,支持`link`/`copy`/`move`/`softlink`
|
||||
@ -196,7 +196,7 @@ docker pull jxxghp/moviepilot:latest
|
||||
- 通过CookieCloud同步快速同步站点,不需要使用的站点可在WEB管理界面中禁用。
|
||||
- 通过下载器监控实现资源下载后自动整理入库刮削。
|
||||
- 通过微信/Telegram/Slack远程搜索下载、订阅和管理设置,其中Telegram将会自动添加操作菜单。微信回调相对路径为`/api/v1/message/`。
|
||||
- 通过WEB进行管理,将WEB添加到手机桌面获得类App使用效果,管理界面地址:http://ip:3000。
|
||||
- 通过WEB进行管理,将WEB添加到手机桌面获得类App使用效果,管理界面端口:`3000`。
|
||||
- 设置媒体服务器Webhook,通过MoviePilot发送播放通知,以及后续播放限速等插件功能。Webhook回调相对路径为`/api/v1/message?token=moviepilot`,其中`moviepilot`为设置的`API_TOKEN`。
|
||||
- 将MoviePilot做为Radarr或Sonarr服务器添加到Overseerr或Jellyseerr,可使用Overseerr/Jellyseerr选片。
|
||||
|
||||
@ -216,7 +216,7 @@ docker pull jxxghp/moviepilot:latest
|
||||
|
||||
- [x] 搜索结果过滤
|
||||
- [x] 多通知渠道支持
|
||||
- [ ] 多媒体库目录支持
|
||||
- [x] 多媒体库目录支持
|
||||
- [ ] 插件管理,支持自定义插件功能界面
|
||||
- [ ] 更易用的自定义识别词
|
||||
- [ ] 手动整理功能增强
|
||||
|
@ -38,7 +38,9 @@ def storage(_: schemas.TokenPayload = Depends(verify_token)) -> Any:
|
||||
查询存储空间信息
|
||||
"""
|
||||
if settings.LIBRARY_PATH:
|
||||
total_storage, free_storage = SystemUtils.space_usage(Path(settings.LIBRARY_PATH))
|
||||
total_storage, free_storage = SystemUtils.space_usage(
|
||||
[Path(path) for path in settings.LIBRARY_PATH.split(",")]
|
||||
)
|
||||
else:
|
||||
total_storage, free_storage = 0, 0
|
||||
return schemas.Storage(
|
||||
|
@ -63,10 +63,13 @@ def arr_rootfolder(apikey: str) -> Any:
|
||||
status_code=403,
|
||||
detail="认证失败!",
|
||||
)
|
||||
library_path = "/"
|
||||
if settings.LIBRARY_PATH:
|
||||
library_path = settings.LIBRARY_PATH.split(",")[0]
|
||||
return [
|
||||
{
|
||||
"id": 1,
|
||||
"path": settings.LIBRARY_PATH,
|
||||
"path": library_path,
|
||||
"accessible": True,
|
||||
"freeSpace": 0,
|
||||
"unmappedFolders": []
|
||||
|
@ -36,13 +36,16 @@ class FileTransferModule(_ModuleBase):
|
||||
:param mediainfo: 识别的媒体信息
|
||||
:return: {path, target_path, message}
|
||||
"""
|
||||
if not settings.LIBRARY_PATH:
|
||||
logger.error("未设置媒体库目录,无法转移文件")
|
||||
return None
|
||||
# 获取目标路径
|
||||
target_path = self.get_target_path(in_path=path)
|
||||
if not target_path:
|
||||
logger.error("未找到媒体库目录,无法转移文件")
|
||||
return TransferInfo(message="未找到媒体库目录,无法转移文件")
|
||||
# 转移
|
||||
result = self.transfer_media(in_path=path,
|
||||
meidainfo=mediainfo,
|
||||
rmt_mode=settings.TRANSFER_TYPE,
|
||||
target_dir=Path(settings.LIBRARY_PATH))
|
||||
target_dir=target_path)
|
||||
if not result:
|
||||
return TransferInfo()
|
||||
if isinstance(result, str):
|
||||
@ -514,20 +517,6 @@ class FileTransferModule(_ModuleBase):
|
||||
"fileExt": file_ext
|
||||
}
|
||||
|
||||
def get_movie_dest_path(self, meta: MetaBase, mediainfo: MediaInfo) -> Tuple[str, str]:
|
||||
"""
|
||||
计算电影文件路径
|
||||
:return: 电影目录、电影名称
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_tv_dest_path(self, meta: MetaBase, mediainfo: MediaInfo) -> Tuple[str, str, str]:
|
||||
"""
|
||||
计算电视剧文件路径
|
||||
:return: 电视剧目录、季目录、集名称
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_rename_path(template_string: str, rename_dict: dict, path: Path = None) -> Path:
|
||||
"""
|
||||
@ -542,3 +531,36 @@ class FileTransferModule(_ModuleBase):
|
||||
return path / render_str
|
||||
else:
|
||||
return Path(render_str)
|
||||
|
||||
@staticmethod
|
||||
def get_target_path(in_path: Path = None) -> Optional[Path]:
|
||||
"""
|
||||
计算一个最好的目的目录,有in_path时找与in_path同路径的,没有in_path时,顺序查找1个符合大小要求的,没有in_path和size时,返回第1个
|
||||
:param in_path: 源目录
|
||||
"""
|
||||
if not settings.LIBRARY_PATH:
|
||||
return None
|
||||
# 目的路径,多路径以,分隔
|
||||
dest_paths = str(settings.LIBRARY_PATH).split(",")
|
||||
# 只有一个路径,直接返回
|
||||
if len(dest_paths) == 1:
|
||||
return Path(dest_paths[0])
|
||||
# 匹配有最长共同上级路径的目录
|
||||
max_length = 0
|
||||
target_path = None
|
||||
if in_path:
|
||||
for path in dest_paths:
|
||||
relative = Path(path).relative_to(in_path).as_posix()
|
||||
if relative.startswith("..") or len(relative) > max_length:
|
||||
max_length = len(relative)
|
||||
target_path = path
|
||||
if target_path:
|
||||
return Path(target_path)
|
||||
# 顺序匹配第1个满足空间存储要求的目录
|
||||
if in_path.exists():
|
||||
file_size = in_path.stat().st_size
|
||||
for path in dest_paths:
|
||||
if SystemUtils.free_space(Path(path)) > file_size:
|
||||
return Path(path)
|
||||
# 默认返回第1个
|
||||
return Path(dest_paths[0])
|
||||
|
Loading…
x
Reference in New Issue
Block a user