mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-09-07 08:26:53 +08:00
Skip download dir selection for single matches
This commit is contained in:
+11
-2
@@ -2635,6 +2635,8 @@ class MediaInteractionChain(ChainBase):
|
|||||||
download_dirs = self._get_download_dirs(media_info)
|
download_dirs = self._get_download_dirs(media_info)
|
||||||
if not download_dirs:
|
if not download_dirs:
|
||||||
return False
|
return False
|
||||||
|
if len(download_dirs) == 1 and not self._is_auto_download_dir(download_dirs[0]):
|
||||||
|
return False
|
||||||
|
|
||||||
request.pending_torrent_page = request.page
|
request.pending_torrent_page = request.page
|
||||||
request.phase = "download-dir"
|
request.phase = "download-dir"
|
||||||
@@ -3252,6 +3254,11 @@ class MediaInteractionChain(ChainBase):
|
|||||||
"""
|
"""
|
||||||
获取可供消息交互选择的下载目录。
|
获取可供消息交互选择的下载目录。
|
||||||
"""
|
"""
|
||||||
|
dir_infos = [
|
||||||
|
dir_info
|
||||||
|
for dir_info in DirectoryHelper().get_download_dirs()
|
||||||
|
if dir_info.download_path
|
||||||
|
]
|
||||||
download_dirs = [
|
download_dirs = [
|
||||||
DownloadDirectory(
|
DownloadDirectory(
|
||||||
name=dir_info.name,
|
name=dir_info.name,
|
||||||
@@ -3265,11 +3272,13 @@ class MediaInteractionChain(ChainBase):
|
|||||||
media_type=dir_info.media_type,
|
media_type=dir_info.media_type,
|
||||||
media_category=dir_info.media_category,
|
media_category=dir_info.media_category,
|
||||||
)
|
)
|
||||||
for dir_info in DirectoryHelper().get_download_dirs()
|
for dir_info in dir_infos
|
||||||
if dir_info.download_path and cls._match_download_dir_media(dir_info, media_info)
|
if cls._match_download_dir_media(dir_info, media_info)
|
||||||
]
|
]
|
||||||
if not download_dirs:
|
if not download_dirs:
|
||||||
return []
|
return []
|
||||||
|
if len(download_dirs) == 1:
|
||||||
|
return download_dirs
|
||||||
return [cls._build_auto_download_dir(), *download_dirs]
|
return [cls._build_auto_download_dir(), *download_dirs]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|||||||
+131
-10
@@ -65,7 +65,7 @@ def _build_tv_context(title: str = "葬送的芙莉莲") -> Context:
|
|||||||
|
|
||||||
|
|
||||||
def _build_download_dirs() -> list[TransferDirectoryConf]:
|
def _build_download_dirs() -> list[TransferDirectoryConf]:
|
||||||
"""构造消息交互可选择的下载目录配置。"""
|
"""构造不同媒体类型各一个下载目录的配置。"""
|
||||||
return [
|
return [
|
||||||
TransferDirectoryConf(
|
TransferDirectoryConf(
|
||||||
name="电影下载",
|
name="电影下载",
|
||||||
@@ -85,6 +85,46 @@ def _build_download_dirs() -> list[TransferDirectoryConf]:
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _build_multiple_movie_download_dirs() -> list[TransferDirectoryConf]:
|
||||||
|
"""构造多个匹配电影类型的下载目录配置。"""
|
||||||
|
return [
|
||||||
|
TransferDirectoryConf(
|
||||||
|
name="电影下载",
|
||||||
|
storage="local",
|
||||||
|
download_path="/downloads/movies",
|
||||||
|
priority=1,
|
||||||
|
media_type=MediaType.MOVIE.value,
|
||||||
|
),
|
||||||
|
TransferDirectoryConf(
|
||||||
|
name="4K电影下载",
|
||||||
|
storage="local",
|
||||||
|
download_path="/downloads/uhd-movies",
|
||||||
|
priority=2,
|
||||||
|
media_type=MediaType.MOVIE.value,
|
||||||
|
),
|
||||||
|
TransferDirectoryConf(
|
||||||
|
name="动画下载",
|
||||||
|
storage="rclone",
|
||||||
|
download_path="/media/anime",
|
||||||
|
priority=3,
|
||||||
|
media_type=MediaType.TV.value,
|
||||||
|
media_category="动漫",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _build_single_download_dir() -> list[TransferDirectoryConf]:
|
||||||
|
"""构造只有一个下载目录的配置。"""
|
||||||
|
return [
|
||||||
|
TransferDirectoryConf(
|
||||||
|
name="默认下载",
|
||||||
|
storage="local",
|
||||||
|
download_path="/downloads",
|
||||||
|
priority=1,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_message_routes_text_reply_to_media_interaction_before_ai():
|
def test_message_routes_text_reply_to_media_interaction_before_ai():
|
||||||
"""已有传统媒体交互时,用户回复应优先交给传统交互处理。"""
|
"""已有传统媒体交互时,用户回复应优先交给传统交互处理。"""
|
||||||
chain = MessageChain()
|
chain = MessageChain()
|
||||||
@@ -295,7 +335,7 @@ def test_media_interaction_legacy_page_callback_updates_existing_request():
|
|||||||
|
|
||||||
|
|
||||||
def test_torrent_selection_prompts_download_dir_buttons_before_download():
|
def test_torrent_selection_prompts_download_dir_buttons_before_download():
|
||||||
"""支持按钮的渠道选择资源后,应先发送下载目录按钮而不是立即下载。"""
|
"""匹配当前媒体的目录有多个时,应先发送下载目录按钮而不是立即下载。"""
|
||||||
chain = MediaInteractionChain()
|
chain = MediaInteractionChain()
|
||||||
context = _build_context()
|
context = _build_context()
|
||||||
request = media_interaction_manager.create_or_replace(
|
request = media_interaction_manager.create_or_replace(
|
||||||
@@ -313,7 +353,7 @@ def test_torrent_selection_prompts_download_dir_buttons_before_download():
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"app.chain.message.DirectoryHelper.get_download_dirs",
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
return_value=_build_download_dirs(),
|
return_value=_build_multiple_movie_download_dirs(),
|
||||||
), patch.object(chain, "post_message") as post_message, patch(
|
), patch.object(chain, "post_message") as post_message, patch(
|
||||||
"app.chain.message.DownloadChain.download_single"
|
"app.chain.message.DownloadChain.download_single"
|
||||||
) as download_single:
|
) as download_single:
|
||||||
@@ -334,12 +374,93 @@ def test_torrent_selection_prompts_download_dir_buttons_before_download():
|
|||||||
assert "请选择下载目录" in notification.title
|
assert "请选择下载目录" in notification.title
|
||||||
assert "1. 自动匹配目录" in notification.text
|
assert "1. 自动匹配目录" in notification.text
|
||||||
assert "2. 电影下载 (/downloads/movies)" in notification.text
|
assert "2. 电影下载 (/downloads/movies)" in notification.text
|
||||||
|
assert "3. 4K电影下载 (/downloads/uhd-movies)" in notification.text
|
||||||
assert "动画下载" not in notification.text
|
assert "动画下载" not in notification.text
|
||||||
assert notification.buttons[0][0]["callback_data"] == f"media:{request.request_id}:download-dir:1"
|
assert notification.buttons[0][0]["callback_data"] == f"media:{request.request_id}:download-dir:1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_torrent_selection_skips_download_dir_when_only_one_dir_matches_media():
|
||||||
|
"""匹配当前媒体的目录只有一个时,应跳过目录选择并交给下载链自动匹配。"""
|
||||||
|
chain = MediaInteractionChain()
|
||||||
|
context = _build_context()
|
||||||
|
request = media_interaction_manager.create_or_replace(
|
||||||
|
user_id="10001",
|
||||||
|
channel=MessageChannel.Telegram,
|
||||||
|
source="telegram-test",
|
||||||
|
username="tester",
|
||||||
|
action="Search",
|
||||||
|
keyword="星际穿越",
|
||||||
|
title="星际穿越",
|
||||||
|
meta=_build_meta("星际穿越"),
|
||||||
|
items=[context],
|
||||||
|
)
|
||||||
|
request.phase = "torrent"
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
|
return_value=_build_download_dirs(),
|
||||||
|
), patch.object(chain, "post_message") as post_message, patch(
|
||||||
|
"app.chain.message.DownloadChain.download_single",
|
||||||
|
return_value="hash",
|
||||||
|
) as download_single:
|
||||||
|
handled = chain.handle_text_interaction(
|
||||||
|
channel=MessageChannel.Telegram,
|
||||||
|
source="telegram-test",
|
||||||
|
userid="10001",
|
||||||
|
username="tester",
|
||||||
|
text="1",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert handled
|
||||||
|
assert request.phase == "torrent"
|
||||||
|
post_message.assert_not_called()
|
||||||
|
download_single.assert_called_once()
|
||||||
|
assert download_single.call_args.args[0] is context
|
||||||
|
assert "save_path" not in download_single.call_args.kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def test_torrent_selection_skips_download_dir_when_user_has_single_dir():
|
||||||
|
"""用户只有一个下载目录时,也应跳过目录选择并交给下载链自动匹配。"""
|
||||||
|
chain = MediaInteractionChain()
|
||||||
|
context = _build_context()
|
||||||
|
request = media_interaction_manager.create_or_replace(
|
||||||
|
user_id="10001",
|
||||||
|
channel=MessageChannel.Telegram,
|
||||||
|
source="telegram-test",
|
||||||
|
username="tester",
|
||||||
|
action="Search",
|
||||||
|
keyword="星际穿越",
|
||||||
|
title="星际穿越",
|
||||||
|
meta=_build_meta("星际穿越"),
|
||||||
|
items=[context],
|
||||||
|
)
|
||||||
|
request.phase = "torrent"
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
|
return_value=_build_single_download_dir(),
|
||||||
|
), patch.object(chain, "post_message") as post_message, patch(
|
||||||
|
"app.chain.message.DownloadChain.download_single",
|
||||||
|
return_value="hash",
|
||||||
|
) as download_single:
|
||||||
|
handled = chain.handle_text_interaction(
|
||||||
|
channel=MessageChannel.Telegram,
|
||||||
|
source="telegram-test",
|
||||||
|
userid="10001",
|
||||||
|
username="tester",
|
||||||
|
text="1",
|
||||||
|
)
|
||||||
|
|
||||||
|
assert handled
|
||||||
|
assert request.phase == "torrent"
|
||||||
|
post_message.assert_not_called()
|
||||||
|
download_single.assert_called_once()
|
||||||
|
assert download_single.call_args.args[0] is context
|
||||||
|
assert "save_path" not in download_single.call_args.kwargs
|
||||||
|
|
||||||
|
|
||||||
def test_torrent_selection_prompts_text_download_dir_for_plain_channel():
|
def test_torrent_selection_prompts_text_download_dir_for_plain_channel():
|
||||||
"""不支持按钮的渠道选择资源后,应提示用户回复数字选择下载目录。"""
|
"""不支持按钮的渠道在多个匹配目录时,应提示用户回复数字选择下载目录。"""
|
||||||
chain = MediaInteractionChain()
|
chain = MediaInteractionChain()
|
||||||
context = _build_context()
|
context = _build_context()
|
||||||
request = media_interaction_manager.create_or_replace(
|
request = media_interaction_manager.create_or_replace(
|
||||||
@@ -357,7 +478,7 @@ def test_torrent_selection_prompts_text_download_dir_for_plain_channel():
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"app.chain.message.DirectoryHelper.get_download_dirs",
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
return_value=_build_download_dirs(),
|
return_value=_build_multiple_movie_download_dirs(),
|
||||||
), patch.object(chain, "post_message") as post_message:
|
), patch.object(chain, "post_message") as post_message:
|
||||||
handled = chain.handle_text_interaction(
|
handled = chain.handle_text_interaction(
|
||||||
channel=MessageChannel.Wechat,
|
channel=MessageChannel.Wechat,
|
||||||
@@ -374,6 +495,7 @@ def test_torrent_selection_prompts_text_download_dir_for_plain_channel():
|
|||||||
assert notification.buttons is None
|
assert notification.buttons is None
|
||||||
assert "1. 自动匹配目录" in notification.text
|
assert "1. 自动匹配目录" in notification.text
|
||||||
assert "2. 电影下载 (/downloads/movies)" in notification.text
|
assert "2. 电影下载 (/downloads/movies)" in notification.text
|
||||||
|
assert "3. 4K电影下载 (/downloads/uhd-movies)" in notification.text
|
||||||
assert "动画下载" not in notification.text
|
assert "动画下载" not in notification.text
|
||||||
|
|
||||||
|
|
||||||
@@ -398,7 +520,7 @@ def test_download_dir_callback_runs_pending_single_download_without_save_path_fo
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"app.chain.message.DirectoryHelper.get_download_dirs",
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
return_value=_build_download_dirs(),
|
return_value=_build_multiple_movie_download_dirs(),
|
||||||
), patch(
|
), patch(
|
||||||
"app.chain.message.DownloadChain.download_single",
|
"app.chain.message.DownloadChain.download_single",
|
||||||
return_value="hash",
|
return_value="hash",
|
||||||
@@ -440,7 +562,7 @@ def test_download_dir_callback_runs_pending_single_download_with_save_path():
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"app.chain.message.DirectoryHelper.get_download_dirs",
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
return_value=_build_download_dirs(),
|
return_value=_build_multiple_movie_download_dirs(),
|
||||||
), patch(
|
), patch(
|
||||||
"app.chain.message.DownloadChain.download_single",
|
"app.chain.message.DownloadChain.download_single",
|
||||||
return_value="hash",
|
return_value="hash",
|
||||||
@@ -482,7 +604,7 @@ def test_download_dir_text_reply_runs_pending_single_download_without_save_path(
|
|||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"app.chain.message.DirectoryHelper.get_download_dirs",
|
"app.chain.message.DirectoryHelper.get_download_dirs",
|
||||||
return_value=_build_download_dirs(),
|
return_value=_build_multiple_movie_download_dirs(),
|
||||||
), patch(
|
), patch(
|
||||||
"app.chain.message.DownloadChain.download_single",
|
"app.chain.message.DownloadChain.download_single",
|
||||||
return_value="hash",
|
return_value="hash",
|
||||||
@@ -515,7 +637,6 @@ def test_get_download_dirs_keeps_matching_tv_category_dir():
|
|||||||
download_dirs = chain._get_download_dirs(context.media_info)
|
download_dirs = chain._get_download_dirs(context.media_info)
|
||||||
|
|
||||||
assert [download_dir.name for download_dir in download_dirs] == [
|
assert [download_dir.name for download_dir in download_dirs] == [
|
||||||
"自动匹配目录",
|
|
||||||
"动画下载",
|
"动画下载",
|
||||||
]
|
]
|
||||||
assert download_dirs[1].save_path == "rclone:/media/anime"
|
assert download_dirs[0].save_path == "rclone:/media/anime"
|
||||||
|
|||||||
Reference in New Issue
Block a user