def suggest_audio_features_tags(tracks): tags = [] token = sp_oauth.get_cached_token()['access_token'] sp = Spotify(token) track_ids = [t['track']['id'] for t in tracks][:min(len(tracks), 100)] audio_features = sp.audio_features(tracks=track_ids) if average_field(audio_features, 'danceability') > .75: tags.append(Tag.objects.get(name="Party", category=TAG_CATEGORY_MOOD)) avg_tempo = average_field(audio_features, 'tempo') if avg_tempo > 120 and avg_tempo < 150: tags.append(Tag.objects.get(name="Roadtrip", category=TAG_CATEGORY_MOOD)) avg_energy = average_field(audio_features, 'energy') avg_valence = average_field(audio_features, 'valence') # Refactor this bullshit mess # No magic numbers if avg_energy > .7 and avg_valence > .7: tags.append(Tag.objects.get(name="Upbeat", category=TAG_CATEGORY_MOOD)) elif avg_energy < .4 and avg_valence > .7: tags.append(Tag.objects.get(name="Relaxed", category=TAG_CATEGORY_MOOD)) elif avg_energy < .4 and avg_valence < .4: tags.append(Tag.objects.get(name="Melancholy", category=TAG_CATEGORY_MOOD)) elif avg_energy > .7 and avg_valence < .4: tags.append(Tag.objects.get(name="Angry", category=TAG_CATEGORY_MOOD)) return tags
def share(request): access_token = get_token(request) uri = request.POST['uri'] # ToDo: Gracefully handle errors # URI FORMAT: spotify:user:1210159879:playlist:0v5PyzDU1jZIN7zgvpFfFb tokens = uri.split(':') user = tokens[2] pid = tokens[4] sp = Spotify(access_token) playlist = sp.user_playlist(user=user, playlist_id=pid) tracks = playlist['tracks']['items'] suggested_tags = suggest_tags(tracks) # This can possibly be made more efficient... all_tags = Tag.objects.all() tags = { 'mood': all_tags.filter(category=TAG_CATEGORY_MOOD), 'genre': all_tags.filter(category=TAG_CATEGORY_GENRE) } return render(request, 'tag-and-share.html', {'playlist': playlist, 'suggested_tags': suggested_tags, 'tags': tags})
def get_playlist_genres(tracks, suggestion_count): # Pagination should happen, at some point above. artists_num_appearances = [] genres = [] token = sp_oauth.get_cached_token()['access_token'] sp = Spotify(token) # Assemble a list of all artists represented. for track in tracks: for artist in track['track']['artists']: artists_num_appearances.append(artist['id']) # Count it artists_num_appearances = Counter(artists_num_appearances) # Grab the 10 most common artists in the playlist, and get their genres. for artist_id, _ in artists_num_appearances.most_common(10): artist_info = sp.artist(artist_id) for genre in artist_info['genres']: genres.append(genre) # Count genres genre_counter = Counter(genres) top_n_genres = genre_counter.most_common(suggestion_count) # Resolve these to actual tag objects tags = [] for genre in top_n_genres: name = genre[0] tag = Tag.objects.get_or_create(name=name, category=TAG_CATEGORY_GENRE)[0] tags.append(tag) print tag return tags
def connect(self, response_code, redirect_uri): try: token_response = self.auth_api(redirect_uri).get_access_token(response_code) self.token = token_response['access_token'] sp = Spotify(auth=self.token) self.username = sp.me()['id'] self.state = self.CONNECTED except SpotifyOauthError: self.state = self.FAILED self.repository.save(self)
def spot_search(output): # try: artist = raw_input("Please enter artist: ") spot = Spotify() results = spot.search(q='artist:' + artist, type='artist') print "Found:", results[u'artists'][u'items'][0][u'name'] artist_uri = results[u'artists'][u'items'][0][u'uri'] choice = raw_input("Top 10 [T] or album [A]: ") if choice == 't' or choice == 'T': get_top_ten(artist_uri, spot, output) else: get_album(artist_uri, spot, output) print "Found:", results[u'artists'][u'items'][0][u'name']
def detail(request): id = request.GET['id'] mixd_playlist = Playlist.objects.get(id=id) access_token = get_token(request) sp = Spotify(access_token) playlist = sp.user_playlist(user=mixd_playlist.user_id, playlist_id=mixd_playlist.id) tags = TagInstance.objects.filter(playlist=mixd_playlist) return render(request, 'playlist.html', {'playlist': playlist, 'description': mixd_playlist.description, 'tags': tags})
def list(request): access_token = get_token(request) # Messy but OK for now. if not access_token: return auth(request) sp = Spotify(access_token) raw_playlists = Playlist.objects.all() playlists = [sp.user_playlist(user=playlist.user_id, playlist_id=playlist.id) for playlist in raw_playlists] for playlist in playlists: playlist['owner'] = sp.user(playlist['owner']['id']) playlist['tags'] = TagInstance.objects.filter(playlist_id=playlist['id']) return render(request, 'index.html', {'playlists': playlists})
def search(request): access_token = get_token(request) tag = request.GET['tag'] raw_playlists = Playlist.objects.filter(tags__name__exact=tag) access_token = sp_oauth.get_cached_token()['access_token'] sp = Spotify(access_token) playlists = [sp.user_playlist(user=playlist.user_id, playlist_id=playlist.id) for playlist in raw_playlists] for playlist in playlists: playlist['owner'] = sp.user(playlist['owner']['id']) playlist['tags'] = TagInstance.objects.filter(playlist_id=playlist['id']) return render(request, 'index.html', {'playlists': playlists})
def login_spotify(): """ Log into Spotify and retrieve user playlists """ scope = 'playlist-modify-public playlist-modify-private' token = util.prompt_for_user_token(config.auth['SPOTIFY_EMAIL'], scope) if not token: log.error("Invalid Spotify token; exiting.") sys.exit(1) s = Spotify(auth=token) s.username = config.auth['SPOTIFY_USERNAME'] playlists = s.user_playlists(s.username)['items'] s.playlists = {} for sl in playlists: s.playlists[sl['name']] = sl return s
def __init__(self, spotify_user_data): self.user_name = spotify_user_data['user_name'] token = spotipy.util.prompt_for_user_token( self.user_name, scope='user-follow-read', client_id=spotify_user_data['client_id'], client_secret=spotify_user_data['client_secret'], redirect_uri=spotify_user_data['redirect_uri'] ) self.spotify = Spotify(auth=token) self.cache_path = settings.CACHE_PATH_PATTERN.format(self.user_name) self.is_first_run = is_first_run(self.cache_path) self.cache = AlreadyHandledCache(self.cache_path)
def spotify_auth(self): scope = os.getenv("scope") try: token = util.prompt_for_user_token( username=self.username, \ scope=scope, \ client_id=self.client_id, \ redirect_uri=self.redirect_uri, \ client_secret=self.client_secret) if token: sp = Spotify(auth=token) return sp except spotipy.client.SpotifyException: token = util.prompt_for_user_token( username=self.username, \ scope=scope, \ client_id=self.client_id, \ redirect_uri=self.redirect_uri, \ client_secret=self.client_secret) sp = Spotify(auth=token) return sp
class Spotify_client: def __init__(self, scope='playlist-modify-private', *args, **kwargs): client_id = getenv('SPOTIFY_client_id') client_secret = getenv('SPOTIFY_client_secret') self.username = getenv('SPOTIFY_username') redirect_uri = getenv('SPOTIFY_redirect_uri') # login logging.info("Starting Spotify client") token = util.prompt_for_user_token(self.username, scope, client_id=client_id, client_secret=client_secret, redirect_uri=redirect_uri) self.sp_client = Spotify(auth=token) def create_playlist(self, playlist_name): logging.debug(f'playlist_name: {playlist_name}') return self.sp_client.user_playlist_create(user=self.username, name=playlist_name, public=False) def search_track(self, search_string): logging.debug(f'search_string: {search_string}') return self.sp_client.search(search_string, limit=1) def search_album(self, album_name, artist_name): artist_string = f'artist:"{artist_name}"' \ if artist_name and "various" not in artist_name.lower() \ else "" search_string = f'album:"{album_name}" {artist_string}' logging.debug(search_string) return self.sp_client.search(search_string, limit=1, type="album") def add_to_playlist(self, playlist_id, track_ids): logging.debug(f'playlist_id: {playlist_id}, track_ids: {track_ids}') return self.sp_client.playlist_add_items(self.username, playlist_id, track_ids)
def load_more_tracks(self): # this is crude, but it means we don't need to handle expired tokens # TODO: address this when it's clear what Jodal and the team want to do with Pyspotify self.refresh_spotify_token() try: token = self.spotify_token token = token['access_token'] except: logger.error('IrisFrontend: access_token missing or invalid') pusher.broadcast( 'error', { 'source': 'load_more_tracks', 'message': 'access_token missing or invalid' }) try: spotify = Spotify(auth=token) response = spotify.recommendations( seed_artists=self.radio['seed_artists'], seed_genres=self.radio['seed_genres'], seed_tracks=self.radio['seed_tracks'], limit=5) uris = [] for track in response['tracks']: uris.append(track['uri']) self.core.tracklist.add(uris=uris) except: pusher.broadcast( 'error', { 'source': 'load_more_tracks', 'message': 'Failed to fetch Spotify recommendations' }) logger.error( 'IrisFrontend: Failed to fetch Spotify recommendations')
def __init__(self, mail, password, token=None): self.spo = Spotify( auth = generate_token() ) self.req = requests.Session() check = self.get_api("deezer.getUserData")['checkFormLogin'] post_data = { "type": "login", "mail": mail, "password": password, "checkFormLogin": check } end = self.req.post( "https://www.deezer.com/ajax/action.php", post_data ).text if "success" == end: print("Success, you are in :)") else: if not token: raise exceptions.BadCredentials(end + ", and no token provided") self.req.cookies['arl'] = token user_id = ( self.req.get("https://www.deezer.com/") .text .split("'deezer_user_id': ")[1] .split(",")[0] ) if user_id == "0": raise exceptions.BadCredentials("Wrong token :(")
def load_more_tracks( self ): # this is crude, but it means we don't need to handle expired tokens # TODO: address this when it's clear what Jodal and the team want to do with Pyspotify self.refresh_spotify_token() try: token = self.spotify_token token = token['access_token'] except: logger.error('SpotmopFrontend: access_token missing or invalid') try: spotify = Spotify( auth = token ) response = spotify.recommendations(seed_artists = self.radio['seed_artists'], seed_genres = self.radio['seed_genres'], seed_tracks = self.radio['seed_tracks'], limit = 5) uris = [] for track in response['tracks']: uris.append( track['uri'] ) self.core.tracklist.add( uris = uris ) except: logger.error('SpotmopFrontend: Failed to fetch recommendations from Spotify')
def save_new_releases(): """Saves all new releases released yesterday by the specified Spotify user's followed artists to their library. We check for yesterday so that all releases released throughout that day are picked up (trying to get today's releases has a chance of missing anything released after this script is run).""" setup_logging("new_releases.log") args = _extract_args() spotify = Spotify(auth=token.get_token( args.spotify_user, args.spotify_client_id_key, args.spotify_client_secret_key, )) yesterday = date.today() - timedelta(days=1) if args.save_albums_to_liked_songs: _save_new_tracks( spotify, args.lastfm_user, args.lastfm_api_key, args.ignore_remixes, args.ignore_scrobbled_songs, yesterday, # Save all types of albums straight to Liked Songs [album.SINGLE_ALBUM_TYPE, album.ALBUM_ALBUM_TYPE], ) else: _save_new_tracks( spotify, args.lastfm_user, args.lastfm_api_key, args.ignore_remixes, args.ignore_scrobbled_songs, yesterday, # Save only single-type albums to Liked Songs [album.SINGLE_ALBUM_TYPE], ) new_albums = new_releases.fetch_new_albums( spotify, album_types=[album.ALBUM_ALBUM_TYPE], as_of_date=yesterday) if len(new_albums) > 0: library.add_albums_to_library(spotify, new_albums) else: logging.info("No new albums to add!") logging.info("Done!")
def track_search(sp: spotipy.Spotify, query: str) -> Optional[Any]: try: results = sp.search(q=query, limit=5) if results and results['tracks'] and results['tracks']['items']: for item in results['tracks']['items']: if item['id'] not in FOUND_TRACKS: FOUND_TRACKS.add(item['id']) print(f'Search result: {item["name"]}, Query: {query}') return item except: pass print(f'Search result: {None}, Query: {query}') return None
def spotify_artists(token, user): spotify_client = Spotify(auth=token) async_q(playlist_artists, spotify_client, user, hook='concertowl.apis.spotify._got_artists') async_q(saved_artists, spotify_client, user, hook='concertowl.apis.spotify._got_artists') async_q(followed_artists, spotify_client, user, hook='concertowl.apis.spotify._got_artists')
def album_from_title_artist( title: str, artists: List[str], sp: spotipy.Spotify ) -> Optional[Album]: """ Return an album """ q = query(title, artists) if q in search_memo: search_result = search_memo[q] else: search_result = sp.search(q, type="album", limit=50) print(f"Key error looking up the query {q}") album_id = find_album_id_from_search(search_result, artists) if album_id: try: tracks = album_tracks_memo[album_id] except KeyError: tracks = sp.album_tracks(album_id) print(f"Key error looking up the track with id {album_id}") return Album( title, album_id, artists, [ Song( title=item["name"], uri=item["uri"], features={}, artists=[artist["name"] for artist in item["artists"]], ) for item in tracks["items"] ], ) return None
async def get_spotify_playlist(url): # Url can be a spotify url or uri. user = '' playlist_id = '' songs = [] token = prompt_for_user_token('mdeception', 'user-library-read') spotify = Spotify(auth=token) if not 'http' in url: user = url.split('user:'******':')[0] playlist_id = url.split(':')[-1] else: user = url.split('user/')[1].split('/')[0] playlist_id = url.split('/')[-1] playlist = spotify.user_playlist(user, playlist_id, fields='tracks, next, name') tracks = playlist['tracks'] for t in tracks['items']: track = t['track'] songs.append('%s %s' % (track['name'], ' & '.join(x['name'] for x in track['artists']))) while tracks['next']: tracks = spotify.next(tracks) for t in tracks['items']: track = t['track'] songs.append( '%s %s' % (track['name'], ' & '.join(x['name'] for x in track['artists']))) return (playlist['name'], user, songs)
def callback(request): spotify_oauth = SpotifyOAuth( settings.SPOTIPY_CLIENT_ID, settings.SPOTIPY_CLIENT_SECRET, settings.SPOTIPY_REDIRECT_URI, scope='user-read-email playlist-modify-public user-follow-modify') oauth_token = request.GET.get('code') access_token = spotify_oauth.get_access_token(oauth_token) spotify = Spotify(auth=access_token.get('access_token')) me = spotify.me() # Check spotify session current_user = None user = None try: current_user = SpotifySession.objects.get(username=me['id']) user = current_user.user user.backend = 'django.contrib.auth.backends.ModelBackend' except: current_user = SpotifySession(username=me.get('id')) # Create this current_user.access_token = access_token.get('access_token') current_user.refresh_token = access_token.get('refresh_token') current_user.expires_in = access_token.get('expires_in') password = get_random_string(length=32) user = User.objects.create_user(me['id'], me['email'], password) user.backend = 'django.contrib.auth.backends.ModelBackend' user.save() current_user.user = user current_user.save() if user is not None: if user.is_active: login(request, user) return HttpResponseRedirect('/dashboard')
def get_top_artists(sp: spotipy.Spotify, amount: int = 20) -> list: """compiles list of user's top artists of length amount""" print('...getting top artists') artists_name = [] artists_uri = [] ranges = ['short_term', 'medium_term', 'long_term'] for r in ranges: all_top_artist_data = sp.current_user_top_artists(limit=amount, time_range=r) top_artist_data = all_top_artist_data['items'] for artist_data in top_artist_data: if artist_data['name'] not in artists_name: artists_name.append(artist_data['name']) artists_uri.append(artist_data['uri']) return artists_uri
def get_recent_tracks(username: str, sp: spotipy.Spotify) -> list: print('...getting the recent tracks from a user') ret = [] # afterTime = time.time() # afterTime = afterTime - 2629743 #one month ago # afterTime = afterTime - 604800 #one week ago # afterTime = math.floor(afterTime) recent_tracks = sp.current_user_recently_played() for item in recent_tracks['items']: track = item['track'] ret.append( dict(id=track['id'], artist=track['artists'][0]['name'], name=track['name'])) return ret
def akttym(): SCOPE = 'user-library-modify,user-read-playback-state' dir_path = os.path.dirname(os.path.realpath(__file__)) config = yaml.safe_load(open(dir_path + '/config.yaml')) check_config(config, dir_path) token = util.prompt_for_user_token(config['username'], SCOPE, client_id=config['client_id'], client_secret=config['client_secret'], redirect_uri='http://localhost:1911/', cache_path=dir_path + '/cache') if token: sp = Spotify(auth=token) track = sp.current_playback() if track is not None: sp.current_user_saved_tracks_add([track['item']['id']]) logging.warning("added %s to %s's library", track['item']['name'], config['username']) else: logging.warning("nothing is playing currently, aborting") else: logging.warning("Can't get token for %s", config['username'])
def get_artists_top_tracks(sp: spotipy.Spotify, artists_uri: list, amount: int = 50) -> list: # compiles list of top tracks made by artists in artists_uri of length amount print('...getting top tracks for each artist') tracks = [] for artist in artists_uri: all_top_tracks_data = sp.artist_top_tracks(artist) top_tracks_data = all_top_tracks_data['tracks'] for track_data in top_tracks_data: tracks.append( dict(id=track_data['id'], artist=track_data['artists'][0]['name'], name=track_data['name'])) return tracks
def download_playlist(username,playlist_id,credential_file_location): from spotipy import Spotify,util from json import load #import the credentials credentials = load(open(credential_file_location)) #Create an authenticated connection scope = 'playlist-modify-public' token = util.prompt_for_user_token(username,scope=scope,client_id=credentials['client_id'], client_secret=credentials['client_secret'], redirect_uri=credentials['redirect_url']) connection = Spotify(auth=token) #Mine the songs songs = [] for track in connection.user_playlist(username, playlist_id,fields="tracks,next")['tracks']['items']: songs.append((track['track']['artists'][0]['name'],track['track']['name'])) #Gebruikersnaaam lostrekken, geheimen lostrekken return songs
def download_name(self, artist, song, output=stock_output + "/", quality=stock_quality, recursive_quality=stock_recursive_quality, recursive_download=stock_recursive_download, not_interface=stock_not_interface): query = "track:{} artist:{}".format(song, artist) try: search = self.spo.search(query) except: self.spo = Spotify(generate_token()) search = self.spo.search(query) try: return self.download_trackspo( search['tracks']['items'][0]['external_urls']['spotify'], output, quality, recursive_quality, recursive_download, not_interface) except IndexError: raise exceptions.TrackNotFound("Track not found: :(")
def get_connection(client_id, client_secret, send_auth_request, callback_url): scope = "user-library-modify,user-library-read,playlist-read-private,user-read-private,user-read-email" auth_manager = SpotifyOAuth( client_id, client_secret, callback_url, scope=scope, open_browser=False ) url = auth_manager.get_authorize_url() click.echo(f"Auth URL: {url}") if auth_manager.get_cached_token() is None: send_auth_request(url) start_local_http_server(30001) return Spotify(auth_manager=auth_manager)
class Spotify_client: def __init__(self, *args, **kwargs): client_id = getenv('SPOTIFY_client_id') client_secret = getenv('SPOTIFY_client_secret') self.username = getenv('SPOTIFY_username') redirect_uri = getenv('SPOTIFY_redirect_uri') scope = 'playlist-modify-private' # login logging.info("Starting Spotify client") token = util.prompt_for_user_token(self.username,scope,client_id=client_id,client_secret=client_secret,redirect_uri=redirect_uri) self.sp_client = Spotify(auth=token) def create_playlist(self, playlist_name): logging.debug(f'playlist_name: {playlist_name}') return self.sp_client.user_playlist_create(user=self.username, name=playlist_name, public=False) def search_track(self, search_string): logging.debug(f'search_string: {search_string}') return self.sp_client.search(search_string, limit=1) def add_to_playlist(self, playlist_id, track_ids): logging.debug(f'playlist_id: {playlist_id}, track_ids: {track_ids}') return self.sp_client.user_playlist_add_tracks(self.username, playlist_id, track_ids)
def renew(): global sp token_info = sp_oauth.get_cached_token() if token_info: # Retieve token from memory access_token = token_info['access_token'] # Log in again at Spotify sp = Spotify(access_token) return True else: # Logout if this is not possible logout() return False
def download_trackspo( self, URL, output = stock_output + "/", quality = stock_quality, recursive_quality = stock_recursive_quality, recursive_download = stock_recursive_download, not_interface = stock_not_interface ): if "?" in URL: URL, a = URL.split("?") try: url = self.spo.track(URL) except Exception as a: if not "The access token expired" in str(a): raise exceptions.InvalidLink("Invalid link ;)") self.spo = Spotify( auth = generate_token() ) url = self.spo.track(URL) isrc = url['external_ids']['isrc'] url = request( "https://api.deezer.com/track/isrc:" + isrc, True ).json() name = self.download_trackdee( url['link'], output, quality, recursive_quality, recursive_download, not_interface ) return name
def make_auth(self): # TODO : 커스텀 CLIENT_ID / CLIENT_SECRET 사용 가능하게 """ CONFIG.py의 CLIENT_ID와 CLIENT_SECRET을 이용하여 인증합니다. Returns: 성공적으로 인증하면 spotipy.Spotify를 리턴합니다. """ cred = SpotifyClientCredentials( client_id=CONFIG.CLIENT_ID, client_secret=CONFIG.CLIENT_SECRET, requests_timeout=5, ) sp = Spotify(client_credentials_manager=cred) self.spoti = sp
def download_playlistspo(URL, output=stock_output + "/", recursive_download=stock_recursive_download, not_interface=stock_not_interface, zips=stock_zip): global spo array = [] URL = (URL.split("?")[0].split("/")) try: tracks = spo.user_playlist_tracks(URL[-3], URL[-1]) except Exception as a: if not "The access token expired" in str(a): raise exceptions.InvalidLink("Invalid link ;)") spo = Spotify(generate_token()) tracks = spo.user_playlist_tracks(URL[-3], URL[-1]) def lazy(tracks): for a in tracks['items']: try: array.append( download_trackspo(a['track']['external_urls']['spotify'], output, recursive_download, not_interface)) except: print("Track not found :(") array.append("None") lazy(tracks) tot = tracks['total'] for a in range(tot // 100 - 1): try: tracks = spo.next(tracks) except: spo = Spotify(generate_token()) tracks = spo.next(tracks) lazy(tracks) if zips: zip_name = "{}playlist {}.zip".format(output, URL[-1]) create_zip(zip_name, array) return array, zip_name return array
def trackInPlaylist(spotify: Spotify, trackname, playlist): result = spotify.playlist_tracks(playlist, offset=0, limit=50) while result["next"]: try: if result["items"]["track"][trackname]: print("match") return True except KeyError: result = spotify.next(result) '''for track in result["items"]: track = track["track"] if track["name"] == trackname: print("match") print(trackname) return True''' #result = spotify.next(result) print("miss") print(trackname) return False
def main(): vertices_path = os.environ.get("VERTICES_PATH") edges_path = os.environ.get("EDGES_PATH") playlists_path = os.environ.get("PLAYLISTS_PATH") spotify = Spotify(auth_manager=SpotifyClientCredentials()) audio_features = [ "danceability", "energy", "key", "loudness", "mode", "speechiness", "acousticness", "instrumentalness", "liveness", "valence", "tempo", "duration_ms", "time_signature" ] if vertices_path and edges_path: print("Loading graph from file") vertices = pd.read_csv(vertices_path) edges = pd.read_csv(edges_path) network = Network.from_dataframe(spotify=spotify, audio_features=audio_features, max_tracks=50, vertices=vertices, edges=edges) print( f"Loaded {len(network.graph.nodes)} nodes and {len(network.graph.edges)}" ) else: network = Network(spotify=spotify, audio_features=audio_features, max_tracks=50) print("Adding new tracks and artists via seed playlists") playlist_names = read_lines(playlists_path) for name, playlist_id in playlist_names: start_time = time.time() playlist = network.get_playlist(playlist_id=playlist_id) if not playlist: continue print(f"Exploring via playlist: {playlist.name} ({playlist.id})") add_artists(network, playlist.get_artists(), 0, 2) print( f"Writing {len(network.graph.nodes)} nodes and {len(network.graph.edges())} edges to file" ) vertices, edges = network.graph.to_dataframe() vertices.to_csv(f"vertices_{name}.csv", index=False) edges.to_csv(f"edges_{name}.csv", index=False) print(f"Completed: {time.time() - start_time}")
def search_album( sp: Spotify, album: str, artist: Optional[str] = None, year: Optional[int] = None, limit: int = 5, ) -> List[Dict[str, Any]]: """Returns the search results for albums given an album query Artist and year are optional """ query = f"album:{album}" if artist is not None: query += f" artist:{artist}" if year is not None: query += f" year:{year}" return sp.search(query, limit=limit, type="album")["albums"]
def get_spotify_track_id(spot_client: spotipy.Spotify, song: str) -> Optional[str]: try: response = spot_client.search(q=song, type='track', limit=1) if response and len(response) > 0 and 'tracks' in response and response['tracks'] \ and len(response['tracks']) > 0: tracks = response['tracks'] if 'items' in tracks and tracks['items'] and len(tracks['items']) > 0 and tracks['items'][0] \ and 'id' in tracks['items'][0] and tracks['items'][0]['id'] \ and len(tracks['items'][0]['id']) > 0: return tracks['items'][0]['id'] except spotipy.client.SpotifyException as spot_except: print(f"Error in looking up {song}.\nMore info:\n{str(spot_except)}") return None
def archive_discover_weekly_playlist( spotify_instance: Spotify, spotify_handler: SpotifyHandler, user_id: str, playlist_name: str, description: str = None, ) -> dict: if spotify_handler.is_discover_weekly_playlist_already_in_spotify( playlist_name): raise ValueError( "Error: Discover Weekly playlist is already archived.") new_dwp = spotify_instance.user_playlist_create(user_id, playlist_name, description) return new_dwp
def create_playlist(sp: spotipy.Spotify, user_id: str, name: str, save_info=False, indent=4) -> str: """creates new playlist and returns its id; if save_info=True, saves playlist info to file""" results = sp.user_playlist_create(user_id, name) if save_info: with open(f"{name}_playlist_data.json", mode="w", encoding="utf-8", newline="\n") as file: json.dump(results, file, indent=indent) return results["id"]
def __init__(self, sp_client_id: str, sp_client_secret: str, sp_username: str, sp_redirect_uri: str, sp_scope: str): self.client_id: str = sp_client_id self.secret: str = sp_client_secret self.username: str = sp_username self.redirect_uri: str = sp_redirect_uri self.scope: str = sp_scope self.sp_oauth: SpotifyOAuth = SpotifyOAuth( username=sp_username, client_id=sp_client_id, client_secret=sp_client_secret, redirect_uri=sp_redirect_uri, scope=sp_scope) self.token: str = str() self.token_info: dict = dict() self.sp_api: Spotify = Spotify()
def get_album_uri(spotify: Spotify, name: str) -> str: """ :param spotify: Spotify object to make the search from :param name: album name :return: Spotify uri of the desired album """ # Replace all spaces in name with '+' original = name name = name.replace(' ', '+') results = spotify.search(q=name, limit=1, type='album') if not results['albums']['items']: raise InvalidSearchError(f'No album named "{original}"') album_uri = results['albums']['items'][0]['uri'] return album_uri
def spotify_auth(): username = os.getenv("username") password = os.getenv("password") client_id = os.getenv("client_id") client_secret = os.getenv("client_secret") redirect_uri = os.getenv("redirect_uri") scope = os.getenv("scope") token = util.prompt_for_user_token( username=username, \ scope=scope, \ client_id=client_id, \ redirect_uri=redirect_uri, \ client_secret=client_secret) if token: sp = Spotify(auth=token) return sp
class SpotifyClient: def __init__(self): token = self.get_token() self.sp = Spotify(auth=token) def get_token(self): scope = 'playlist-modify-private' return util.prompt_for_user_token( SPOTIFY_AUTH['USERNAME'], scope, client_id=SPOTIFY_AUTH['CLIENT_ID'], client_secret=SPOTIFY_AUTH['CLIENT_SECRET'], redirect_uri=SPOTIFY_AUTH['REDIRECT_URI']) def search_album(self, album_name, artist_name): results = self.sp.search(q=album_name, limit=20, type="album") for album in results["albums"]["items"]: if 'GB' in album['available_markets']: return album def get_album(self, album_name, artist_name): album_id = self.search_album(album_name, artist_name) try: return self.sp.album(album_id['uri']) except TypeError: return {"tracks": []} def get_album_tracks(self, album_name, artist_name): try: return self.get_album(album_name, artist_name)['tracks'] except TypeError: return None def list_track_ids(self, album_name, artist_name): track_ids = [] album_items = self.get_album_tracks(album_name, artist_name) if album_items: for track in album_items['items']: track_ids.append(track['id']) return track_ids def get_playlist(self): return self.sp.user_playlist(SPOTIFY_AUTH['USERNAME'], TARGET_PLAYLIST) def get_playlist_track_ids(self): track_ids = [] offset = 0 tracks = self.sp.user_playlist_tracks( SPOTIFY_AUTH['USERNAME'], TARGET_PLAYLIST, None, 100, offset) track_items = tracks['items'] while tracks['next']: # Paginate offset = offset + 100 tracks = self.sp.user_playlist_tracks( SPOTIFY_AUTH['USERNAME'], TARGET_PLAYLIST, None, 100, offset) track_items = track_items + tracks['items'] if len(track_items) > 0: for track in track_items: track_ids.append(track["track"]['id']) return track_ids def add_tracks(self, track_id_list): playlist_id = self.get_playlist()['id'] self.sp.user_playlist_add_tracks(SPOTIFY_AUTH['USERNAME'], playlist_id, track_id_list)
def __init__(self): token = self.get_token() self.sp = Spotify(auth=token)
class SpotifyReleaseGun(object): def __init__(self, spotify_user_data): self.user_name = spotify_user_data['user_name'] token = spotipy.util.prompt_for_user_token( self.user_name, scope='user-follow-read', client_id=spotify_user_data['client_id'], client_secret=spotify_user_data['client_secret'], redirect_uri=spotify_user_data['redirect_uri'] ) self.spotify = Spotify(auth=token) self.cache_path = settings.CACHE_PATH_PATTERN.format(self.user_name) self.is_first_run = is_first_run(self.cache_path) self.cache = AlreadyHandledCache(self.cache_path) def get_ids_of_followed_artists(self): result = [] last_artist_id = None while True: artist_result = self.spotify.\ current_user_followed_artists(50, last_artist_id) artists = artist_result['artists']['items'] if not artists: break for artist in artists: last_artist_id = artist['id'] result.append(artist['id']) return result def filter_releases(self, artist_releases): release_ids = [release.release_id for release in artist_releases] reduced_ids = self.cache.reduce(release_ids) filtered = filter( lambda release: release.release_id in reduced_ids, artist_releases ) return list(filtered) def get_releases_per_artist(self, artist_ids, limit=settings.LAST_N_RELEASES): releases_per_artist_id = {} for artist_id in artist_ids: artist_releases = [] try: # Albums result_albums = self.spotify.artist_albums( artist_id=artist_id, album_type='Album', country=settings.SPOTIFY_MARKET, limit=limit ) albums = [SpotifyRelease(d) for d in result_albums['items']] artist_releases.extend(albums) # Singles result_singles = self.spotify.artist_albums( artist_id=artist_id, album_type='Single', country=settings.SPOTIFY_MARKET, limit=limit ) singles = [SpotifyRelease(d) for d in result_singles['items']] artist_releases.extend(singles) except ConnectionError: print(("> Could not establish connection while " "fetching releases for artist with id {}. " "Skipping.").format(artist_id)) except JSONDecodeError: print(("> Could not decode JSON response " "of artist with id {}. Skipping.").format(artist_id)) filtered_releases = self.filter_releases(artist_releases) if filtered_releases: releases_per_artist_id[artist_id] = filtered_releases return releases_per_artist_id def get_releases_of_artists(self): artist_ids = self.get_ids_of_followed_artists() print("> {} followed artists found.".format(len(artist_ids))) releases_per_artist = self.get_releases_per_artist(artist_ids) return releases_per_artist def process(self, to_console=True): print("> Start ({}).".format(datetime.now())) releases = self.get_releases_of_artists() if to_console: send_to_console(releases, self.user_name) if settings.REALLY_SIMPLE_RSS_SERVER_URL: send_to_really_simple_rss_server(releases, self.user_name) if settings.SLACK_URL: send_to_slack(releases, self.user_name) print("> Done ({}).".format(datetime.now()))