def song_album_data(app_token,album_name,connection): spotify = tk.Spotify(app_token) albums, = spotify.search('kendrick lamar to pimp a butterfly',types=('album',), limit=1) album = albums.items[0] spotify = tk.Spotify(app_token) album = spotify.album(album.id) for track in album.tracks.items: track_uri_length = len(track.uri) track_uri = track.uri[14:track_uri_length] track_info = spotify.track_audio_features(track_uri) data_tuple = (track_info.id,album.id,'null', track.name,track.track_number, track_info.acousticness, track_info.danceability, track_info.duration_ms, track_info.energy, track_info.instrumentalness, track_info.key, track_info.liveness, track_info.loudness, track_info.mode, track_info.speechiness, track_info.tempo, track_info.time_signature, track_info.valence) insert_songs(connection,data_tuple)
def lambda_handler(tracks_file_name, context): """ Lambda handler for the action of querying spotify for all information related to spotify-artists by artist-id. This function reads the S3 object CSV file containing the artist-ids for the tracks and queries Spotify to get the metadata about all those artists. This metadata is compiled into a CSV file as a table with primary key being album-id. This CSV is uploaded to S3. :param tracks_file_name: S3 file containing track-metadata with album-ids for tracks recently listened to :param context: :return: uploaded S3 file name for file containing artist-metadata """ # Read S3 Event to get the created csv file containing track-ids to query tracks_df = soundprintutils.download_df_from_s3_csv( tracks_file_name, TrackerCommon.SCHEMA) artist_ids = list(set(tracks_df[TrackerCommon.ARTIST_ID[0]].dropna())) # Get Spotify access token and initialize Spotify client access_token = soundprintutils.get_access_token() spotify = tk.Spotify(access_token) # Extract all data related to the artists artists_df = get_artists_data(spotify, artist_ids) # Upload dataframe to S3 as CSV artists_file_name = f"{ArtisterCommon.FILE_PATH_PREFIX}{tracks_file_name.split(TrackerCommon.FILE_PATH_PREFIX)[1]}" soundprintutils.upload_df_to_s3_csv(df=artists_df, include_index=False, file_name=artists_file_name) return artists_file_name
def __init__(self, *args, **kwargs): """ The constructor for the Track class. Parameters: args (*tuple): Positional args for the Player class. kwargs (**dict): Keyword args for the Player class. """ super().__init__(*args, **kwargs) self.context: commands.Context = kwargs.get('context', None) if self.context: self.dj: discord.Member = self.context.author self.queue = asyncio.Queue() self.controller = None conf = (getenv('SPOTIFY_ID'), getenv('SPOTIFY_SECRET')) token = tk.request_client_token(*conf[:2]) self.spotify = tk.Spotify(token, asynchronous=True) self.waiting = False self.updating = False self.pause_votes = set() self.resume_votes = set() self.skip_votes = set() self.shuffle_votes = set() self.stop_votes = set() self.repeat_votes = set()
def __init__(self): self.sp = spotipy.Spotify(client_credentials_manager=SpotifyClientCredentials()) file = 'tekore.cfg' conf = tk.config_from_file(file, return_refresh=True) token = tk.refresh_user_token(*conf[:2], conf[3]) self.tk = tk.Spotify(token)
def app_client(app_token): """ Provides a client with an application token. """ sender = tk.RetryingSender(sender=tk.SyncSender()) yield tk.Spotify(app_token, sender=sender) sender.close()
async def app_aclient(app_token): """ Provides an asynchronous client with an application token. """ sender = tk.RetryingSender(sender=tk.AsyncSender()) yield tk.Spotify(app_token, sender=sender) await sender.close()
async def user_aclient(user_token): """ Provides an asynchronous client with a user token. """ sender = tk.RetryingSender(sender=tk.AsyncSender()) yield tk.Spotify(user_token, sender=sender) await sender.close()
async def preferences_from_platform( token: str, platform: str = Query(..., regex="^(spotify|genius)$"), ): """Get user preferences (genres and artists) based on user's activity on platform. """ if platform == "genius": auth_header = {"Authorization": f"Bearer {token}"} async with httpx.AsyncClient(headers=auth_header) as client: r = await client.get("https://api.genius.com/account") res = r.json() if r.status_code == 401: raise HTTPException(status_code=400, detail="Invalid token. " + res["error_description"]) else: spotify = tk.Spotify(token, asynchronous=True) try: await spotify.current_user() except (tk.BadRequest, tk.Unauthorised) as e: # pragma: no cover raise HTTPException( status_code=400, detail="Invalid token. " + e.response.content["error"]["message"], ) await spotify.close() pref = await recommender.preferences_from_platform(token, platform) return { "preferences": pref if pref is not None else Preferences(genres=[], artists=[]) }
def exportPlaylist(request): list_id = request.POST["playlilstid"] playlisttoexport = Playlist.objects.get(id=list_id) tracks = playlisttoexport.tracks.all() uris = [] for t in tracks: uri = "spotify:track:" + t.spotify_id uris.append(uri) app_token = tk.request_client_token(client_id, client_secret) spotify = tk.Spotify(app_token) user_token = tk.prompt_for_user_token(client_id, client_secret, redirect_uri, scope=tk.scope.every) spotify.token = user_token user = spotify.current_user() playlist = spotify.playlist_create( user.id, playlisttoexport.name, public=False, description='Generated By Ewan\'s Spotify Playlist Assist') spotify.playlist_add(playlist.id, uris=uris) #THIS IS WHERE ONE AVIODS COPYING PASTING INTO COSNOLE, COULDN'T QUITE WORK IT, FOR THE PURPOSES OF THIS PROJECT I DECIDED TO NOT WASTE MORE TIME ON IT #code = request.GET.get('', '') #token = cred.request_user_token(code) #with spotify.token_as(token): # info = spotify.current_user() # session['user'] = info.id # users[info.id] = token return HttpResponseRedirect(reverse("playlistlist"))
def lambda_handler(event, context): """ Lambda handler for the action of querying most recently heard tracks in the last 1 hour from Spotify and uploading the results into a CSV file in the S3 bucket. The CSV file follows the schema for ListenerCommon#SCHEMA. :return uploaded S3 file name with listening history """ # First, get access token access_token = soundprintutils.get_access_token() # Initialize Spotify client and query tracks played in the last hour spotify = tk.Spotify(access_token) current_timestamp_ms = int(datetime.now(tz=timezone.utc).timestamp() * 1000) snapshot_begin_timestamp_ms = current_timestamp_ms - 3600*1000 tracks_df = get_tracks_played_after(spotify, snapshot_begin_timestamp_ms) # Calculate time spent in listening to each track tracks_df = update_listened_to_durations(tracks_df, current_timestamp_ms) # Upload to S3 as a CSV dt = datetime.fromtimestamp(current_timestamp_ms/1000, tz=timezone.utc) s3_file_name = f"{ListenerCommon.FILE_PATH_PREFIX}{dt.year}/{dt.month}/{dt.day}/" \ f"{dt.hour}-{dt.day}-{dt.month}-{dt.year}.csv" soundprintutils.upload_df_to_s3_csv(df=tracks_df, include_index=False, file_name=s3_file_name) return s3_file_name
async def format_page( self, menu: menus.MenuPages, artist: tekore.model.FullArtist ) -> discord.Embed: self.current_track = artist em = discord.Embed(color=discord.Colour(0x1DB954)) url = f"https://open.spotify.com/artist/{artist.id}" artist_title = f"{artist.name}" em.set_author( name=artist_title, url=url, icon_url=SPOTIFY_LOGO, ) sp = tekore.Spotify(sender=menu.cog._sender) with sp.token_as(menu.user_token): cur = await sp.artist_top_tracks(artist.id, "from_token") msg = _("Top Tracks\n") for track in cur: msg += f"[{track.name}](https://open.spotify.com/track/{track.id})\n" em.description = msg if artist.images: em.set_thumbnail(url=artist.images[0].url) em.set_footer( text=_("Page") + f" {menu.current_page + 1}/{self.get_max_pages()}", ) return em
async def like_song(self, payload): """go to the next page""" try: user_spotify = tekore.Spotify(sender=self.cog._sender) with user_spotify.token_as(self.user_token): cur = await user_spotify.playback() if not cur: await self.ctx.send( _("I could not find an active device to send requests for.") ) await user_spotify.saved_tracks_add([self.source.current_track.id]) except tekore.Unauthorised: await self.ctx.send(_("I am not authorized to perform this action for you.")) except tekore.NotFound: await self.ctx.send(_("I could not find an active device to send requests for.")) except tekore.Forbidden as e: if "non-premium" in str(e): await self.ctx.send(_("This action is prohibited for non-premium users.")) else: await self.ctx.send(_("I couldn't perform that action for you.")) except tekore.HTTPError: log.exception("Error grabing user info from spotify") await self.ctx.send( _("An exception has occured, please contact the bot owner for more assistance.") ) await self.show_checked_page(0)
async def play_pause(self, payload): """go to the previous page""" try: user_spotify = tekore.Spotify(sender=self.cog._sender) with user_spotify.token_as(self.user_token): cur = await user_spotify.playback() if not cur: await self.ctx.send( _("I could not find an active device to send requests for.") ) return if cur.item.id == self.source.current_track.id: if cur.is_playing: await user_spotify.playback_pause() else: await user_spotify.playback_resume() else: if self.source.current_track.type == "track": await user_spotify.playback_start_tracks([self.source.current_track.id]) else: await user_spotify.playback_start_context(self.source.current_track.uri) except tekore.Unauthorised: await self.ctx.send(_("I am not authorized to perform this action for you.")) except tekore.NotFound: await self.ctx.send(_("I could not find an active device to send requests for.")) except tekore.Forbidden as e: if "non-premium" in str(e): await self.ctx.send(_("This action is prohibited for non-premium users.")) else: await self.ctx.send(_("I couldn't perform that action for you.")) except tekore.HTTPError: log.exception("Error grabing user info from spotify") await self.ctx.send( _("An exception has occured, please contact the bot owner for more assistance.") )
async def format_page( self, menu: menus.MenuPages, track: tekore.model.FullTrack ) -> discord.Embed: self.current_track = track em = discord.Embed(color=discord.Colour(0x1DB954)) url = f"https://open.spotify.com/track/{track.id}" artist_title = f"{track.name} by " + ", ".join(a.name for a in track.artists) em.set_author( name=track.name[:256], url=url, icon_url=SPOTIFY_LOGO, ) em.description = f"[{artist_title}]({url})\n" if track.album.images: em.set_thumbnail(url=track.album.images[0].url) if self.detailed: sp = tekore.Spotify(sender=menu.cog._sender) with sp.token_as(menu.user_token): details = await sp.track_audio_features(track.id) msg = await make_details(track, details) em.add_field(name="Details", value=box(msg[:1000], lang="css")) em.set_footer( text=_("Page") + f" {menu.current_page + 1}/{self.get_max_pages()}", ) return em
async def repeat(self, payload): """go to the next page""" try: user_spotify = tekore.Spotify(sender=self.cog._sender) with user_spotify.token_as(self.user_token): cur = await user_spotify.playback() if cur.repeat_state == "off": state = "context" if cur.repeat_state == "context": state = "track" if cur.repeat_state == "track": state = "off" await user_spotify.playback_repeat(state) except tekore.Unauthorised: await self.ctx.send(_("I am not authorized to perform this action for you.")) except tekore.NotFound: await self.ctx.send(_("I could not find an active device to send requests for.")) except tekore.Forbidden as e: if "non-premium" in str(e): await self.ctx.send(_("This action is prohibited for non-premium users.")) else: await self.ctx.send(_("I couldn't perform that action for you.")) except tekore.HTTPError: log.exception("Error grabing user info from spotify") await self.ctx.send( _("An exception has occured, please contact the bot owner for more assistance.") ) await asyncio.sleep(1) await self.show_checked_page(0)
async def get_page(self, page_number): """|coro| An abstract method that retrieves an object representing the object to format. Subclasses must implement this. .. note:: The page_number is zero-indexed between [0, :meth:`get_max_pages`), if there is a maximum number of pages. Parameters ----------- page_number: :class:`int` The page number to access. Returns --------- Any The object represented by that page. This is passed into :meth:`format_page`. """ try: user_spotify = tekore.Spotify(sender=self.sender) with user_spotify.token_as(self.user_token): cur_state = await user_spotify.playback() if not cur_state: raise NotPlaying is_liked = False if not cur_state.item.is_local: song = cur_state.item.id liked = await user_spotify.saved_tracks_contains([song]) is_liked = liked[0] except tekore.Unauthorised: raise return cur_state, is_liked
async def format_page( self, menu: menus.MenuPages, playlist: tekore.model.SimplePlaylist ) -> discord.Embed: self.current_track = playlist em = None em = discord.Embed(color=discord.Colour(0x1DB954)) url = f"https://open.spotify.com/playlist/{playlist.id}" artists = getattr(playlist, "artists", []) artist = humanize_list([a.name for a in artists])[:256] em.set_author( name=artist or playlist.name, url=url, icon_url=SPOTIFY_LOGO, ) user_spotify = tekore.Spotify(sender=menu.cog._sender) description = "" with user_spotify.token_as(menu.user_token): if playlist.type == "playlist": cur = await user_spotify.playlist_items(playlist.id) for track in cur.items[:10]: description += f"[{track.track.name}](https://open.spotify.com/playlist/{track.track.id})\n" if playlist.type == "album": album = await user_spotify.album(playlist.id) cur = album.tracks for track in cur.items[:10]: description += f"[{track.name}](https://open.spotify.com/album/{track.id})\n" em.description = description if playlist.images: em.set_thumbnail(url=playlist.images[0].url) em.set_footer( text=_("Page") + f" {menu.current_page + 1}/{self.get_max_pages()}", ) return em
async def format_page( self, menu: menus.MenuPages, album: tekore.model.FullAlbum ) -> discord.Embed: self.current_track = album em = discord.Embed(color=discord.Colour(0x1DB954)) url = f"https://open.spotify.com/album/{album.id}" title = f"{album.name} by {humanize_list([a.name for a in album.artists])}" if len(title) > 256: title = title[:253] + "..." em.set_author( name=title, url=url, icon_url=SPOTIFY_LOGO, ) msg = "Tracks:\n" sp = tekore.Spotify(sender=menu.cog._sender) with sp.token_as(menu.user_token): cur = await sp.album(album.id) for track in cur.tracks.items: msg += f"[{track.name}](https://open.spotify.com/track/{track.id})\n" em.description = msg if album.images: em.set_thumbnail(url=album.images[0].url) em.set_footer( text=_("Page") + f" {menu.current_page + 1}/{self.get_max_pages()}", ) return em
def data_client(user_token): """ Provides a client with a user token. """ sender = tk.RetryingSender(sender=tk.SyncSender()) yield tk.Spotify(user_token, sender=sender) sender.close()
def get_spotify_object(tekore_cfg_file, scope=None): token = None if os.path.exists(tekore_cfg_file): conf = tekore.config_from_file(tekore_cfg_file, return_refresh=True) token = tekore.refresh_user_token(*conf[:2], conf[3]) if not scope: scope = tekore.Scope() elif not isinstance(scope, tekore.Scope): scope = tekore.Scope(scope) if not (scope <= token.scope): missing_scopes = scope - token.scope print("Existing token lacks scope(s): " + ", ".join(missing_scopes)) token = None if token is None: token = tekore.prompt_for_user_token(client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope=scope) if not token: print("Couldn't get Spotify API token") exit(1) tekore.config_to_file(tekore_cfg_file, (CLIENT_ID, CLIENT_SECRET, REDIRECT_URI, token.refresh_token)) return tekore.Spotify(token)
def get_spotify_user_tracks(request): # read credentials from the saved file from callback file = settings.SPOTIFY_LOCAL_FILE conf = tk.config_from_file(file, return_refresh=True) token = tk.refresh_user_token(*conf[:2], conf[3]) spotify = tk.Spotify(token) spotify_tracks = spotify.saved_tracks() tracks = [] for saved_track in spotify_tracks.items: track = saved_track.track album = track.album images = list(album.images) image = images[0].url spotify_link = tk.to_url('track', track.id) _artists = album.artists artists = [] for artist in _artists: artists.append(artist.name) t = { 'title': track.name, 'artists': artists, 'image': image, 'url': spotify_link, 'preview_url': track.preview_url, } tracks.append(t) save_spotify_track(track, artists, spotify_link) return JsonResponse(tracks, safe=False)
def update_progress(self): spotify = tk.Spotify(self.owner.get_spotify_token()) self.timestamp = timezone.now() playing = spotify.playback_currently_playing() if playing is None or playing.context is None: return # only check for a resync if we've updated before resync_needed = False if self.progress_ms: resync_needed = self.resync_needed(playing) self.is_playing = playing.is_playing self.progress_ms = playing.progress_ms self.item_id = playing.item.id self.item_uri = playing.item.uri self.item_name = playing.item.name self.item_duration_ms = playing.item.duration_ms self.context_uri = playing.context.uri self.context_type = playing.context.type.value self.save() return resync_needed
def __init__(self): with open(os.getcwd() + "\\token.json") as f: data = json.load(f) client_id = data['client_id'] client_secret = data['client_secret'] token = tk.request_client_token(client_id=client_id, client_secret=client_secret) self.tk_spotify = tk.Spotify(token)
def __init__(self, client_id=Config.client_id, client_secret=Config.client_secret, redirect_uri=Config.redirect_uri): # Credentials to access the Spotify Music Data self.client_id = client_id self.client_secret = client_secret self.redirect_uri = redirect_uri self.app_token = tk.request_client_token(self.client_id, self.client_secret) self.spt = tk.Spotify(self.app_token)
def setup_config(scope): """ Configure setup for library-read step, return the spotify object which will interact with the Spotify API. """ conf = tk.config_from_file('credentials.ini') token = tk.prompt_for_user_token(*conf, scope=scope) spotify = tk.Spotify(token, chunked_on=True) return spotify
def setup_spotify_client(self, client_id, client_secret, username): scope = "user-modify-playback-state user-read-playback-state playlist-modify-private playlist-read-private" token = tekore.prompt_for_user_token( scope=scope, client_id=client_id, client_secret=client_secret, redirect_uri="http://localhost:/callback", ) return tekore.Spotify(token=token)
def get_top_tracks(term, token): tempspotify = tk.Spotify() with tempspotify.token_as(token): data = [] toptracks = tempspotify.current_user_top_tracks(time_range=term, limit=50) for item in toptracks.items: data.append(get_track_data(item)) return data
def connect(self): if self.cred is None: self.prep_cred() if self.spotify is None: if self.token is None: self.load_token() if self.token: print("Init spotify support") self.spotify = tk.Spotify(self.token)
def connect(self): if self.cred is None: self.prep_cred() if self.spotify is None: if self.token is None: self.load_token() if self.token: print("Init spotify support") self.sender = tk.RetryingSender(retries=3) self.spotify = tk.Spotify(self.token, sender=self.sender)
def init_spotify(self): """ Initialize the main entity for the Spotify API. This includes Authorization. :return: Spotify object on which API methods can be called """ cred = tk.RefreshingCredentials(config_project.CLIENT_ID, config_project.CLIENT_SECRET) app_token = cred.request_client_token() sender = tk.RetryingSender(sender=tk.CachingSender()) spotify = tk.Spotify(app_token, sender=sender) return spotify