Dashboard detail, library filtering/pagination, simplified playlist times,
job descriptions Dashboard: format breakdown (FLAC/MP3/etc. counts), approximate library size (bitrate*length/8, same approximation `beet stats` itself uses -- verified to match its "100.5 GiB" output exactly against the real library), and a credential auth-state summary per scope (configured y/n plus, for Bandcamp, cookie expiry parsed locally from the stored cookie jar -- deliberately not a live network probe like pipeline-status.sh's Qobuz check, since this renders on every dashboard load). Library: was one unfiltered page dumping all 4072 tracks. Added search (artist/title/album), playlist and format filter dropdowns, and real SQL-level pagination (LIMIT/OFFSET, not fetch-everything-then-slice). beets_service gained count_items()/distinct_formats() to support this. Playlists: cron_expr is still the stored/scheduled representation, but the UI now shows and edits a plain daily time picker instead of raw cron syntax -- every playlist schedule today is a simple daily HH:MM anyway. playlist_service.cron_to_time()/time_to_cron() convert at the router boundary; verified round-trip against all real playlist cron values. Jobs: each maintenance job now shows a short one-line description of what it actually does (MAINTENANCE_JOB_DESCRIPTIONS), and "next run" is formatted consistently with playlists' time style (HH:MM, with a day qualifier for non-today runs -- maintenance jobs can be weekly/monthly, unlike playlists' plain daily schedule). Verified end-to-end against the real production data (4072 tracks, 100.5 GiB, real credentials): stats/format-breakdown/search/pagination all correct, all 7 credential scopes report configured with Bandcamp's real cookie expiry (325 days), and a full authenticated page-render sweep (dashboard, library with every filter combination, playlist detail, jobs) all returned 200 with no template errors.
This commit is contained in:
@@ -153,6 +153,31 @@ MAINTENANCE_JOBS: dict[str, tuple[dict, callable]] = {
|
||||
),
|
||||
}
|
||||
|
||||
# One short line per job for the /jobs page -- what it actually does, not
|
||||
# just its key. Kept separate from MAINTENANCE_JOBS so the schedule/function
|
||||
# mapping above stays easy to scan.
|
||||
MAINTENANCE_JOB_DESCRIPTIONS: dict[str, str] = {
|
||||
"maintenance:sync_bandcamp": "Pull new Bandcamp purchases and import them.",
|
||||
"maintenance:normalize_casing": "Fix artist-name casing to match your canonical list.",
|
||||
"maintenance:dedup": "Scan for duplicate tracks (dry-run only; confirm deletes in Dedup).",
|
||||
"maintenance:gen_djmix_playlist": "Rebuild the DJ-mix M3U from configured albums.",
|
||||
"maintenance:gen_vgm_playlist": "Rebuild the video-game-soundtrack M3U.",
|
||||
"maintenance:navidrome_scan": "Trigger a Navidrome library rescan (share-health gated).",
|
||||
"maintenance:export_laptop_playlists": "Export dj-* Navidrome playlists for the laptop.",
|
||||
"maintenance:enrich_buy_url": "Look up buy links for tracks without one yet.",
|
||||
"maintenance:build_fingerprint_index": "Refresh the acoustic fingerprint index.",
|
||||
"maintenance:pipeline_status_report": "Write the daily health snapshot / Telegram digest.",
|
||||
"maintenance:log_rotation": "Delete job logs older than 30 days.",
|
||||
"maintenance:strip_mb_tags": "Strip stale MusicBrainz tags that fragment Navidrome albums.",
|
||||
"maintenance:strip_watermark_art": "Remove Soulseek-uploader watermark cover art.",
|
||||
"maintenance:scrub_watermark_text": "Remove Soulseek-uploader watermark text frames.",
|
||||
"maintenance:clean_sldl_index": "Prune stale entries from each playlist's download index.",
|
||||
"maintenance:clear_bad_genres": "Blank malformed/junk GENRE tags before Spotify refill.",
|
||||
"maintenance:spotify_genre": "Refill GENRE tags from Spotify per-artist data.",
|
||||
"maintenance:beets_update_sync": "Sync the beets DB to on-disk tag changes.",
|
||||
"maintenance:upgrade_mp3_to_flac": "Look for FLAC replacements for MP3 tracks (monthly).",
|
||||
}
|
||||
|
||||
|
||||
# Module-level singleton so other services (playlist_service, future
|
||||
# routers) can reach the live scheduler without main.py threading it through
|
||||
|
||||
Reference in New Issue
Block a user