Merge branch 'master' of gitlab.com:sumner/sublime-music

This commit is contained in:
Sumner Evans
2020-03-06 08:11:49 -07:00
10 changed files with 55 additions and 31 deletions

View File

@@ -855,16 +855,19 @@ class SublimeMusicApp(Gtk.Application):
if order_token != self.song_playing_order_token: if order_token != self.song_playing_order_token:
return return
# Add the image to the notification, and re-draw the # Add the image to the notification, and re-show the
# notification. # notification.
song_notification.set_image_from_pixbuf( song_notification.set_image_from_pixbuf(
GdkPixbuf.Pixbuf.new_from_file(cover_art_filename)) GdkPixbuf.Pixbuf.new_from_file_at_scale(
cover_art_filename, 70, 70, True))
song_notification.show() song_notification.show()
def get_cover_art_filename(order_token): def get_cover_art_filename(order_token):
cover_art_future = CacheManager.get_cover_art_filename( return (
song.coverArt, size=70) CacheManager.get_cover_art_filename(
return cover_art_future.result(), order_token song.coverArt).result(),
order_token,
)
self.song_playing_order_token += 1 self.song_playing_order_token += 1
cover_art_future = CacheManager.create_future( cover_art_future = CacheManager.create_future(

View File

@@ -4,6 +4,7 @@ import itertools
import json import json
import logging import logging
import os import os
import re
import shutil import shutil
import threading import threading
from collections import defaultdict from collections import defaultdict
@@ -252,6 +253,7 @@ class CacheManager(metaclass=Singleton):
CacheManager.should_exit = True CacheManager.should_exit = True
logging.info('CacheManager shutdown start') logging.info('CacheManager shutdown start')
CacheManager.executor.shutdown() CacheManager.executor.shutdown()
CacheManager._instance.save_cache_info()
logging.info('CacheManager shutdown complete') logging.info('CacheManager shutdown complete')
@staticmethod @staticmethod
@@ -335,7 +337,30 @@ class CacheManager(metaclass=Singleton):
try: try:
meta_json = json.load(f) meta_json = json.load(f)
except json.decoder.JSONDecodeError: except json.decoder.JSONDecodeError:
return # Just continue with the default meta_json.
pass
cache_version = meta_json.get('version', 0)
if cache_version < 1:
logging.info('Migrating cache to version 1.')
cover_art_re = re.compile(r'(\d+)_(\d+)')
abs_path = self.calculate_abs_path('cover_art/')
for cover_art_file in Path(abs_path).iterdir():
match = cover_art_re.match(cover_art_file.name)
if match:
art_id, dimensions = map(int, match.groups())
if dimensions == 1000:
no_dimens = cover_art_file.parent.joinpath(
'{art_id}')
logging.debug(
f'Moving {cover_art_file} to {no_dimens}')
shutil.move(cover_art_file, no_dimens)
else:
logging.debug(f'Deleting {cover_art_file}')
cover_art_file.unlink()
self.cache['version'] = 1
cache_configs = [ cache_configs = [
# Playlists # Playlists
@@ -476,7 +501,7 @@ class CacheManager(metaclass=Singleton):
return CacheManager.executor.submit(fn, *args) return CacheManager.executor.submit(fn, *args)
def delete_cached_cover_art(self, id: int): def delete_cached_cover_art(self, id: int):
relative_path = f'cover_art/*{id}_*' relative_path = f'cover_art/*{id}*'
abs_path = self.calculate_abs_path(relative_path) abs_path = self.calculate_abs_path(relative_path)
@@ -698,12 +723,12 @@ class CacheManager(metaclass=Singleton):
'2a96cbd8b46e442fc41c2b86b821562f.png')): '2a96cbd8b46e442fc41c2b86b821562f.png')):
if isinstance(artist, (ArtistWithAlbumsID3, ArtistID3)): if isinstance(artist, (ArtistWithAlbumsID3, ArtistID3)):
return CacheManager.get_cover_art_filename( return CacheManager.get_cover_art_filename(
artist.coverArt, size=300) artist.coverArt)
elif (isinstance(artist, Directory) elif (isinstance(artist, Directory)
and len(artist.child) > 0): and len(artist.child) > 0):
# Retrieve the first album's cover art # Retrieve the first album's cover art
return CacheManager.get_cover_art_filename( return CacheManager.get_cover_art_filename(
artist.child[0].coverArt, size=300) artist.child[0].coverArt)
if lastfm_url == '': if lastfm_url == '':
return CacheManager.Result.from_data('') return CacheManager.Result.from_data('')
@@ -876,17 +901,16 @@ class CacheManager(metaclass=Singleton):
self, self,
id: str, id: str,
before_download: Callable[[], None] = lambda: None, before_download: Callable[[], None] = lambda: None,
size: Union[str, int] = 200,
force: bool = False, force: bool = False,
allow_download: bool = True, allow_download: bool = True,
) -> 'CacheManager.Result[Optional[str]]': ) -> 'CacheManager.Result[Optional[str]]':
if id is None: if id is None:
art_path = 'ui/images/default-album-art.png' default_art_path = 'ui/images/default-album-art.png'
return CacheManager.Result.from_data( return CacheManager.Result.from_data(
str(Path(__file__).parent.joinpath(art_path))) str(Path(__file__).parent.joinpath(default_art_path)))
return self.return_cached_or_download( return self.return_cached_or_download(
f'cover_art/{id}_{size}', f'cover_art/{id}',
lambda: self.server.get_cover_art(id, str(size)), lambda: self.server.get_cover_art(id),
before_download=before_download, before_download=before_download,
force=force, force=force,
allow_download=allow_download, allow_download=allow_download,

View File

@@ -277,11 +277,11 @@ class DBusManager:
'x', 'x',
(song.duration or 0) * self.second_microsecond_conversion, (song.duration or 0) * self.second_microsecond_conversion,
) )
track_cover = CacheManager.get_cover_art_url(song.coverArt, 1000)
return { return {
'mpris:trackid': trackid, 'mpris:trackid': trackid,
'mpris:length': duration, 'mpris:length': duration,
'mpris:artUrl': track_cover, 'mpris:artUrl': CacheManager.get_cover_art_url(song.coverArt),
'xesam:album': song.album or '', 'xesam:album': song.album or '',
'xesam:albumArtist': [song.artist or ''], 'xesam:albumArtist': [song.artist or ''],
'xesam:artist': [song.artist or ''], 'xesam:artist': [song.artist or ''],

View File

@@ -428,7 +428,7 @@ class ChromecastPlayer(Player):
force_stream=True, force_stream=True,
) )
cover_art_url = CacheManager.get_cover_art_url(song.coverArt, 1000) cover_art_url = CacheManager.get_cover_art_url(song.coverArt)
self.chromecast.media_controller.play_media( self.chromecast.media_controller.play_media(
file_or_url, file_or_url,
# Just pretend that whatever we send it is mp3, even if it isn't. # Just pretend that whatever we send it is mp3, even if it isn't.

View File

@@ -840,7 +840,7 @@ class Server:
""" """
return self.do_download(self._make_url('download'), id=id) return self.do_download(self._make_url('download'), id=id)
def get_cover_art(self, id: str, size: str = None) -> bytes: def get_cover_art(self, id: str, size: int = 1000):
""" """
Returns the cover art image in binary form. Returns the cover art image in binary form.
@@ -850,9 +850,9 @@ class Server:
return self.do_download( return self.do_download(
self._make_url('getCoverArt'), id=id, size=size) self._make_url('getCoverArt'), id=id, size=size)
def get_cover_art_url(self, id: str, size: str = None) -> str: def get_cover_art_url(self, id: str, size: int = 1000):
""" """
Returns the cover art image in binary form. Returns the URL of the cover art image.
:param id: The ID of a song, album or artist. :param id: The ID of a song, album or artist.
:param size: If specified, scale image to this size. :param size: If specified, scale image to this size.

View File

@@ -183,6 +183,7 @@ class ArtistDetailPanel(Gtk.Box):
loading=False, loading=False,
image_name='artist-album-artwork', image_name='artist-album-artwork',
spinner_name='artist-artwork-spinner', spinner_name='artist-artwork-spinner',
image_size=300,
) )
self.big_info_panel.pack_start(self.artist_artwork, False, False, 0) self.big_info_panel.pack_start(self.artist_artwork, False, False, 0)

