Skip to content

Commit

Permalink
Separate spotify submission into a utility function (#104)
Browse files Browse the repository at this point in the history
So that we can submit bulk generated playlists from spark without creating
unnecessary patch objects.
  • Loading branch information
amCap1712 authored Jul 5, 2023
1 parent 1457875 commit cb01f34
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 45 deletions.
5 changes: 2 additions & 3 deletions troi/patches/periodic_jams.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
import troi.listenbrainz.listens
import troi.listenbrainz.recs
import troi.musicbrainz.recording_lookup
from troi import Playlist, Element, Recording
from troi.musicbrainz.recording import RecordingListElement
from troi.playlist import PlaylistMakerElement, PlaylistShuffleElement
from troi import Playlist
from troi.playlist import PlaylistMakerElement

DAYS_OF_RECENT_LISTENS_TO_EXCLUDE = 60 # Exclude tracks listened in last X days from the daily jams playlist
DAILY_JAMS_MIN_RECORDINGS = 25 # the minimum number of recordings we aspire to have in a daily jam, this is not a hard limit
Expand Down
46 changes: 4 additions & 42 deletions troi/playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

import requests
import spotipy
from more_itertools import chunked
from spotipy import SpotifyException

from troi import Recording, Playlist, PipelineError, Element, Artist, Release
from troi.operations import is_homogeneous
from troi.print_recording import PrintRecordingList
from troi.tools.spotify_lookup import lookup_spotify_ids, fixup_spotify_playlist
from troi.tools.spotify_lookup import submit_to_spotify

LISTENBRAINZ_SERVER_URL = "https://listenbrainz.org"
LISTENBRAINZ_API_URL = "https://api.listenbrainz.org"
Expand Down Expand Up @@ -244,52 +242,16 @@ def submit_to_spotify(self,
submitted = []

for idx, playlist in enumerate(self.playlists):

if len(playlist.recordings) == 0:
continue
filtered_recordings = [r for r in playlist.recordings if r.mbid]

_, mbid_spotify_index, spotify_mbid_index = lookup_spotify_ids(filtered_recordings)
spotify_track_ids = [r.spotify_id for r in filtered_recordings if r.spotify_id]
if len(spotify_track_ids) == 0:
continue

print("submit %d tracks" % len(spotify_track_ids))

playlist_id, playlist_url = None, None
existing_url = None
if existing_urls and idx < len(existing_urls) and existing_urls[idx]:
# update existing playlist
playlist_url = existing_urls[idx]
playlist_id = playlist_url.split("/")[-1]
try:
sp.playlist_change_details(playlist_id=playlist_id, name=playlist.name, description=playlist.description)
except SpotifyException as err:
# one possibility is that the user has deleted the spotify from playlist, so try creating a new one
print("provided playlist url has been unfollowed/deleted by the user, creating a new one")
playlist_id, playlist_url = None, None

if not playlist_id:
# create new playlist
spotify_playlist = sp.user_playlist_create(user=user_id,
name=playlist.name,
public=is_public,
collaborative=is_collaborative,
description=playlist.description)
playlist_id = spotify_playlist["id"]
playlist_url = spotify_playlist["external_urls"]["spotify"]
else:
# existing playlist, clear it
sp.playlist_replace_items(playlist_id, [])
existing_url = existing_urls[idx]

# spotify API allows a max of 100 tracks in 1 request
for chunk in chunked(spotify_track_ids, 100):
sp.playlist_add_items(playlist_id, chunk)

fixup_spotify_playlist(sp, playlist_id, mbid_spotify_index, spotify_mbid_index)
playlist_url, playlist_id = submit_to_spotify(sp, playlist, user_id, is_public, is_collaborative, existing_url)
submitted.append((playlist_url, playlist_id))

playlist.add_metadata({"external_urls": {"spotify": playlist_url}})

return submitted


Expand Down
54 changes: 54 additions & 0 deletions troi/tools/spotify_lookup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import requests
import spotipy
from more_itertools import chunked
from spotipy import SpotifyException

SPOTIFY_IDS_LOOKUP_URL = "https://labs.api.listenbrainz.org/spotify-id-from-mbid/json"

Expand Down Expand Up @@ -113,3 +114,56 @@ def fixup_spotify_playlist(sp: spotipy.Spotify, playlist_id: str, mbid_spotify_i
# spotify API allows a max of 100 tracks in 1 request
for chunk in chunked(finalized_ids, 100):
sp.playlist_add_items(playlist_id, chunk)


def submit_to_spotify(spotify, playlist, spotify_user_id: str, is_public: bool = True,
is_collaborative: bool = False, existing_url: str = None):
""" Submit or update an existing spotify playlist.
If existing urls are specified then is_public and is_collaborative arguments are ignored.
"""
filtered_recordings = [r for r in playlist.recordings if r.mbid]

_, mbid_spotify_index, spotify_mbid_index = lookup_spotify_ids(filtered_recordings)
spotify_track_ids = [r.spotify_id for r in filtered_recordings if r.spotify_id]
if len(spotify_track_ids) == 0:
return None, None

print("submit %d tracks" % len(spotify_track_ids))

playlist_id, playlist_url = None, None
if existing_url:
# update existing playlist
playlist_url = existing_url
playlist_id = existing_url.split("/")[-1]
try:
spotify.playlist_change_details(playlist_id=playlist_id, name=playlist.name, description=playlist.description)
except SpotifyException as err:
# one possibility is that the user has deleted the spotify from playlist, so try creating a new one
print("provided playlist url has been unfollowed/deleted by the user, creating a new one")
playlist_id, playlist_url = None, None

if not playlist_id:
# create new playlist
spotify_playlist = spotify.user_playlist_create(
user=spotify_user_id,
name=playlist.name,
public=is_public,
collaborative=is_collaborative,
description=playlist.description
)
playlist_id = spotify_playlist["id"]
playlist_url = spotify_playlist["external_urls"]["spotify"]
else:
# existing playlist, clear it
spotify.playlist_replace_items(playlist_id, [])

# spotify API allows a max of 100 tracks in 1 request
for chunk in chunked(spotify_track_ids, 100):
spotify.playlist_add_items(playlist_id, chunk)

fixup_spotify_playlist(spotify, playlist_id, mbid_spotify_index, spotify_mbid_index)

playlist.add_metadata({"external_urls": {"spotify": playlist_url}})

return playlist_url, playlist_id

0 comments on commit cb01f34

Please sign in to comment.