Got the albums showing
This commit is contained in:
@@ -19,6 +19,7 @@ from libremsonic.server.api_objects import (
|
||||
Child,
|
||||
ArtistID3,
|
||||
ArtistWithAlbumsID3,
|
||||
AlbumWithSongsID3,
|
||||
)
|
||||
|
||||
|
||||
@@ -61,14 +62,20 @@ class CacheManager(metaclass=Singleton):
|
||||
class __CacheManagerInternal:
|
||||
# NOTE: you need to add custom load/store logic for everything you add
|
||||
# here!
|
||||
server: Server
|
||||
playlists: Optional[List[Playlist]] = None
|
||||
artists: Optional[List[ArtistID3]] = None
|
||||
albums: Optional[List[Child]] = None
|
||||
|
||||
playlist_details: Dict[int, PlaylistWithSongs] = {}
|
||||
arist_details: Dict[int, ArtistWithAlbumsID3] = {}
|
||||
permanently_cached_paths: Set[str] = set()
|
||||
artist_details: Dict[int, ArtistWithAlbumsID3] = {}
|
||||
album_details: Dict[int, AlbumWithSongsID3]
|
||||
song_details: Dict[int, Child] = {}
|
||||
|
||||
permanently_cached_paths: Set[str] = set()
|
||||
|
||||
# The server instance.
|
||||
server: Server
|
||||
|
||||
# Thread lock for preventing threads from overriding the state while
|
||||
# it's being saved.
|
||||
cache_lock = threading.Lock()
|
||||
@@ -113,6 +120,9 @@ class CacheManager(metaclass=Singleton):
|
||||
self.artists = [
|
||||
ArtistID3.from_json(a) for a in meta_json.get('artists') or []
|
||||
]
|
||||
self.albums = [
|
||||
Child.from_json(a) for a in meta_json.get('albums') or []
|
||||
]
|
||||
self.playlist_details = {
|
||||
id: PlaylistWithSongs.from_json(v)
|
||||
for id, v in (meta_json.get('playlist_details') or {}).items()
|
||||
@@ -121,6 +131,10 @@ class CacheManager(metaclass=Singleton):
|
||||
id: ArtistWithAlbumsID3.from_json(a)
|
||||
for id, a in (meta_json.get('artist_details') or {}).items()
|
||||
}
|
||||
self.album_details = {
|
||||
id: AlbumWithSongsID3.from_json(a)
|
||||
for id, a in (meta_json.get('album_details') or {}).items()
|
||||
}
|
||||
self.song_details = {
|
||||
id: Child.from_json(v)
|
||||
for id, v in (meta_json.get('song_details') or {}).items()
|
||||
@@ -136,8 +150,10 @@ class CacheManager(metaclass=Singleton):
|
||||
cache_info = dict(
|
||||
playlists=self.playlists,
|
||||
artists=self.artists,
|
||||
albums=self.albums,
|
||||
playlist_details=self.playlist_details,
|
||||
artist_details=self.artist_details,
|
||||
album_details=self.album_details,
|
||||
song_details=self.song_details,
|
||||
permanently_cached_paths=list(
|
||||
self.permanently_cached_paths),
|
||||
@@ -187,7 +203,7 @@ class CacheManager(metaclass=Singleton):
|
||||
shutil.move(download_path, abs_path)
|
||||
|
||||
with self.download_set_lock:
|
||||
self.current_downloads.remove(abs_path)
|
||||
self.current_downloads.discard(abs_path)
|
||||
|
||||
return str(abs_path)
|
||||
|
||||
@@ -271,6 +287,26 @@ class CacheManager(metaclass=Singleton):
|
||||
|
||||
return CacheManager.executor.submit(do_get_artists)
|
||||
|
||||
def get_albums(
|
||||
self,
|
||||
type_: str,
|
||||
before_download: Callable[[], None] = lambda: None,
|
||||
force: bool = False,
|
||||
) -> Future:
|
||||
def do_get_albums() -> List[Child]:
|
||||
if not self.albums or force:
|
||||
before_download()
|
||||
albums = self.server.get_album_list(type_)
|
||||
|
||||
with self.cache_lock:
|
||||
self.albums = albums.album
|
||||
|
||||
self.save_cache_info()
|
||||
|
||||
return self.albums
|
||||
|
||||
return CacheManager.executor.submit(do_get_albums)
|
||||
|
||||
def batch_download_songs(
|
||||
self,
|
||||
song_ids: List[int],
|
||||
|
@@ -1,10 +1,14 @@
|
||||
import gi
|
||||
import sys
|
||||
from typing import List
|
||||
|
||||
gi.require_version('Gtk', '3.0')
|
||||
from gi.repository import Gio, Gtk, GObject
|
||||
from gi.repository import Gio, Gtk, GObject, Pango
|
||||
|
||||
from libremsonic.state_manager import ApplicationState
|
||||
from libremsonic.cache_manager import CacheManager
|
||||
from libremsonic.ui import util
|
||||
|
||||
from libremsonic.server.api_objects import Child
|
||||
|
||||
|
||||
class AlbumsPanel(Gtk.ScrolledWindow):
|
||||
@@ -25,6 +29,13 @@ class AlbumsPanel(Gtk.ScrolledWindow):
|
||||
self.child.update(state)
|
||||
|
||||
|
||||
class AlbumModel(GObject.Object):
|
||||
def __init__(self, title, cover_art):
|
||||
self.title = title
|
||||
self.cover_art = cover_art
|
||||
super().__init__()
|
||||
|
||||
|
||||
class AlbumsGrid(Gtk.FlowBox):
|
||||
"""Defines the albums panel."""
|
||||
|
||||
@@ -40,8 +51,59 @@ class AlbumsGrid(Gtk.FlowBox):
|
||||
homogeneous=True,
|
||||
valign=Gtk.Align.START,
|
||||
halign=Gtk.Align.CENTER,
|
||||
selection_mode=Gtk.SelectionMode.NONE,
|
||||
selection_mode=Gtk.SelectionMode.BROWSE,
|
||||
)
|
||||
|
||||
self.albums_model = Gio.ListStore()
|
||||
self.bind_model(self.albums_model, self.create_album_widget)
|
||||
|
||||
def update(self, state: ApplicationState):
|
||||
pass
|
||||
self.update_grid('random')
|
||||
|
||||
@util.async_callback(
|
||||
lambda *a, **k: CacheManager.get_albums(*a, **k),
|
||||
before_download=lambda self: print('ohea'),
|
||||
on_failure=lambda self, e: print('fail', e),
|
||||
)
|
||||
def update_grid(self, albums: List[Child]):
|
||||
# TODO do the diff thing eventually?
|
||||
self.albums_model.remove_all()
|
||||
for album in albums:
|
||||
self.albums_model.append(AlbumModel(album.title, album.coverArt))
|
||||
|
||||
|
||||
def create_album_widget(self, item):
|
||||
album_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
artwork_overlay = Gtk.Overlay()
|
||||
album_artwork = Gtk.Image(name='album-artwork')
|
||||
artwork_overlay.add(album_artwork)
|
||||
|
||||
artwork_spinner = Gtk.Spinner(name='album-artwork-spinner',
|
||||
active=False,
|
||||
halign=Gtk.Align.CENTER,
|
||||
valign=Gtk.Align.CENTER)
|
||||
artwork_overlay.add_overlay(artwork_spinner)
|
||||
album_box.pack_start(artwork_overlay, False, False, 0)
|
||||
|
||||
def artwork_downloaded(f):
|
||||
filename = f.result()
|
||||
album_artwork.set_from_file(filename)
|
||||
artwork_spinner.active = False
|
||||
|
||||
def before_download():
|
||||
artwork_spinner.active = True
|
||||
|
||||
cover_art_filename_future = CacheManager.get_cover_art_filename(
|
||||
item.cover_art, before_download=before_download)
|
||||
cover_art_filename_future.add_done_callback(artwork_downloaded)
|
||||
|
||||
title_label = Gtk.Label(
|
||||
label=item.title,
|
||||
ellipsize=Pango.EllipsizeMode.END,
|
||||
max_width_chars=20,
|
||||
)
|
||||
|
||||
album_box.pack_end(title_label, False, False, 0)
|
||||
album_box.show_all()
|
||||
return album_box
|
||||
|
@@ -27,12 +27,12 @@
|
||||
margin: 5px 10px 10px 0;
|
||||
}
|
||||
|
||||
#playlist-artwork-spinner, #artist-artwork-spinner {
|
||||
#playlist-artwork-spinner, #artist-artwork-spinner, #album-artwork-spinner {
|
||||
min-height: 35px;
|
||||
min-width: 35px;
|
||||
}
|
||||
|
||||
#playlist-album-artwork, #artist-artwork {
|
||||
#playlist-album-artwork, #artist-artwork, #album-artwork {
|
||||
min-height: 200px;
|
||||
min-width: 200px;
|
||||
margin: 10px;
|
||||
|
@@ -45,8 +45,8 @@ class ArtistsGrid(Gtk.FlowBox):
|
||||
self,
|
||||
vexpand=True,
|
||||
hexpand=True,
|
||||
row_spacing=10,
|
||||
column_spacing=10,
|
||||
row_spacing=12,
|
||||
column_spacing=12,
|
||||
margin_top=12,
|
||||
margin_bottom=12,
|
||||
homogeneous=True,
|
||||
@@ -55,9 +55,8 @@ class ArtistsGrid(Gtk.FlowBox):
|
||||
selection_mode=Gtk.SelectionMode.BROWSE,
|
||||
)
|
||||
|
||||
self.artist_model = Gio.ListStore()
|
||||
|
||||
self.bind_model(self.artist_model, self.create_artist_widget)
|
||||
self.artists_model = Gio.ListStore()
|
||||
self.bind_model(self.artists_model, self.create_artist_widget)
|
||||
|
||||
def update(self, state: ApplicationState):
|
||||
self.update_grid()
|
||||
@@ -69,9 +68,10 @@ class ArtistsGrid(Gtk.FlowBox):
|
||||
)
|
||||
def update_grid(self, artists: List[ArtistID3]):
|
||||
# TODO do the diff thing eventually?
|
||||
self.artist_model.remove_all()
|
||||
self.artists_model.remove_all()
|
||||
for artist in artists:
|
||||
self.artist_model.append(ArtistModel(artist.name, artist.coverArt))
|
||||
self.artists_model.append(ArtistModel(artist.name,
|
||||
artist.coverArt))
|
||||
|
||||
def create_artist_widget(self, item):
|
||||
artist_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
@@ -100,7 +100,6 @@ class ArtistsGrid(Gtk.FlowBox):
|
||||
cover_art_filename_future.add_done_callback(artwork_downloaded)
|
||||
|
||||
name_label = Gtk.Label(
|
||||
name='artist-name-label',
|
||||
label=item.name,
|
||||
ellipsize=Pango.EllipsizeMode.END,
|
||||
max_width_chars=20,
|
||||
|
Reference in New Issue
Block a user