View File

@@ -57,7 +57,6 @@ class AlbumWithSongs(Gtk.Box):
cover_art_filename_future = CacheManager.get_cover_art_filename( cover_art_filename_future = CacheManager.get_cover_art_filename(
album.coverArt, album.coverArt,
before_download=lambda: artist_artwork.set_loading(True), before_download=lambda: artist_artwork.set_loading(True),
size=cover_art_size,
) )
cover_art_filename_future.add_done_callback( cover_art_filename_future.add_done_callback(
lambda f: GLib.idle_add(cover_art_future_done, f)) lambda f: GLib.idle_add(cover_art_future_done, f))

View File

@@ -391,7 +391,7 @@ class MainWindow(Gtk.ApplicationWindow):
util.esc(song.artist), util.esc(song.artist),
) )
cover_art_future = CacheManager.get_cover_art_filename( cover_art_future = CacheManager.get_cover_art_filename(
song.coverArt, size=50) song.coverArt)
self.song_results.add( self.song_results.add(
self._create_search_result_row( self._create_search_result_row(
label_text, 'song', song, cover_art_future)) label_text, 'song', song, cover_art_future))
@@ -407,7 +407,7 @@ class MainWindow(Gtk.ApplicationWindow):
util.esc(album.artist), util.esc(album.artist),
) )
cover_art_future = CacheManager.get_cover_art_filename( cover_art_future = CacheManager.get_cover_art_filename(
album.coverArt, size=50) album.coverArt)
self.album_results.add( self.album_results.add(
self._create_search_result_row( self._create_search_result_row(
label_text, 'album', album, cover_art_future)) label_text, 'album', album, cover_art_future))

