def authenticate(): class RequestHandler(BaseHTTPRequestHandler): callbackUri = None def do_GET(self): self.send_response(200, "OK") self.end_headers() self.wfile.write( pkg_resources.resource_string(__name__, "html/success.html")) RequestHandler.callbackUri = self.path config = get_config() oauth = SpotifyOAuth( client_id=config["client_id"], client_secret=config["client_secret"], redirect_uri="http://localhost:8000", scope=scope, cache_path=dirs.user_cache_dir, ) token_info = oauth.get_cached_token() if not token_info: url = oauth.get_authorize_url() webbrowser.open(url) server = HTTPServer(('', 8000), RequestHandler) server.handle_request() code = oauth.parse_response_code(RequestHandler.callbackUri) oauth.get_access_token(code, as_dict=False) return oauth
def refresh_access_token(self, spotify_credentials: SpotifyOAuth) -> str: cached_token: dict = spotify_credentials.get_cached_token() refreshed_token: str = cached_token.get('refresh_token') new_token: dict = spotify_credentials.refresh_access_token( refreshed_token) new_access_token = new_token.get('access_token') spotify_instance = Spotify(auth=new_access_token) self._spotify_instance = spotify_instance return new_access_token
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)
def login() -> Spotify: """ Attempt to log in to Spotify as the current user These OS Env variables must be set: SPOTIPY_CLIENT_ID SPOTIPY_CLIENT_SECRET SPOTIPY_REDIRECT_URI :return: Spotify session """ scope = 'user-library-read ' \ 'playlist-read-private ' \ 'playlist-modify-private ' \ 'playlist-modify-public ' \ 'user-library-modify ' \ 'user-read-recently-played' auth = SpotifyOAuth(scope=scope, username=USERNAME, cache_path=os.path.join(CACHE_DIR, 'auth_token.json')) token_info = auth.get_cached_token() if token_info: logging.info('Using cached token for login') return _get_login_session(token_info['access_token']) code = auth.parse_response_code(RESPONSE_URL) if code: logging.info('Found response URL. Getting an access token...') token_info = auth.get_access_token(code) return _get_login_session(token_info['access_token']) logging.warning( 'Access token not found. Please use the below URL to authorize this ' 'application and then set the RESPONSE_URL env variable to the URL ' 'spotify responds with and run this application again') logging.warning(auth.get_authorize_url()) sys.exit(0)
class MusicFeeder: scopes = " ".join([ "ugc-image-upload", "user-read-playback-state", "user-modify-playback-state", "user-read-currently-playing", "streaming", "app-remote-control", "user-read-email", "user-read-private", "playlist-read-collaborative", "playlist-modify-public", "playlist-read-private", "playlist-modify-private", "user-library-modify", "user-library-read", "user-top-read", "user-read-recently-played", "user-follow-read", "user-follow-modify" ]) feedly_username = '******' spotify_username = "******" spotify_playlist_id = "6qsodHkxMB36VhWfIwvylQ" stop_words = ["MV"] def __init__(self): # feedly setup self.feedly_access_token = self._get_feedly_access_token() # spotify setup self.cache_path = Path(__file__).parent / f".cache-{self.spotify_username}" self.sp_oauth = SpotifyOAuth( SPOTIPY_CLIENT_ID, SPOTIPY_CLIENT_SECRET, SPOTIPY_REDIRECT_URI, scope=self.scopes, cache_path=self.cache_path, username=self.spotify_username ) self.token_info = self.sp_oauth.get_cached_token() self.token = self.token_info["access_token"] self.spotify = spotipy.Spotify(auth=self.token) self.titles, self.tracks, self.current_tracks, self.tracks_to_add = None, None, None, None def execute(self): self.titles = self._get_titles() # extract latest 30 titles self.titles = self.titles[:30] self.tracks = self._get_taget_tracks(self.titles) self.current_tracks = self._get_current_tracks() self.tracks_to_add = self._get_tracks_to_add(self.tracks, self.current_tracks) self._add_to_spotify(self.tracks_to_add) def _get_feedly_access_token(self): url = "https://cloud.feedly.com/v3/auth/token" payload = dict( refresh_token=FEEDLY_REFRESH_TOKEN, client_id="feedlydev", client_secret="feedlydev", grant_type="refresh_token" ) resp = requests.post(url, json=payload).json() return resp['access_token'] def _request_to_feedly(self, url, params={}): headers = {'Authorization': f"OAuth {self.feedly_access_token}"} resp = requests.get(url, headers=headers, params=params) if resp.status_code != 200: raise FeedlyApiRequestError(json.dumps(resp.json())) return resp.json() def _get_titles(self): url = f"https://cloud.feedly.com/v3/streams/contents?streamId=user/{self.feedly_username}/category/Music" params = dict(unreadOnly=False, count=100) resp = self._request_to_feedly(url, params) return [item['title'] for item in resp['items'] if item['title']] def _get_taget_tracks(self, titles): one_week_ago = datetime.today() - timedelta(days=7) tracks = [] for title in titles: terms = re.findall("[a-zA-Z ]+", title) terms = [term.strip() for term in terms if term.strip()] terms = [term for term in terms if term not in self.stop_words] query = " ".join(terms) logging.info(f"searching: {query}") result = self.spotify.search(query)['tracks']['items'] if result: track = result[0] try: release_date = datetime.strptime(track['album']['release_date'], "%Y-%m-%d") except ValueError: continue # Don't append if the release date of the track is older than one week ago if release_date < one_week_ago: continue tracks.append(track['id']) return tracks def _get_current_tracks(self): return self.spotify.user_playlist(self.spotify_username, self.spotify_playlist_id)['tracks']['items'] def _get_tracks_to_add(self, tracks, current_tracks): current_track_ids = [c_track['track']['id'] for c_track in current_tracks] tracks = [track for track in tracks if track not in current_track_ids] return tracks def _add_to_spotify(self, tracks): if not tracks: return self.spotify.user_playlist_add_tracks(self.spotify_username, self.spotify_playlist_id, tracks, position=0)