diff --git a/libremsonic/app.py b/libremsonic/app.py index 413fda6..b8c2722 100644 --- a/libremsonic/app.py +++ b/libremsonic/app.py @@ -346,8 +346,14 @@ class LibremsonicApp(Gtk.Application): def save_play_queue(self): position = self.state.song_progress self.last_play_queue_update = position - CacheManager.executor.submit(lambda: CacheManager.save_play_queue( - id=self.state.play_queue, - current=self.state.current_song.id, - position=math.floor(position * 1000), - )) + + current_server = self.state.config.current_server + current_server = self.state.config.servers[current_server] + + if current_server.sync_enabled: + CacheManager.executor.submit( + CacheManager.save_play_queue, + id=self.state.play_queue, + current=self.state.current_song.id, + position=math.floor(position * 1000), + ) diff --git a/libremsonic/cache_manager.py b/libremsonic/cache_manager.py index 268c9aa..3227f0b 100644 --- a/libremsonic/cache_manager.py +++ b/libremsonic/cache_manager.py @@ -66,6 +66,9 @@ class CacheManager(metaclass=Singleton): download_set_lock = threading.Lock() current_downloads: Set[Path] = set() + # TODO make this configurable. + download_limiter_semaphore = threading.Semaphore(5) + def __init__( self, app_config: AppConfiguration, @@ -226,6 +229,33 @@ class CacheManager(metaclass=Singleton): return CacheManager.executor.submit(do_get_playlist) + def batch_download_songs( + self, + song_ids: List[int], + before_download: Callable[[], None], + on_song_download_complete: Callable[[int], None], + ) -> Future: + def do_download_song(song_id): + # Do the actual download. + song_details_future = CacheManager.get_song_details(song_id) + song_filename_future = CacheManager.get_song_filename( + song_details_future.result(), + before_download=before_download, + ) + + def filename_future_done(f): + on_song_download_complete(song_id) + self.download_limiter_semaphore.release() + + song_filename_future.add_done_callback(filename_future_done) + + def do_batch_download_songs(): + for song_id in song_ids: + self.download_limiter_semaphore.acquire() + CacheManager.executor.submit(do_download_song, song_id) + + return CacheManager.executor.submit(do_batch_download_songs) + def get_cover_art_filename( self, id: str, diff --git a/libremsonic/ui/playlists.py b/libremsonic/ui/playlists.py index 3dcd767..045fbef 100644 --- a/libremsonic/ui/playlists.py +++ b/libremsonic/ui/playlists.py @@ -321,21 +321,15 @@ class PlaylistsPanel(Gtk.Paned): playlist = self.playlist_map[ self.playlist_list.get_selected_row().get_index()] - def do_download_song(song: Child): - song_filename_future = CacheManager.get_song_filename( - song, - before_download=lambda: self.update_playlist_view(playlist.id), - ) + def download_state_change(*args): + GLib.idle_add(self.update_playlist_view, playlist.id) - def on_song_download_complete(f): - self.update_playlist_view(playlist) - - song_filename_future.add_done_callback(on_song_download_complete) - - for song in self.playlist_song_model: - song_details_future = CacheManager.get_song_details(song[-1]) - song_details_future.add_done_callback( - lambda f: do_download_song(f.result()), ) + song_ids = [s[-1] for s in self.playlist_song_model] + CacheManager.batch_download_songs( + song_ids, + before_download=download_state_change, + on_song_download_complete=download_state_change, + ) def on_view_refresh_click(self, button): playlist = self.playlist_map[