Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions app/helper/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ def get_download_dir_by_save_path(
return dir_info
if dir_info.media_type == media_type and not dir_info.media_category:
return dir_info
if dir_info.media_type == media_type and dir_info.media_category == media.category:
if dir_info.media_type == media_type and _match_media_category(
dir_info.media_category, media.category):
return dir_info
return None

Expand Down Expand Up @@ -136,8 +137,8 @@ def get_dir(self, media: Optional[MediaInfo], include_unsorted: Optional[bool] =
if d.media_type == media_type and not d.media_category:
matched_dirs.append(d)
continue
# 目录类型相等,目录类别相等,符合条件
if d.media_type == media_type and d.media_category == media.category:
# 目录类型相等,目录类别命中配置,符合条件
if d.media_type == media_type and _match_media_category(d.media_category, media.category):
matched_dirs.append(d)
continue
if matched_dirs:
Expand Down Expand Up @@ -210,6 +211,20 @@ def get_media_root_path(rename_format: str, rename_path: Path) -> Optional[Path]
return media_root


def _match_media_category(configured_category: Optional[str], media_category: Optional[str]) -> bool:
"""
判断媒体类别是否命中目录配置,支持逗号分隔的多个类别。
"""
if not configured_category or not media_category:
return False
categories = {
category.strip()
for category in re.split(r"[,,]", configured_category)
if category.strip()
}
return media_category.strip() in categories


def _split_file_uri(value: str) -> Tuple[str, str]:
"""
拆分 FileURI 字符串,保留原始路径用于安全校验。
Expand Down
72 changes: 72 additions & 0 deletions tests/test_directory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from pathlib import Path
from types import SimpleNamespace

import pytest

from app.helper.directory import DirectoryHelper
from app.schemas import TransferDirectoryConf


def _media(category: str):
"""构造目录匹配测试所需的媒体信息。"""
return SimpleNamespace(
type=SimpleNamespace(value="电视剧"),
category=category,
)


def _directory(media_category: str) -> TransferDirectoryConf:
"""构造启用自动整理的动漫目录配置。"""
return TransferDirectoryConf(
name="动漫",
priority=1,
storage="local",
download_path="/media/anime",
media_type="电视剧",
media_category=media_category,
monitor_type="monitor",
library_path="/media/link/anime",
library_storage="local",
)


@pytest.mark.parametrize("configured_category", ["日番", "日番,日韩剧", "日番,日韩剧", " 日番 , 日韩剧 "])
def test_get_dir_matches_media_category_list(monkeypatch, configured_category):
"""自动整理应匹配目录配置中逗号分隔的任一媒体类别。"""
directory = _directory(configured_category)
monkeypatch.setattr(DirectoryHelper, "get_dirs", staticmethod(lambda: [directory]))

matched = DirectoryHelper().get_dir(
media=_media("日番"),
storage="local",
src_path=Path("/media/anime/demo.mkv"),
)

assert matched == directory


def test_get_dir_rejects_unconfigured_media_category(monkeypatch):
"""自动整理不应匹配目录配置中不存在的媒体类别。"""
directory = _directory("日番,日韩剧")
monkeypatch.setattr(DirectoryHelper, "get_dirs", staticmethod(lambda: [directory]))

matched = DirectoryHelper().get_dir(
media=_media("欧美剧"),
storage="local",
src_path=Path("/media/anime/demo.mkv"),
)

assert matched is None


def test_get_download_dir_by_save_path_matches_media_category_list(monkeypatch):
"""精确保存根路径应继承逗号分隔的媒体类别规则。"""
directory = _directory("日番,日韩剧")
monkeypatch.setattr(DirectoryHelper, "get_download_dirs", lambda _self: [directory])

matched = DirectoryHelper().get_download_dir_by_save_path(
media=_media("日韩剧"),
save_path="/media/anime",
)

assert matched == directory