Video automations: Clean Completed Downloads twin (phase 3)
Same pattern as phase 2: video_clean_completed_downloads action (scope='video' block + registry), reuses the shared auto_clean_completed_downloads handler, and an owned_by='video' system automation on the music cadence (every 5 min). Music copy untouched. Seam tests for scope isolation, single video-owned seed, and shared-handler reuse; EXPECTED_ACTION_NAMES updated.
This commit is contained in:
parent
3ef0990ffc
commit
a6b2737a5c
5 changed files with 47 additions and 7 deletions
|
|
@ -272,6 +272,8 @@ ACTIONS: list[dict] = [
|
|||
# them on the video builder only; the music blocks above are untouched.
|
||||
{"type": "video_clean_search_history", "label": "Clean Search History", "icon": "trash-2", "scope": "video",
|
||||
"description": "Remove old searches from Soulseek", "available": True},
|
||||
{"type": "video_clean_completed_downloads", "label": "Clean Completed Downloads", "icon": "check-square", "scope": "video",
|
||||
"description": "Clear completed downloads and empty directories", "available": True},
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,10 @@ def register_all(deps: AutomationDeps) -> None:
|
|||
'video_clean_search_history',
|
||||
lambda config: auto_clean_search_history(config, deps),
|
||||
)
|
||||
engine.register_action_handler(
|
||||
'video_clean_completed_downloads',
|
||||
lambda config: auto_clean_completed_downloads(config, deps),
|
||||
)
|
||||
engine.register_action_handler(
|
||||
'clean_completed_downloads',
|
||||
lambda config: auto_clean_completed_downloads(config, deps),
|
||||
|
|
|
|||
|
|
@ -193,6 +193,14 @@ SYSTEM_AUTOMATIONS = [
|
|||
'initial_delay': 600,
|
||||
'owned_by': 'video',
|
||||
},
|
||||
{
|
||||
'name': 'Clean Completed Downloads',
|
||||
'trigger_type': 'schedule',
|
||||
'trigger_config': {'interval': 5, 'unit': 'minutes'},
|
||||
'action_type': 'video_clean_completed_downloads',
|
||||
'initial_delay': 300,
|
||||
'owned_by': 'video',
|
||||
},
|
||||
# Video twin of music's 'Auto-Deep Scan Library', split into TWO because Movies
|
||||
# and TV are independent libraries — a TV scan never pulls in new movies and
|
||||
# vice-versa. Fixed weekly deep scan (re-read + prune removed) at 02:00 server-
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ EXPECTED_ACTION_NAMES = frozenset({
|
|||
'video_update_database',
|
||||
'video_add_airing_episodes',
|
||||
'video_clean_search_history',
|
||||
'video_clean_completed_downloads',
|
||||
})
|
||||
|
||||
# Action names that MUST register a guard (duplicate-run prevention).
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ def test_video_clean_search_history_seeds_one_video_owned_system_row():
|
|||
assert row["trigger_config"] == {"interval": 1, "unit": "hours"}
|
||||
|
||||
|
||||
def test_video_clean_search_history_reuses_the_music_handler():
|
||||
# Registered to the SAME handler function as the music action (identical behaviour).
|
||||
def _registered_handlers():
|
||||
from core.automation.handlers import register_all
|
||||
|
||||
class _Eng:
|
||||
|
|
@ -60,10 +59,36 @@ def test_video_clean_search_history_reuses_the_music_handler():
|
|||
def register_progress_callbacks(self, *a, **k):
|
||||
pass
|
||||
|
||||
import core.automation.handlers.registration as reg
|
||||
eng = _Eng()
|
||||
# Build minimal deps via the test helper the registration suite uses.
|
||||
from tests.automation.test_handler_registration import _build_deps
|
||||
eng = _Eng()
|
||||
register_all(_build_deps(eng))
|
||||
assert "video_clean_search_history" in eng.handlers
|
||||
assert "clean_search_history" in eng.handlers
|
||||
return eng.handlers
|
||||
|
||||
|
||||
def test_video_clean_search_history_reuses_the_music_handler():
|
||||
# Registered to the SAME handler function as the music action (identical behaviour).
|
||||
handlers = _registered_handlers()
|
||||
assert "video_clean_search_history" in handlers
|
||||
assert "clean_search_history" in handlers
|
||||
|
||||
|
||||
# ── Phase 3: Clean Completed Downloads ──────────────────────────────────────
|
||||
|
||||
def test_video_clean_completed_downloads_is_video_scoped_only():
|
||||
assert "video_clean_completed_downloads" in _action_types("video")
|
||||
assert "video_clean_completed_downloads" not in _action_types("music")
|
||||
# music original untouched
|
||||
assert "clean_completed_downloads" in _action_types("music")
|
||||
assert "clean_completed_downloads" not in _action_types("video")
|
||||
|
||||
|
||||
def test_video_clean_completed_downloads_seeds_one_video_owned_system_row():
|
||||
rows = _system_by_action("video_clean_completed_downloads")
|
||||
assert len(rows) == 1 and rows[0]["owned_by"] == "video"
|
||||
assert rows[0]["trigger_config"] == {"interval": 5, "unit": "minutes"}
|
||||
|
||||
|
||||
def test_video_clean_completed_downloads_reuses_the_music_handler():
|
||||
handlers = _registered_handlers()
|
||||
assert "video_clean_completed_downloads" in handlers
|
||||
assert "clean_completed_downloads" in handlers
|
||||
|
|
|
|||
Loading…
Reference in a new issue