From 25db066345f5a5485edbc72a1ad8859c7e159dbe Mon Sep 17 00:00:00 2001 From: Sumner Evans Date: Thu, 21 May 2020 12:20:21 -0600 Subject: [PATCH] Bug fixes for getting similar artists working --- sublime/adapters/filesystem/models.py | 7 ++++++- sublime/adapters/subsonic/api_objects.py | 18 +++++++++++------- sublime/ui/albums.py | 2 ++ sublime/ui/app_styles.css | 1 + sublime/ui/artists.py | 15 +++++++++------ sublime/ui/player_controls.py | 2 +- sublime/ui/util.py | 8 ++++++-- tests/adapter_tests/subsonic_adapter_tests.py | 8 +++++++- 8 files changed, 43 insertions(+), 18 deletions(-) diff --git a/sublime/adapters/filesystem/models.py b/sublime/adapters/filesystem/models.py index 524c303..fc26df2 100644 --- a/sublime/adapters/filesystem/models.py +++ b/sublime/adapters/filesystem/models.py @@ -73,7 +73,12 @@ class Artist(BaseModel): @property def similar_artists(self) -> Query: - return SimilarArtist.select().where(SimilarArtist.artist == self.id) + return ( + Artist.select() + .join(SimilarArtist, on=(SimilarArtist.similar_artist == Artist.id)) + .where(SimilarArtist.artist == self.id) + .order_by(SimilarArtist.order) + ) class SimilarArtist(BaseModel): diff --git a/sublime/adapters/subsonic/api_objects.py b/sublime/adapters/subsonic/api_objects.py index 7f8bc83..902f02b 100644 --- a/sublime/adapters/subsonic/api_objects.py +++ b/sublime/adapters/subsonic/api_objects.py @@ -94,9 +94,7 @@ class ArtistAndArtistInfo(SublimeAPI.Artist): starred: Optional[datetime] = None # Artist Info - similar_artists: List["ArtistAndArtistInfo"] = field( - default_factory=list, metadata=config(field_name="similar_artist") - ) + similar_artists: List["ArtistAndArtistInfo"] = field(default_factory=list) biography: Optional[str] = None music_brainz_id: Optional[str] = None last_fm_url: Optional[str] = None @@ -112,15 +110,21 @@ class ArtistAndArtistInfo(SublimeAPI.Artist): def augment_with_artist_info(self, artist_info: Optional["ArtistInfo"]): if artist_info: - for k, v in asdict(artist_info).items(): - if v: - setattr(self, k, v) + self.similar_artists = artist_info.similar_artists + self.biography = artist_info.biography + self.last_fm_url = artist_info.last_fm_url + self.artist_image_url = ( + artist_info.artist_image_url or self.artist_image_url + ) + self.music_brainz_id = artist_info.music_brainz_id @dataclass_json(letter_case=LetterCase.CAMEL) @dataclass class ArtistInfo: - similar_artist: List[ArtistAndArtistInfo] = field(default_factory=list) + similar_artists: List[ArtistAndArtistInfo] = field( + default_factory=list, metadata=config(field_name="similarArtist") + ) biography: Optional[str] = None last_fm_url: Optional[str] = None artist_image_url: Optional[str] = field( diff --git a/sublime/ui/albums.py b/sublime/ui/albums.py index 2f85ebf..4a9c653 100644 --- a/sublime/ui/albums.py +++ b/sublime/ui/albums.py @@ -1,5 +1,6 @@ import datetime import itertools +import logging import math from typing import Any, Callable, cast, Iterable, List, Optional, Tuple @@ -674,6 +675,7 @@ class AlbumsGrid(Gtk.Overlay): f"Getting albums by {self.current_query.type} failed due to the " f"following error\n\n{e}" ) + logging.exception("Failed to retrieve albums") self.error_dialog.run() self.error_dialog.destroy() self.error_dialog = None diff --git a/sublime/ui/app_styles.css b/sublime/ui/app_styles.css index d8cb2d7..59afc39 100644 --- a/sublime/ui/app_styles.css +++ b/sublime/ui/app_styles.css @@ -91,6 +91,7 @@ #player-controls-album-artwork { min-height: 70px; min-width: 70px; + margin-right: 10px; } #player-controls-bar #play-button { diff --git a/sublime/ui/artists.py b/sublime/ui/artists.py index 22049c2..2a6b49f 100644 --- a/sublime/ui/artists.py +++ b/sublime/ui/artists.py @@ -242,7 +242,7 @@ class ArtistDetailPanel(Gtk.Box): self.play_shuffle_buttons.pack_start(shuffle_button, False, False, 5) artist_details_box.add(self.play_shuffle_buttons) - self.big_info_panel.pack_start(artist_details_box, True, True, 10) + self.big_info_panel.pack_start(artist_details_box, True, True, 0) # Action buttons action_buttons_container = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) @@ -289,10 +289,12 @@ class ArtistDetailPanel(Gtk.Box): def update(self, app_config: AppConfiguration): self.artist_id = app_config.state.selected_artist_id if app_config.state.selected_artist_id is None: - self.hide() + self.big_info_panel.hide() + self.album_list_scrolledwindow.hide() else: self.update_order_token += 1 - self.show() + self.big_info_panel.show() + self.album_list_scrolledwindow.show() self.update_artist_view( app_config.state.selected_artist_id, app_config=app_config, @@ -328,6 +330,7 @@ class ArtistDetailPanel(Gtk.Box): if self.artist_details_expanded: self.show_all() + self.artist_name.get_style_context().remove_class("collapsed") self.artist_artwork.set_image_size(300) self.artist_indicator.set_text("ARTIST") self.artist_stats.set_markup(self.format_stats(artist)) @@ -339,13 +342,13 @@ class ArtistDetailPanel(Gtk.Box): for c in self.similar_artists_button_box.get_children(): self.similar_artists_button_box.remove(c) - for artist in (artist.similar_artists or [])[:5]: + for similar_artist in (artist.similar_artists or [])[:5]: self.similar_artists_button_box.add( Gtk.LinkButton( - label=artist.name, + label=similar_artist.name, name="similar-artist-button", action_name="app.go-to-artist", - action_target=GLib.Variant("s", artist.id), + action_target=GLib.Variant("s", similar_artist.id), ) ) self.similar_artists_scrolledwindow.show_all() diff --git a/sublime/ui/player_controls.py b/sublime/ui/player_controls.py index 4aa82fb..0f6876f 100644 --- a/sublime/ui/player_controls.py +++ b/sublime/ui/player_controls.py @@ -490,7 +490,7 @@ class PlayerControls(Gtk.ActionBar): self.album_art = SpinnerImage( image_name="player-controls-album-artwork", image_size=70, ) - box.pack_start(self.album_art, False, False, 5) + box.pack_start(self.album_art, False, False, 0) details_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) details_box.pack_start(Gtk.Box(), True, True, 0) diff --git a/sublime/ui/util.py b/sublime/ui/util.py index aeab519..e11c4ef 100644 --- a/sublime/ui/util.py +++ b/sublime/ui/util.py @@ -246,10 +246,14 @@ def show_song_popover( albums, artists, parents = set(), set(), set() for song in songs: - albums.add(album.id if (album := song.album) else None) - artists.add(artist.id if (artist := song.artist) else None) parents.add(parent_id if (parent_id := song.parent_id) else None) + if (al := song.album) and (id_ := al.id) and not id_.startswith("invalid:"): + albums.add(id_) + + if (a := song.artist) and (id_ := a.id) and not id_.startswith("invalid:"): + artists.add(id_) + if len(albums) == 1 and list(albums)[0] is not None: album_value = GLib.Variant("s", list(albums)[0]) go_to_album_button.set_action_target_value(album_value) diff --git a/tests/adapter_tests/subsonic_adapter_tests.py b/tests/adapter_tests/subsonic_adapter_tests.py index b4a716b..9cd9ef1 100644 --- a/tests/adapter_tests/subsonic_adapter_tests.py +++ b/tests/adapter_tests/subsonic_adapter_tests.py @@ -358,10 +358,16 @@ def test_get_artist(adapter: SubsonicAdapter): artist = adapter.get_artist("3") assert artist.album_count == 1 assert artist.albums and len(artist.albums) == 1 + assert ("3", "Kane Brown") == (artist.albums[0].id, artist.albums[0].name) assert artist.artist_image_url == "ar-3" assert artist.biography and len(artist.biography) > 0 assert artist.name == "Kane Brown" - assert ("3", "Kane Brown") == (artist.albums[0].id, artist.albums[0].name) + assert artist.similar_artists + assert len(artist.similar_artists) == 20 + assert (first_similar := artist.similar_artists[0]) + assert first_similar + assert first_similar.name == 'Luke Combs' + assert first_similar.artist_image_url == 'ar-158' def test_get_artist_with_good_image_url(adapter: SubsonicAdapter):