View File

@@ -137,7 +137,6 @@ class PlayerControls(Gtk.ActionBar):
self.cover_art_update_order_token += 1 self.cover_art_update_order_token += 1
self.update_cover_art( self.update_cover_art(
state.current_song.coverArt, state.current_song.coverArt,
size='70',
order_token=self.cover_art_update_order_token, order_token=self.cover_art_update_order_token,
) )
@@ -194,9 +193,7 @@ class PlayerControls(Gtk.ActionBar):
# Cover Art # Cover Art
cover_art_future = CacheManager.get_cover_art_filename( cover_art_future = CacheManager.get_cover_art_filename(
song_details.coverArt, song_details.coverArt)
size=50,
)
if cover_art_result.is_future: if cover_art_result.is_future:
# We don't have the cover art already cached. # We don't have the cover art already cached.
cover_art_result.add_done_callback( cover_art_result.add_done_callback(
@@ -227,9 +224,7 @@ class PlayerControls(Gtk.ActionBar):
label = calculate_label(song_details) label = calculate_label(song_details)
cover_art_result = CacheManager.get_cover_art_filename( cover_art_result = CacheManager.get_cover_art_filename(
song_details.coverArt, song_details.coverArt)
size=50,
)
if cover_art_result.is_future: if cover_art_result.is_future:
# We don't have the cover art already cached. # We don't have the cover art already cached.
cover_art_result.add_done_callback( cover_art_result.add_done_callback(
@@ -655,7 +650,8 @@ class PlayerControls(Gtk.ActionBar):
if not filename: if not filename:
cell.set_property('icon_name', '') cell.set_property('icon_name', '')
return return
pixbuf = GdkPixbuf.Pixbuf.new_from_file(filename) pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale(
filename, 50, 50, True)
# If this is the playing song, then overlay the play icon. # If this is the playing song, then overlay the play icon.
if model.get_value(iter, 2): if model.get_value(iter, 2):

View File

@@ -264,6 +264,7 @@ class PlaylistDetailPanel(Gtk.Overlay):
self.playlist_artwork = SpinnerImage( self.playlist_artwork = SpinnerImage(
image_name='playlist-album-artwork', image_name='playlist-album-artwork',
spinner_name='playlist-artwork-spinner', spinner_name='playlist-artwork-spinner',
image_size=200,
) )
self.big_info_panel.pack_start(self.playlist_artwork, False, False, 0) self.big_info_panel.pack_start(self.playlist_artwork, False, False, 0)