Resolves #62 cache and state per server

This commit is contained in:
Sumner Evans
2019-10-28 23:40:46 -06:00
parent 19e5d47c76
commit 5ed7ccc0f9
5 changed files with 68 additions and 50 deletions

View File

@@ -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,

View File

@@ -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,

View File

@@ -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])

View File

@@ -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):

View File

@@ -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)