def __playing_now(self, track): """ Now playing track @param track as Track """ try: token = App().ws_director.token_ws.get_token( self.__name, self.__cancellable) if token is None: return args = self.__get_args_for_method("track.updateNowPlaying") args.append(("artist", track.artists[0])) args.append(("track", track.name)) args.append(("album", track.album.name)) if track.mbid and track.mbid.find(":") == -1: args.append(("mbid", track.mbid)) args.append(("duration", str(track.duration // 1000))) args.append(("sk", token)) api_sig = self.__get_sig_for_args(args) args.append(("api_sig", api_sig)) post_data = {} for (name, value) in args: post_data[name] = value msg = Soup.form_request_new_from_hash("POST", self.__uri, post_data) msg.request_headers.append("Accept-Charset", "utf-8") data = App().task_helper.send_message_sync(msg, self.__cancellable) if data is not None: Logger.debug("%s: %s -> %s", self.__uri, data, post_data) except Exception as e: Logger.error("LastFMWebService::__playing_now(): %s" % e)
def get_token(cancellable): """ Get a new auth token @param cancellable as Gio.Cancellable @return str """ # Remove 60 seconds to be sure if int(time()) + 60 < SpotifySearch.__EXPIRES and\ SpotifySearch.__TOKEN is not None: debug("Use spotify token: %s" % SpotifySearch.__TOKEN) return SpotifySearch.__TOKEN try: token_uri = "https://accounts.spotify.com/api/token" credentials = "%s:%s" % (SPOTIFY_CLIENT_ID, SPOTIFY_SECRET) encoded = b64encode(credentials.encode("utf-8")) credentials = encoded.decode("utf-8") session = Soup.Session.new() data = {"grant_type": "client_credentials"} msg = Soup.form_request_new_from_hash("POST", token_uri, data) msg.request_headers.append("Authorization", "Basic %s" % credentials) status = session.send_message(msg) if status == 200: body = msg.get_property("response-body") data = body.flatten().get_data() decode = json.loads(data.decode("utf-8")) SpotifySearch.__EXPIRES = int(time()) +\ int(decode["expires_in"]) SpotifySearch.__TOKEN = decode["access_token"] return SpotifySearch.__TOKEN except: return ""
def __love(self, artist, title, status): """ Love track @param artist as string @param title as string @param status as bool """ try: token = App().ws_director.token_ws.get_token( self.__name, self.__cancellable) if token is None: return if status: args = self.__get_args_for_method("track.love") else: args = self.__get_args_for_method("track.unlove") args.append(("artist", artist)) args.append(("track", title)) args.append(("sk", token)) api_sig = self.__get_sig_for_args(args) args.append(("api_sig", api_sig)) post_data = {} for (name, value) in args: post_data[name] = value msg = Soup.form_request_new_from_hash("POST", self.__uri, post_data) msg.request_headers.append("Accept-Charset", "utf-8") data = App().task_helper.send_message_sync(msg, self.__cancellable) if data is not None: Logger.debug("%s: %s", self.__uri, data) except Exception as e: Logger.error("LastFMWebService::__love(): %s" % e)
def _lastfm_api_call(self, media, time_stamp, request_type_key): """Internal method called by self.scrobble""" api_key = self._goa_lastfm.client_id sk = self._goa_lastfm.session_key secret = self._goa_lastfm.secret artist = utils.get_artist_name(media) title = utils.get_media_title(media) request_type = { "update now playing": "track.updateNowPlaying", "scrobble": "track.scrobble" } # The album is optional. So only provide it when it is # available. album = media.get_album() request_dict = {} if album: request_dict.update({ "album": album }) if time_stamp is not None: request_dict.update({ "timestamp": str(time_stamp) }) request_dict.update({ "api_key": api_key, "method": request_type[request_type_key], "artist": artist, "track": title, "sk": sk, }) sig = "" for key in sorted(request_dict): sig += key + request_dict[key] sig += secret api_sig = md5(sig.encode()).hexdigest() request_dict.update({ "api_sig": api_sig }) msg = Soup.form_request_new_from_hash( "POST", "https://ws.audioscrobbler.com/2.0/", request_dict) self._soup_session.queue_message( msg, self._lastfm_api_callback, request_type_key)
def _lastfm_api_call(self, media, time_stamp, request_type_key): """Internal method called by self.scrobble""" api_key = self._goa_lastfm.client_id sk = self._goa_lastfm.session_key secret = self._goa_lastfm.secret artist = utils.get_artist_name(media) title = utils.get_media_title(media) request_type = { "update now playing": "track.updateNowPlaying", "scrobble": "track.scrobble" } # The album is optional. So only provide it when it is # available. album = media.get_album() request_dict = {} if album: request_dict.update({"album": album}) if time_stamp is not None: request_dict.update({"timestamp": str(time_stamp)}) request_dict.update({ "api_key": api_key, "method": request_type[request_type_key], "artist": artist, "track": title, "sk": sk, }) sig = "" for key in sorted(request_dict): sig += key + request_dict[key] sig += secret api_sig = md5(sig.encode()).hexdigest() request_dict.update({"api_sig": api_sig}) msg = Soup.form_request_new_from_hash( "POST", "https://ws.audioscrobbler.com/2.0/", request_dict) self._soup_session.queue_message(msg, self._lastfm_api_callback, request_type_key)
def run(self): while not self.should_exit: if not self._context._queue.empty(): ec, ea, el = self._context._queue.get() data = self._context._base_payload.copy() data.update(ec=ec, ea=ea) if el: data.update(el=el) logger.debug(f"{data=}") message = Soup.form_request_new_from_hash( "POST", self._context._endpoint, data) self._session.send(message) if message.props.status_code != 200: logger.info( f"Could not send message to Google Analytics: {message.props.status}" ) time.sleep(0.1)
def get_token(self): """ Get a new auth token """ try: token_uri = "https://accounts.spotify.com/api/token" credentials = "%s:%s" % (SPOTIFY_CLIENT_ID, SPOTIFY_SECRET) encoded = b64encode(credentials.encode("utf-8")) credentials = encoded.decode("utf-8") session = Soup.Session.new() data = {"grant_type": "client_credentials"} msg = Soup.form_request_new_from_hash("POST", token_uri, data) msg.request_headers.append("Authorization", "Basic %s" % credentials) status = session.send_message(msg) if status == 200: body = msg.get_property("response-body") data = body.flatten().get_data() decode = json.loads(data.decode("utf-8")) self.__token_expires = int(time()) + int(decode["expires_in"]) self.__token = decode["access_token"] except Exception as e: Logger.error("SpotifyHelper::get_token(): %s", e)
def __get_spotify_token(self, cancellable): """ Get a new auth token @param cancellable as Gio.Cancellable """ try: uri = "https://accounts.spotify.com/api/token" credentials = "%s:%s" % (SPOTIFY_CLIENT_ID, SPOTIFY_SECRET) encoded = b64encode(credentials.encode("utf-8")) credentials = encoded.decode("utf-8") data = {"grant_type": "client_credentials"} msg = Soup.form_request_new_from_hash("POST", uri, data) msg.request_headers.append("Authorization", "Basic %s" % credentials) data = App().task_helper.send_message_sync(msg, cancellable) if data is not None: decode = json.loads(data.decode("utf-8")) self.__token_expires["SPOTIFY"] = int(time()) +\ int(decode["expires_in"]) self.__tokens["SPOTIFY"] = decode["access_token"] except Exception as e: Logger.error("TokenWebService::__get_spotify_token(): %s", e) self.__loading_token["SPOTIFY"] = False
def __get_spotify_token(self, cancellable): """ Get a new auth token @param cancellable as Gio.Cancellable @return str """ try: token_uri = "https://accounts.spotify.com/api/token" credentials = "%s:%s" % (SPOTIFY_CLIENT_ID, SPOTIFY_SECRET) encoded = b64encode(credentials.encode("utf-8")) credentials = encoded.decode("utf-8") session = Soup.Session.new() data = {"grant_type": "client_credentials"} msg = Soup.form_request_new_from_hash("POST", token_uri, data) msg.request_headers.append("Authorization", "Basic %s" % credentials) status = session.send_message(msg) if status == 200: body = msg.get_property("response-body") data = body.flatten().get_data() decode = json.loads(data.decode("utf-8")) return decode["access_token"] except: return ""
def __listen(self, track, timestamp): """ Scrobble track @param track as Track @param timestamp as int """ tracks = self.__queue + [(track, timestamp)] self.__queue = [] try: for (track, timestamp) in tracks: token = App().ws_director.token_ws.get_token( self.__name, self.__cancellable) if token is None: return args = self.__get_args_for_method("track.scrobble") args.append(("artist", track.artists[0])) args.append(("track", track.name)) args.append(("album", track.album.name)) if track.mbid and track.mbid.find(":") == -1: args.append(("mbid", track.mbid)) args.append(("timestamp", str(timestamp))) args.append(("sk", token)) api_sig = self.__get_sig_for_args(args) args.append(("api_sig", api_sig)) post_data = {} for (name, value) in args: post_data[name] = value msg = Soup.form_request_new_from_hash("POST", self.__uri, post_data) msg.request_headers.append("Accept-Charset", "utf-8") data = App().task_helper.send_message_sync( msg, self.__cancellable) if data is not None: Logger.debug("%s: %s", self.__uri, data) except Exception as e: Logger.error("LastFMWebService::__listen(): %s" % e)
def _lastfm_api_call(self, coresong, time_stamp, request_type_key): """Internal method called by self.scrobble""" api_key = self._goa_lastfm.client_id sk = self._goa_lastfm.session_key if sk is None: self._log.warning( "Error: Unable to perform last.fm api call {}".format( request_type_key)) return secret = self._goa_lastfm.secret artist = coresong.props.artist title = coresong.props.title request_type = { "update now playing": "track.updateNowPlaying", "scrobble": "track.scrobble" } # The album is optional. So only provide it when it is # available. album = coresong.props.album request_dict = {} if (request_type_key == "scrobble" and time_stamp is not None): self._scrobble_cache.append({ "artist": artist, "track": title, "album": album, "timestamp": time_stamp }) for index, data in enumerate(self._scrobble_cache): request_dict.update({ "artist[{}]".format(index): data['artist'], "track[{}]".format(index): data['track'], "timestamp[{}]".format(index): str(data['timestamp']), }) if album: request_dict.update( {"album[{}]".format(index): data['album']}) else: if album: request_dict.update({"album": album}) if time_stamp is not None: request_dict.update({"timestamp": str(time_stamp)}) request_dict.update({ "artist": artist, "track": title, }) request_dict.update({ "api_key": api_key, "method": request_type[request_type_key], "sk": sk, }) sig = "" for key in sorted(request_dict): sig += key + request_dict[key] sig += secret api_sig = md5(sig.encode()).hexdigest() request_dict.update({"api_sig": api_sig}) msg = Soup.form_request_new_from_hash( "POST", "https://ws.audioscrobbler.com/2.0/", request_dict) self._soup_session.queue_message(msg, self._lastfm_api_callback, request_type_key)