예제 #1
0
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
예제 #2
0
    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
예제 #3
0
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)
예제 #5
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)