From dad1b5109ea74a6f44656e36c2e7124e12748a64 Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Mon, 25 May 2026 18:48:45 -0700 Subject: [PATCH] Add _build_library_tag_db_data helper Extract repeated DB tag payload construction into a new _build_library_tag_db_data(track_data, album_genres) helper and replace in multiple endpoints. The helper builds the metadata dict (title, artist_name, track_artist, album_title, year, genres, track/disc numbers, bpm, track_count, thumb_url) and populates artists_list by splitting track_artist on ';'. Added tests (tests/test_library_tag_payload.py) to verify artists_list creation, genre propagation, thumb_url selection, and fallback behavior when track_artist is missing. This reduces duplication and ensures consistent tag payloads across tag-preview, batch preview, and tag-writing flows. --- tests/test_library_tag_payload.py | 45 ++++++++++++++++++ web_server.py | 77 ++++++++++++------------------- 2 files changed, 75 insertions(+), 47 deletions(-) create mode 100644 tests/test_library_tag_payload.py diff --git a/tests/test_library_tag_payload.py b/tests/test_library_tag_payload.py new file mode 100644 index 00000000..f7b6d198 --- /dev/null +++ b/tests/test_library_tag_payload.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +from web_server import _build_library_tag_db_data + + +def test_library_tag_payload_preserves_track_artist_and_artists_list(): + payload = _build_library_tag_db_data( + { + 'title': 'Duet', + 'artist_name': 'Album Artist', + 'track_artist': 'Artist A; Artist B', + 'album_title': 'Compilation', + 'year': 2026, + 'track_number': 3, + 'disc_number': 1, + 'bpm': 124, + 'track_count': 12, + 'album_thumb_url': 'https://example.test/cover.jpg', + 'artist_thumb_url': 'https://example.test/artist.jpg', + }, + ['Electronic', 'Dance'], + ) + + assert payload['artist_name'] == 'Album Artist' + assert payload['track_artist'] == 'Artist A; Artist B' + assert payload['artists_list'] == ['Artist A', 'Artist B'] + assert payload['genres'] == ['Electronic', 'Dance'] + assert payload['thumb_url'] == 'https://example.test/cover.jpg' + + +def test_library_tag_payload_falls_back_without_track_artist(): + payload = _build_library_tag_db_data( + { + 'title': 'Solo', + 'artist_name': 'Solo Artist', + 'track_artist': None, + 'album_title': 'Solo Album', + 'artist_thumb_url': 'https://example.test/artist.jpg', + } + ) + + assert payload['track_artist'] is None + assert 'artists_list' not in payload + assert payload['artist_name'] == 'Solo Artist' + assert payload['thumb_url'] == 'https://example.test/artist.jpg' diff --git a/web_server.py b/web_server.py index 7458a46f..e4eea0c6 100644 --- a/web_server.py +++ b/web_server.py @@ -9025,6 +9025,32 @@ def batch_update_library_tracks(): # ── Write Tags to File endpoints ── +def _build_library_tag_db_data(track_data, album_genres=None): + """Build the metadata payload consumed by core.tag_writer.""" + album_genres = album_genres or [] + db_data = { + 'title': track_data.get('title'), + 'artist_name': track_data.get('artist_name'), + 'track_artist': track_data.get('track_artist'), + 'album_title': track_data.get('album_title'), + 'year': track_data.get('year'), + 'genres': album_genres, + 'track_number': track_data.get('track_number'), + 'disc_number': track_data.get('disc_number'), + 'bpm': track_data.get('bpm'), + 'track_count': track_data.get('track_count'), + 'thumb_url': track_data.get('album_thumb_url') or track_data.get('artist_thumb_url'), + } + + track_artist = track_data.get('track_artist') + if isinstance(track_artist, str) and ';' in track_artist: + artists_list = [name.strip() for name in track_artist.split(';') if name.strip()] + if artists_list: + db_data['artists_list'] = artists_list + + return db_data + + @app.route('/api/library/track//tag-preview', methods=['GET']) def get_track_tag_preview(track_id): """Read current file tags and compare against DB metadata for a single track.""" @@ -9072,19 +9098,7 @@ def get_track_tag_preview(track_id): album_genres = [g.strip() for g in track_data['album_genres'].split(',') if g.strip()] # Build DB metadata dict for comparison - db_data = { - 'title': track_data.get('title'), - 'artist_name': track_data.get('artist_name'), - 'track_artist': track_data.get('track_artist'), - 'album_title': track_data.get('album_title'), - 'year': track_data.get('year'), - 'genres': album_genres, - 'track_number': track_data.get('track_number'), - 'disc_number': track_data.get('disc_number'), - 'bpm': track_data.get('bpm'), - 'track_count': track_data.get('track_count'), - 'thumb_url': track_data.get('album_thumb_url') or track_data.get('artist_thumb_url'), - } + db_data = _build_library_tag_db_data(track_data, album_genres) diff = build_tag_diff(file_tags, db_data) has_changes = any(d['changed'] for d in diff) @@ -9166,18 +9180,7 @@ def get_batch_tag_preview(): except (ValueError, TypeError): album_genres = [g.strip() for g in track_data['album_genres'].split(',') if g.strip()] - db_data = { - 'title': track_data.get('title'), - 'artist_name': track_data.get('artist_name'), - 'album_title': track_data.get('album_title'), - 'year': track_data.get('year'), - 'genres': album_genres, - 'track_number': track_data.get('track_number'), - 'disc_number': track_data.get('disc_number'), - 'bpm': track_data.get('bpm'), - 'track_count': track_data.get('track_count'), - 'thumb_url': track_data.get('album_thumb_url') or track_data.get('artist_thumb_url'), - } + db_data = _build_library_tag_db_data(track_data, album_genres) diff = build_tag_diff(file_tags, db_data) has_changes = any(d['changed'] for d in diff) @@ -9249,17 +9252,7 @@ def write_track_tags(track_id): album_genres = [g.strip() for g in track_data['album_genres'].split(',') if g.strip()] # Build data for writer - db_data = { - 'title': track_data.get('title'), - 'artist_name': track_data.get('artist_name'), - 'album_title': track_data.get('album_title'), - 'year': track_data.get('year'), - 'genres': album_genres, - 'track_number': track_data.get('track_number'), - 'disc_number': track_data.get('disc_number'), - 'bpm': track_data.get('bpm'), - 'track_count': track_data.get('track_count'), - } + db_data = _build_library_tag_db_data(track_data, album_genres) # Resolve cover URL cover_url = None @@ -9408,17 +9401,7 @@ def write_tracks_tags_batch(): except (ValueError, TypeError): album_genres = [g.strip() for g in track_data['album_genres'].split(',') if g.strip()] - db_data = { - 'title': track_data.get('title'), - 'artist_name': track_data.get('artist_name'), - 'album_title': track_data.get('album_title'), - 'year': track_data.get('year'), - 'genres': album_genres, - 'track_number': track_data.get('track_number'), - 'disc_number': track_data.get('disc_number'), - 'bpm': track_data.get('bpm'), - 'track_count': track_data.get('track_count'), - } + db_data = _build_library_tag_db_data(track_data, album_genres) # Get pre-downloaded cover art for this track's album art_data = None