fix(monitor): 优先按目录配置识别音乐

This commit is contained in:
jxxghp
2026-08-09 21:19:43 +08:00
parent 393a4ca4e2
commit d03307b687
2 changed files with 82 additions and 1 deletions

View File

@@ -8,8 +8,10 @@ from app.chain.transfer import TransferChain
from app.core.cache import TTLCache
from app.core.config import settings
from app.db.transferhistory_oper import TransferHistoryOper
from app.helper.directory import DirectoryHelper
from app.log import logger
from app.schemas import FileItem
from app.schemas.types import MediaType
class TransferDispatcher:
@@ -97,6 +99,39 @@ class TransferDispatcher:
"""
return f"{storage}:{Path(event_path).as_posix()}"
@staticmethod
def _get_monitor_media_type(storage: str, event_path: Path) -> Optional[MediaType]:
"""
获取事件路径命中的目录监控媒体类型,嵌套配置优先使用最具体的根目录。
:param storage: 存储
:param event_path: 事件文件路径
:return: 配置的媒体类型,未配置或无匹配目录时返回 None
"""
matching_dirs = [
dir_info
for dir_info in DirectoryHelper().get_download_dirs()
if dir_info.monitor_type == "monitor"
and dir_info.storage == storage
and event_path.is_relative_to(Path(dir_info.download_path))
]
if not matching_dirs:
return None
dir_info = max(
matching_dirs,
key=lambda item: len(Path(item.download_path).parts),
)
if not dir_info.media_type:
return None
try:
return MediaType(dir_info.media_type)
except ValueError:
logger.warning(
f"目录监控 {dir_info.download_path} 配置了未知媒体类型:{dir_info.media_type}"
)
return None
def _register_pending(self, storage: str, event_path: Path, file_size: float = None):
"""
登记历史查询失败的文件待重试,重复失败累计次数,超限后放弃。
@@ -202,7 +237,11 @@ class TransferDispatcher:
basename=event_path.stem,
extension=event_path.suffix[1:],
size=file_size
)
),
mtype=self._get_monitor_media_type(
storage=storage,
event_path=event_path,
),
)
return True
except Exception as e:

View File

@@ -5,6 +5,8 @@ from watchfiles import Change
from app.monitor import DirectoryChangeEvent, LocalDirectoryWatcher, Monitor
from app.monitor.dispatcher import TransferDispatcher
from app.schemas import TransferDirectoryConf
from app.schemas.types import MediaType
class CallbackRecorder:
@@ -302,3 +304,43 @@ def test_handle_file_invokes_transfer_when_history_missing(monkeypatch):
assert fileitem.storage == "local"
assert fileitem.path == event_path.as_posix()
assert fileitem.size == 1024
def test_handle_file_prefers_music_type_from_monitor_directory(monkeypatch):
"""音乐目录监控触发整理时应透传音乐类型,避免音频按影视名称识别。"""
dispatcher = TransferDispatcher(all_exts=[".flac"], cache={})
event_path = Path("/downloads/music/album/track.flac")
directories = [
TransferDirectoryConf(
storage="local",
download_path="/downloads",
media_type=MediaType.MOVIE.value,
monitor_type="monitor",
),
TransferDirectoryConf(
storage="local",
download_path="/downloads/music",
media_type=MediaType.MUSIC.value,
monitor_type="monitor",
),
]
transfer_chain_instance = MagicMock()
monkeypatch.setattr(dispatcher, "_has_transfer_history", MagicMock(return_value=False))
monkeypatch.setattr(
"app.monitor.dispatcher.DirectoryHelper",
MagicMock(return_value=MagicMock(get_download_dirs=MagicMock(return_value=directories))),
)
monkeypatch.setattr(
"app.monitor.dispatcher.TransferChain",
MagicMock(return_value=transfer_chain_instance),
)
handled = dispatcher.handle_file(
storage="local",
event_path=event_path,
file_size=1024,
)
assert handled
assert transfer_chain_instance.do_transfer.call_args.kwargs["mtype"] == MediaType.MUSIC