Performance optimization / refactoring (#43)

This replaces #36 and adds some other fixes!

Execution speed should be much faster now, especially when there are not
many changes to synchronize.

* Maintain track cache between different playlists (thanks to @joshrmcdaniel for amazing work on that!)
* Fix incorrect tidal_playlist_is_dirty() implementation
* Remove more redundant API calls
* Avoid unnecessarily spinning up tasks for tracks that were in match failure cache
* Introduce new rate_limit configuration parameter implemented with leaky bucket rate-limiting algorithm
* Where possible, add new tracks to existing playlist instead of erasing the old ones
* Use asyncio multithreading instead of multiprocessing
* When user has large number of spotify playlists, fetch them in parallel instead of one by one
* More typing hints / typing fixes
This commit is contained in:
Tim Rae
2024-06-03 09:11:56 +02:00
committed by GitHub
parent 689637510d
commit 1e8366a0e8
5 changed files with 207 additions and 165 deletions

View File

@@ -1,19 +1,21 @@
from typing import List
import tidalapi
from tqdm import tqdm
def _remove_indices_from_playlist(playlist, indices):
def _remove_indices_from_playlist(playlist: tidalapi.UserPlaylist, indices: List[int]):
headers = {'If-None-Match': playlist._etag}
index_string = ",".join(map(str, indices))
playlist.request.request('DELETE', (playlist._base_url + '/items/%s') % (playlist.id, index_string), headers=headers)
playlist._reparse()
def clear_tidal_playlist(playlist, chunk_size=20):
def clear_tidal_playlist(playlist: tidalapi.UserPlaylist, chunk_size: int=20):
with tqdm(desc="Erasing existing tracks from Tidal playlist", total=playlist.num_tracks) as progress:
while playlist.num_tracks:
indices = range(min(playlist.num_tracks, chunk_size))
_remove_indices_from_playlist(playlist, indices)
progress.update(len(indices))
def add_multiple_tracks_to_playlist(playlist, track_ids, chunk_size=20):
def add_multiple_tracks_to_playlist(playlist: tidalapi.UserPlaylist, track_ids: List[int], chunk_size: int=20):
offset = 0
with tqdm(desc="Adding new tracks to Tidal playlist", total=len(track_ids)) as progress:
while offset < len(track_ids):
@@ -22,6 +24,6 @@ def add_multiple_tracks_to_playlist(playlist, track_ids, chunk_size=20):
offset += count
progress.update(count)
def set_tidal_playlist(playlist, track_ids):
def set_tidal_playlist(playlist: tidalapi.Playlist, track_ids: List[int]):
clear_tidal_playlist(playlist)
add_multiple_tracks_to_playlist(playlist, track_ids)