Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/spotify_to_tidal/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
from . import auth as _auth

def main():
parser = argparse.ArgumentParser()
parser = argparse.ArgumentParser(prog="spotify_to_tidal")
parser.add_argument('--config', default='config.yml', help='location of the config file')
parser.add_argument('--uri', help='synchronize a specific URI instead of the one in the config')
parser.add_argument('--sync-favorites', action=argparse.BooleanOptionalAction, help='synchronize the favorites')
parser.add_argument('--favs-to-playlist', metavar='PLAYLIST_NAME', help='synchronize Spotify favorites to specific Tidal playlist')
args = parser.parse_args()

with open(args.config, 'r') as f:
Expand All @@ -29,6 +30,14 @@ def main():
sync_favorites = args.sync_favorites # only sync favorites if command line argument explicitly passed
elif args.sync_favorites:
sync_favorites = True # sync only the favorites
elif args.favs_to_playlist:
# get tidal playlist by name if it exists
tidal_playlist = None
tidal_playlists = _sync.get_tidal_playlists_wrapper(tidal_session)
if args.favs_to_playlist in tidal_playlists:
tidal_playlist = tidal_playlists[args.favs_to_playlist]
_sync.sync_favorites_to_playlist_wrapper(spotify_session, tidal_session, tidal_playlist, args.favs_to_playlist, config)
sync_favorites = False # favs are already being synced
elif config.get('sync_playlists', None):
# if the config contains a sync_playlists list of mappings then use that
_sync.sync_playlists_wrapper(spotify_session, tidal_session, _sync.get_playlists_from_config(spotify_session, tidal_session, config), config)
Expand Down
37 changes: 37 additions & 0 deletions src/spotify_to_tidal/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,40 @@ async def sync_playlist(spotify_session: spotipy.Spotify, tidal_session: tidalap
clear_tidal_playlist(tidal_playlist)
add_multiple_tracks_to_playlist(tidal_playlist, new_tidal_track_ids)

async def sync_favorites_to_playlist(spotify_session: spotipy.Spotify, tidal_session: tidalapi.Session, tidal_playlist: tidalapi.Playlist | None, tidal_playlist_name: str, config: dict):
""" sync user favorites to tidal playlist """
async def get_tracks_from_spotify_favorites() -> List[dict]:
_get_favorite_tracks = lambda offset: spotify_session.current_user_saved_tracks(offset=offset)
tracks = await repeat_on_request_error( _fetch_all_from_spotify_in_chunks, _get_favorite_tracks)
tracks.reverse()
return tracks

print("Loading favorite tracks from Spotify")
spotify_tracks = await get_tracks_from_spotify_favorites()

if tidal_playlist:
old_tidal_tracks = await get_all_playlist_tracks(tidal_playlist)
else:
print(f"No playlist found on Tidal with provided name: '{tidal_playlist_name}', creating new playlist")
tidal_playlist = tidal_session.user.create_playlist(tidal_playlist_name, "")
old_tidal_tracks = []

populate_track_match_cache(spotify_tracks, old_tidal_tracks)
await search_new_tracks_on_tidal(tidal_session, spotify_tracks, "Favorites", config)
new_tidal_track_ids = get_tracks_for_new_tidal_playlist(spotify_tracks)

# Update the Tidal playlist if there are changes
old_tidal_track_ids = [t.id for t in old_tidal_tracks]
if new_tidal_track_ids == old_tidal_track_ids:
print("No changes to write to Tidal playlist")
elif new_tidal_track_ids[:len(old_tidal_track_ids)] == old_tidal_track_ids:
# Append new tracks to the existing playlist if possible
add_multiple_tracks_to_playlist(tidal_playlist, new_tidal_track_ids[len(old_tidal_track_ids):])
else:
# Erase old playlist and add new tracks from scratch if any reordering occured
clear_tidal_playlist(tidal_playlist)
add_multiple_tracks_to_playlist(tidal_playlist, new_tidal_track_ids)

async def sync_favorites(spotify_session: spotipy.Spotify, tidal_session: tidalapi.Session, config: dict):
""" sync user favorites to tidal """
async def get_tracks_from_spotify_favorites() -> List[dict]:
Expand Down Expand Up @@ -356,6 +390,9 @@ def sync_playlists_wrapper(spotify_session: spotipy.Spotify, tidal_session: tida
def sync_favorites_wrapper(spotify_session: spotipy.Spotify, tidal_session: tidalapi.Session, config):
asyncio.run(main=sync_favorites(spotify_session=spotify_session, tidal_session=tidal_session, config=config))

def sync_favorites_to_playlist_wrapper(spotify_session: spotipy.Spotify, tidal_session: tidalapi.Session, tidal_playlist: tidalapi.Playlist | None, tidal_playlist_name: str, config):
asyncio.run(main=sync_favorites_to_playlist(spotify_session=spotify_session, tidal_session=tidal_session, tidal_playlist=tidal_playlist, tidal_playlist_name=tidal_playlist_name, config=config))

def get_tidal_playlists_wrapper(tidal_session: tidalapi.Session) -> Mapping[str, tidalapi.Playlist]:
tidal_playlists = asyncio.run(get_all_playlists(tidal_session.user))
return {playlist.name: playlist for playlist in tidal_playlists}
Expand Down