Resolves #62 cache and state per server
This commit is contained in:
@@ -150,10 +150,11 @@ class SublimeMusicApp(Gtk.Application):
|
||||
self.state.load()
|
||||
|
||||
# If there is no current server, show the dialog to select a server.
|
||||
if (self.state.config.current_server is None
|
||||
or self.state.config.current_server < 0):
|
||||
if self.state.config.server is None:
|
||||
self.show_configure_servers_dialog()
|
||||
if self.current_server is None:
|
||||
|
||||
# If they didn't add one with the dialog, close the window.
|
||||
if self.state.config.server is None:
|
||||
self.window.close()
|
||||
return
|
||||
|
||||
@@ -161,8 +162,11 @@ class SublimeMusicApp(Gtk.Application):
|
||||
|
||||
# Configure the players
|
||||
self.last_play_queue_update = 0
|
||||
self.loading_state = False
|
||||
|
||||
def time_observer(value):
|
||||
if self.loading_state:
|
||||
return
|
||||
self.state.song_progress = value
|
||||
GLib.idle_add(
|
||||
self.window.player_controls.update_scrubber,
|
||||
@@ -223,7 +227,7 @@ class SublimeMusicApp(Gtk.Application):
|
||||
|
||||
# Prompt to load the play queue from the server.
|
||||
# TODO should this be behind sync enabled?
|
||||
if self.current_server.sync_enabled:
|
||||
if self.state.config.server.sync_enabled:
|
||||
self.update_play_state_from_server(prompt_confirm=True)
|
||||
|
||||
# Send out to the bus that we exist.
|
||||
@@ -423,8 +427,8 @@ class SublimeMusicApp(Gtk.Application):
|
||||
'prefetch_amount'].get_value_as_int()
|
||||
self.state.config.concurrent_download_limit = dialog.data[
|
||||
'concurrent_download_limit'].get_value_as_int()
|
||||
self.state.save()
|
||||
self.reset_cache_manager()
|
||||
self.state.save_config()
|
||||
self.reset_state()
|
||||
dialog.destroy()
|
||||
|
||||
@dbus_propagate()
|
||||
@@ -539,24 +543,25 @@ class SublimeMusicApp(Gtk.Application):
|
||||
|
||||
def on_server_list_changed(self, action, servers):
|
||||
self.state.config.servers = servers
|
||||
self.state.save()
|
||||
self.state.save_config()
|
||||
|
||||
def on_connected_server_changed(self, action, current_server):
|
||||
self.state.config.current_server = current_server
|
||||
self.state.save()
|
||||
self.state.config.current_server = current_server
|
||||
self.state.save_config()
|
||||
|
||||
self.reset_cache_manager()
|
||||
self.update_window()
|
||||
self.reset_state()
|
||||
|
||||
def reset_cache_manager(self):
|
||||
CacheManager.reset(
|
||||
self.state.config,
|
||||
self.current_server
|
||||
if self.state.config.current_server >= 0 else None,
|
||||
)
|
||||
def reset_state(self):
|
||||
if self.state.playing:
|
||||
self.on_play_pause()
|
||||
self.loading_state = True
|
||||
self.state.load()
|
||||
self.player.reset()
|
||||
self.loading_state = False
|
||||
|
||||
# Update the window according to the new server configuration.
|
||||
self.update_window()
|
||||
self.update_window(force=True)
|
||||
|
||||
def on_stack_change(self, stack, child):
|
||||
self.state.current_tab = stack.get_visible_child_name()
|
||||
@@ -655,7 +660,7 @@ class SublimeMusicApp(Gtk.Application):
|
||||
def on_app_shutdown(self, app):
|
||||
Notify.uninit()
|
||||
|
||||
if self.current_server is None:
|
||||
if self.state.config.server is None:
|
||||
return
|
||||
|
||||
self.player.pause()
|
||||
@@ -667,13 +672,6 @@ class SublimeMusicApp(Gtk.Application):
|
||||
self.dbus_manager.shutdown()
|
||||
CacheManager.shutdown()
|
||||
|
||||
# ########## PROPERTIES ########## #
|
||||
@property
|
||||
def current_server(self):
|
||||
if len(self.state.config.servers) < 1:
|
||||
return None
|
||||
return self.state.config.servers[self.state.config.current_server]
|
||||
|
||||
# ########## HELPER METHODS ########## #
|
||||
def show_configure_servers_dialog(self):
|
||||
"""Show the Connect to Server dialog."""
|
||||
@@ -817,10 +815,11 @@ class SublimeMusicApp(Gtk.Application):
|
||||
# Switch to the local media if the player can hotswap (MPV can,
|
||||
# Chromecast cannot hotswap without lag).
|
||||
if self.player.can_hotswap_source:
|
||||
downloaded_filename = (
|
||||
CacheManager.get_song_filename_or_stream(song)[0])
|
||||
self.player.play_media(
|
||||
downloaded_filename, self.state.song_progress, song)
|
||||
CacheManager.get_song_filename_or_stream(song)[0],
|
||||
self.state.song_progress,
|
||||
song,
|
||||
)
|
||||
GLib.idle_add(self.update_window)
|
||||
|
||||
# If streaming, also download the song, unless configured not to,
|
||||
@@ -859,7 +858,7 @@ class SublimeMusicApp(Gtk.Application):
|
||||
self.update_window),
|
||||
)
|
||||
|
||||
if self.current_server.sync_enabled:
|
||||
if self.state.config.server.sync_enabled:
|
||||
CacheManager.scrobble(song.id)
|
||||
|
||||
song_details_future = CacheManager.get_song_details(song_id)
|
||||
@@ -873,7 +872,7 @@ class SublimeMusicApp(Gtk.Application):
|
||||
position = self.state.song_progress
|
||||
self.last_play_queue_update = position
|
||||
|
||||
if self.current_server.sync_enabled and self.state.current_song:
|
||||
if self.state.config.server.sync_enabled and self.state.current_song:
|
||||
CacheManager.save_play_queue(
|
||||
play_queue=self.state.play_queue,
|
||||
current=self.state.current_song.id,
|
||||
|
@@ -84,6 +84,11 @@ class CacheManager(metaclass=Singleton):
|
||||
CacheManager.executor.shutdown()
|
||||
print('Shutdown complete')
|
||||
|
||||
@staticmethod
|
||||
def calculate_server_hash(server: ServerConfiguration):
|
||||
server_info = (server.name + server.server_address + server.username)
|
||||
return hashlib.md5(server_info.encode('utf-8')).hexdigest()[:8]
|
||||
|
||||
class CacheEncoder(json.JSONEncoder):
|
||||
def default(self, obj):
|
||||
if type(obj) == datetime:
|
||||
@@ -123,8 +128,8 @@ class CacheManager(metaclass=Singleton):
|
||||
server_config: ServerConfiguration,
|
||||
):
|
||||
self.app_config = app_config
|
||||
self.browse_by_tags = self.app_config.servers[
|
||||
self.app_config.current_server].browse_by_tags
|
||||
self.browse_by_tags = self.app_config.server.browse_by_tags
|
||||
self.server_config = server_config
|
||||
self.server = Server(
|
||||
name=server_config.name,
|
||||
hostname=server_config.server_address,
|
||||
@@ -191,6 +196,7 @@ class CacheManager(metaclass=Singleton):
|
||||
os.makedirs(self.app_config.cache_location, exist_ok=True)
|
||||
|
||||
cache_meta_file = self.calculate_abs_path('.cache_meta')
|
||||
os.makedirs(os.path.dirname(cache_meta_file), exist_ok=True)
|
||||
with open(cache_meta_file, 'w+') as f, self.cache_lock:
|
||||
f.write(
|
||||
json.dumps(
|
||||
@@ -203,8 +209,10 @@ class CacheManager(metaclass=Singleton):
|
||||
f.write(data)
|
||||
|
||||
def calculate_abs_path(self, *relative_paths):
|
||||
return Path(
|
||||
self.app_config.cache_location).joinpath(*relative_paths)
|
||||
return Path(self.app_config.cache_location).joinpath(
|
||||
CacheManager.calculate_server_hash(self.server_config),
|
||||
*relative_paths,
|
||||
)
|
||||
|
||||
def calculate_download_path(self, *relative_paths):
|
||||
"""
|
||||
@@ -214,7 +222,10 @@ class CacheManager(metaclass=Singleton):
|
||||
os.environ.get('XDG_CACHE_HOME')
|
||||
or os.path.expanduser('~/.cache'))
|
||||
return Path(xdg_cache_home).joinpath(
|
||||
'sublime-music', *relative_paths)
|
||||
'sublime-music',
|
||||
CacheManager.calculate_server_hash(self.server_config),
|
||||
*relative_paths,
|
||||
)
|
||||
|
||||
def return_cached_or_download(
|
||||
self,
|
||||
|
@@ -77,3 +77,9 @@ class AppConfiguration:
|
||||
os.environ.get('XDG_DATA_HOME')
|
||||
or os.path.expanduser('~/.local/share'))
|
||||
return os.path.join(default_cache_location, 'sublime-music')
|
||||
|
||||
@property
|
||||
def server(self) -> ServerConfiguration:
|
||||
return (
|
||||
None if self.current_server < 0 or len(self.servers) < 1 else
|
||||
self.servers[self.current_server])
|
||||
|
@@ -159,13 +159,9 @@ class ApplicationState:
|
||||
def load(self):
|
||||
self.config = self.get_config(self.config_file)
|
||||
|
||||
if self.config.current_server >= 0:
|
||||
if self.config.server is not None:
|
||||
# Reset the CacheManager.
|
||||
CacheManager.reset(
|
||||
self.config,
|
||||
self.config.servers[self.config.current_server]
|
||||
if self.config.current_server >= 0 else None,
|
||||
)
|
||||
CacheManager.reset(self.config, self.config.server)
|
||||
|
||||
if os.path.exists(self.state_filename):
|
||||
with open(self.state_filename, 'r') as f:
|
||||
@@ -176,19 +172,21 @@ class ApplicationState:
|
||||
pass
|
||||
|
||||
def save(self):
|
||||
# Make the necessary directories before writing the config and state.
|
||||
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
||||
# Make the necessary directories before writing the state.
|
||||
os.makedirs(os.path.dirname(self.state_filename), exist_ok=True)
|
||||
|
||||
# Save the config
|
||||
with open(self.config_file, 'w+') as f:
|
||||
f.write(
|
||||
json.dumps(self.config.to_json(), indent=2, sort_keys=True))
|
||||
|
||||
# Save the state
|
||||
with open(self.state_filename, 'w+') as f:
|
||||
f.write(json.dumps(self.to_json(), indent=2, sort_keys=True))
|
||||
|
||||
def save_config(self):
|
||||
# Make the necessary directories before writing the config.
|
||||
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
||||
|
||||
with open(self.config_file, 'w+') as f:
|
||||
f.write(
|
||||
json.dumps(self.config.to_json(), indent=2, sort_keys=True))
|
||||
|
||||
def get_config(self, filename: str) -> AppConfiguration:
|
||||
if not os.path.exists(filename):
|
||||
return AppConfiguration()
|
||||
@@ -204,7 +202,12 @@ class ApplicationState:
|
||||
default_cache_location = (
|
||||
os.environ.get('XDG_DATA_HOME')
|
||||
or os.path.expanduser('~/.local/share'))
|
||||
return os.path.join(default_cache_location, 'sublime-music/state.yaml')
|
||||
return os.path.join(
|
||||
default_cache_location,
|
||||
'sublime-music',
|
||||
CacheManager.calculate_server_hash(self.config.server),
|
||||
'state.yaml',
|
||||
)
|
||||
|
||||
@property
|
||||
def volume(self):
|
||||
|
@@ -314,7 +314,6 @@ class ArtistDetailPanel(Gtk.Box):
|
||||
cover_art_filename,
|
||||
state: ApplicationState,
|
||||
):
|
||||
print(cover_art_filename)
|
||||
self.artist_artwork.set_from_file(cover_art_filename)
|
||||
self.artist_artwork.set_loading(False)
|
||||
|
||||
|
Reference in New Issue
Block a user