def _get_itunes_album_artwork(self, artist, album): """ Get album artwork from itunes @param artist as string @param album as string @return image as bytes @tread safe """ image = None try: album_formated = GLib.uri_escape_string(album, None, True).replace(" ", "+") uri = "https://itunes.apple.com/search" +\ "?entity=album&term=%s" % album_formated helper = TaskHelper() (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) for item in decode["results"]: if item["artistName"].lower() == artist.lower(): uri = item["artworkUrl60"].replace("60x60", "512x512") (status, image) = helper.load_uri_content_sync(uri, None) break except Exception as e: Logger.error("Downloader::_get_album_art_itunes: %s [%s/%s]" % (e, artist, album)) return image
def _get_deezer_album_artwork(self, artist, album): """ Get album artwork from deezer @param artist as string @param album as string @return image as bytes @tread safe """ image = None try: album_formated = GLib.uri_escape_string(album, None, True) uri = "https://api.deezer.com/search/album/?" +\ "q=%s&output=json" % album_formated helper = TaskHelper() (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) uri = None for item in decode["data"]: if item["artist"]["name"].lower() == artist.lower(): uri = item["cover_xl"] break if uri is not None: (status, image) = helper.load_uri_content_sync(uri, None) except Exception as e: Logger.error("Downloader::__get_deezer_album_artwork: %s" % e) return image
def _get_spotify_artist_artwork_uri(self, artist, cancellable=None): """ Return spotify artist information @param artist as str @param cancellable as Gio.Cancellable @return uri as str @tread safe """ if not get_network_available("SPOTIFY"): return None try: artist_formated = GLib.uri_escape_string(artist, None, True).replace(" ", "+") uri = "https://api.spotify.com/v1/search?q=%s" % artist_formated +\ "&type=artist" token = "Bearer %s" % self.__get_spotify_token(cancellable) helper = TaskHelper() helper.add_header("Authorization", token) (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: uri = None decode = json.loads(data.decode("utf-8")) for item in decode["artists"]["items"]: if noaccents(item["name"].lower()) ==\ noaccents(artist.lower()): uri = item["images"][0]["url"] return uri except Exception as e: Logger.debug( "ArtDownloader::_get_spotify_artist_artwork_uri(): %s" % e) return None
def search(self, search, cancellable): """ Get albums related to search We need a thread because we are going to populate DB @param search as str @param cancellable as Gio.Cancellable """ try: while self.wait_for_token(): if cancellable.is_cancelled(): raise Exception("cancelled") sleep(1) token = "Bearer %s" % self.__token helper = TaskHelper() helper.add_header("Authorization", token) uri = "https://api.spotify.com/v1/search?" uri += "q=%s&type=album,track" % search (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) album_ids = [] self.__create_albums_from_album_payload( decode["albums"]["items"], album_ids, cancellable) self.__create_albums_from_tracks_payload( decode["tracks"]["items"], album_ids, cancellable) except Exception as e: Logger.warning("SpotifyHelper::search(): %s", e) # Do not emit search-finished on cancel if str(e) == "cancelled": return GLib.idle_add(self.emit, "search-finished")
def search_similar_artists(self, spotify_id, cancellable): """ Search similar artists @param spotify_id as str @param cancellable as Gio.Cancellable """ try: while self.wait_for_token(): if cancellable.is_cancelled(): raise Exception("cancelled") sleep(1) found = False token = "Bearer %s" % self.__token helper = TaskHelper() helper.add_header("Authorization", token) uri = "https://api.spotify.com/v1/artists/%s/related-artists" % \ spotify_id (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) for item in decode["artists"]: if cancellable.is_cancelled(): raise Exception("cancelled") found = True artist_name = item["name"] cover_uri = item["images"][1]["url"] GLib.idle_add(self.emit, "new-artist", artist_name, cover_uri) except Exception as e: Logger.error("SpotifyHelper::search_similar_artists(): %s", e) if not found: GLib.idle_add(self.emit, "new-artist", None, None)
def get_similar_artists(self, artist_id, cancellable): """ Get similar artists @param artist_id as int @param cancellable as Gio.Cancellable @return artists as [str] """ artists = [] try: while self.wait_for_token(): if cancellable.is_cancelled(): raise Exception("cancelled") sleep(1) token = "Bearer %s" % self.__token helper = TaskHelper() helper.add_header("Authorization", token) uri = "https://api.spotify.com/v1/artists/%s/related-artists" %\ artist_id (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) for item in decode["artists"]: artists.append(item["name"]) except Exception as e: Logger.error("SpotifyHelper::get_similar_artists(): %s", e) return artists
def _get_spotify_album_artwork(self, artist, album): """ Get album artwork from spotify @param artist as string @param album as string @return image as bytes @tread safe """ image = None artists_spotify_ids = [] try: token = self.__get_spotify_token(None) artist_formated = GLib.uri_escape_string(artist, None, True).replace(" ", "+") uri = "https://api.spotify.com/v1/search?q=%s" % artist_formated +\ "&type=artist" token = "Bearer %s" % token helper = TaskHelper() helper.add_header("Authorization", token) (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) for item in decode["artists"]["items"]: artists_spotify_ids.append(item["id"]) for artist_spotify_id in artists_spotify_ids: uri = "https://api.spotify.com/v1/artists/" +\ "%s/albums" % artist_spotify_id (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) uri = None for item in decode["items"]: if item["name"] == album: uri = item["images"][0]["url"] break if uri is not None: (status, image) = helper.load_uri_content_sync(uri, None) break except Exception as e: Logger.error("Downloader::_get_album_art_spotify: %s [%s/%s]" % (e, artist, album)) return image
def _get_spotify_album_artwork_uri(self, artist, album, cancellable=None): """ Get album artwork uri from spotify @param artist as str @param album as str @param cancellable as Gio.Cancellable @return uri as str @tread safe """ if not get_network_available("SPOTIFY"): return None artists_spotify_ids = [] try: token = self.__get_spotify_token(cancellable) artist_formated = GLib.uri_escape_string(artist, None, True).replace(" ", "+") uri = "https://api.spotify.com/v1/search?q=%s" % artist_formated +\ "&type=artist" token = "Bearer %s" % token helper = TaskHelper() helper.add_header("Authorization", token) (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) for item in decode["artists"]["items"]: artists_spotify_ids.append(item["id"]) for artist_spotify_id in artists_spotify_ids: uri = "https://api.spotify.com/v1/artists/" +\ "%s/albums" % artist_spotify_id (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) uri = None for item in decode["items"]: if noaccents(item["name"].lower()) ==\ noaccents(album.lower()): return item["images"][0]["url"] except Exception as e: Logger.error("ArtDownloader::_get_album_art_spotify_uri: %s" % e) return None
def charts(self, cancellable, language="global"): """ Get albums related to search We need a thread because we are going to populate DB @param cancellable as Gio.Cancellable @param language as str """ from csv import reader try: while self.wait_for_token(): if cancellable.is_cancelled(): raise Exception("cancelled") sleep(1) token = "Bearer %s" % self.__token helper = TaskHelper() helper.add_header("Authorization", token) uri = self.__CHARTS % language spotify_ids = [] (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = data.decode("utf-8") for line in decode.split("\n"): try: for row in reader([line]): if not row: continue url = row[4] if url == "URL": continue spotify_id = url.split("/")[-1] if spotify_id: spotify_ids.append(spotify_id) except Exception as e: Logger.warning("SpotifyHelper::charts(): %s", e) album_ids = [] for spotify_id in spotify_ids: if cancellable.is_cancelled(): raise Exception("cancelled") payload = self.__get_track_payload(helper, spotify_id, cancellable) self.__create_albums_from_tracks_payload( [payload], album_ids, cancellable) except Exception as e: Logger.warning("SpotifyHelper::charts(): %s", e) # Do not emit search-finished on cancel if str(e) == "cancelled": return GLib.idle_add(self.emit, "search-finished")
def _get_lastfm_album_artwork(self, artist, album): """ Get album artwork from lastfm @param artist as string @param album as string @return data as bytes @tread safe """ image = None if App().lastfm is not None: try: helper = TaskHelper() last_album = App().lastfm.get_album(artist, album) uri = last_album.get_cover_image(4) if uri is not None: (status, image) = helper.load_uri_content_sync(uri, None) except Exception as e: Logger.error("Downloader::_get_album_art_lastfm: %s [%s/%s]" % (e, artist, album)) return image
def _get_deezer_artist_artwork_uri(self, artist): """ Return deezer artist information @param artist as str @return uri as str/None """ try: artist_formated = GLib.uri_escape_string(artist, None, True).replace(" ", "+") uri = "https://api.deezer.com/search/artist/?" +\ "q=%s&output=json&index=0&limit=1&" % artist_formated helper = TaskHelper() (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) return decode["data"][0]["picture_xl"] except Exception as e: Logger.debug("Downloader::_get_deezer_artist_artwork(): %s [%s]" % (e, artist)) return None
def __create_albums_from_album_payload(self, payload, album_ids, cancellable): """ Get albums from an album payload @param payload as {} @param album_ids as [int] @param cancellable as Gio.Cancellable """ # Populate tracks for album_item in payload: if cancellable.is_cancelled(): return album_id = App().db.exists_in_db( album_item["name"], [artist["name"] for artist in album_item["artists"]], None) if album_id is not None: if album_id not in album_ids: album = Album(album_id) if album.tracks: track = album.tracks[0] if track.is_web: self.__create_album(album_id, None, cancellable) album_ids.append(album_id) continue uri = "https://api.spotify.com/v1/albums/%s" % album_item["id"] token = "Bearer %s" % self.__token helper = TaskHelper() helper.add_header("Authorization", token) (status, data) = helper.load_uri_content_sync(uri, cancellable) if status: decode = json.loads(data.decode("utf-8")) track_payload = decode["tracks"]["items"] for item in track_payload: item["album"] = album_item self.__create_albums_from_tracks_payload(track_payload, album_ids, cancellable)
def _get_spotify_artist_artwork_uri(self, artist): """ Return spotify artist information @param artist as str @return uri as str/None """ try: artist_formated = GLib.uri_escape_string(artist, None, True).replace(" ", "+") uri = "https://api.spotify.com/v1/search?q=%s" % artist_formated +\ "&type=artist" token = "Bearer %s" % self.__get_spotify_token(None) helper = TaskHelper() helper.add_header("Authorization", token) (status, data) = helper.load_uri_content_sync(uri, None) if status: decode = json.loads(data.decode("utf-8")) for item in decode["artists"]["items"]: if item["name"].lower() == artist.lower(): return item["images"][0]["url"] except Exception as e: Logger.debug("Downloader::_get_spotify_artist_artwork(): %s [%s]" % (e, artist)) return None