From a30a70fafd878ce89b9691cd9a17286befda2b2d Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Fri, 26 Jun 2026 11:51:29 -0700 Subject: [PATCH] automations page: friendly labels + icons for the video maintenance actions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the video-prefixed maintenance actions (clean_search_history, clean_completed_downloads, full_cleanup, backup_database) + the new refresh_airing_schedules weren't in the action label/icon maps, so they fell back to the gear + raw action_type ('โš™๏ธ video_full_cleanup'). added all five to both maps (๐Ÿ—“๏ธ/๐Ÿ—‘๏ธ/โœ…/๐Ÿงน/๐Ÿ’พ, mirroring the music side). regression test asserts every seeded video automation resolves a label AND an icon, so this can't recur. --- tests/test_video_automations_builder.py | 10 ++++++++++ webui/static/stats-automations.js | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/tests/test_video_automations_builder.py b/tests/test_video_automations_builder.py index b91b7742..e059c26f 100644 --- a/tests/test_video_automations_builder.py +++ b/tests/test_video_automations_builder.py @@ -110,6 +110,16 @@ def test_video_automations_poll_does_not_rebuild_when_unchanged(): assert 'var sig = JSON.stringify(' in _VAUTO +def test_every_video_automation_has_a_friendly_label_and_icon(): + # regression: a video action missing from the label/icon maps falls back to the gear + + # raw action_type ("โš™๏ธ video_clean_search_history") โ€” inconsistent. Every seeded video + # automation must have an entry in BOTH maps in stats-automations.js. + import core.automation_engine as ae + types = {a.get("action_type") for a in ae.SYSTEM_AUTOMATIONS if a.get("owned_by") == "video"} + missing = [t for t in types if _STATS.count(t + ":") < 2] # icon map + label map + assert not missing, "video actions missing a label/icon: " + ", ".join(sorted(missing)) + + def test_video_system_automations_are_sorted_by_pipeline_order(): # The API returns newest-created-first (jumbled); the page re-sorts by an # explicit order so it reads scans โ†’ processors โ†’ library โ†’ maintenance. diff --git a/webui/static/stats-automations.js b/webui/static/stats-automations.js index cbf5e3c9..63d39d95 100644 --- a/webui/static/stats-automations.js +++ b/webui/static/stats-automations.js @@ -1780,6 +1780,9 @@ const _autoIcons = { video_scan_watchlist_playlists: '\uD83C\uDFB5', video_process_movie_wishlist: '\uD83C\uDFAC', video_process_episode_wishlist: '\uD83D\uDCFA', video_process_youtube_wishlist: '\u2B07\uFE0F', + video_refresh_airing_schedules: '\uD83D\uDDD3\uFE0F', + video_clean_search_history: '\uD83D\uDDD1\uFE0F', video_clean_completed_downloads: '\u2705', + video_full_cleanup: '\uD83E\uDDF9', video_backup_database: '\uD83D\uDCBE', }; // --- Inspiration Templates --- @@ -3380,6 +3383,10 @@ function _autoFormatAction(type) { video_process_movie_wishlist: 'Process Movie Wishlist', video_process_episode_wishlist: 'Process Episode Wishlist', video_process_youtube_wishlist: 'Process YouTube Wishlist', + video_refresh_airing_schedules: 'Refresh Airing Schedules', + video_clean_search_history: 'Clean Search History', + video_clean_completed_downloads: 'Clean Completed Downloads', + video_full_cleanup: 'Full Cleanup', video_backup_database: 'Backup Database', }; return labels[type] || type || 'Unknown'; }