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 = Lio.uri_escape_string(album, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://itunes.apple.com/search" "?entity=album&term=%s" % album_formated) (status, data, tag) = s.load_contents() if status: decode = json.loads(data.decode('utf-8')) for item in decode['results']: if item['artistName'].lower() == artist.lower(): url = item['artworkUrl60'].replace('60x60', '512x512') s = Lio.File.new_for_uri(url) (status, image, tag) = s.load_contents() break except Exception as e: print("Downloader::_get_album_art_itunes: %s [%s/%s]" % (e, artist, album)) return image
def get_google_arts(self, search): """ Get arts on duck image corresponding to search @param search words as string @return [urls as string] """ data = None urls = [] if not get_network_available(): return [] cs_api_key = Lp().settings.get_value('cs-api-key').get_string() try: f = Lio.File.new_for_uri( "https://www.googleapis.com/" "customsearch/v1?key=%s&cx=%s" "&q=%s&searchType=image" % (cs_api_key, GOOGLE_API_ID, Lio.uri_escape_string(search, "", False))) (status, data, tag) = f.load_contents() if status: decode = json.loads(data.decode('utf-8')) if decode is None: return urls for item in decode['items']: urls.append(item['link']) except Exception as e: print(e) return urls
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 = Lio.uri_escape_string(album, None, True) s = Lio.File.new_for_uri("https://api.deezer.com/search/album/?" "q=%s&output=json" % album_formated) (status, data, tag) = s.load_contents() if status: decode = json.loads(data.decode('utf-8')) url = None for item in decode['data']: if item['artist']['name'].lower() == artist.lower(): url = item['cover_xl'] break if url is not None: s = Lio.File.new_for_uri(url) (status, image, tag) = s.load_contents() except Exception as e: print("Downloader::__get_deezer_album_artwork: %s" % e) return image
def tracks(self, name): """ Return tracks containing name @param name as str """ try: formated = Lio.uri_escape_string(name, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://itunes.apple.com/search" "?entity=musicTrack&term=%s" % formated) (status, data, tag) = s.load_contents(self._cancel) if status: decode = json.loads(data.decode('utf-8')) tracks = [] for item in decode['results']: if item['trackName'].lower() in tracks: continue search_item = SearchItem() search_item.is_track = True search_item.name = item['trackName'] tracks.append(search_item.name.lower()) search_item.album = item['collectionName'] search_item.tracknumber = int(item['trackNumber']) search_item.discnumber = int(item['discNumber']) search_item.duration = int(item['trackTimeMillis']) / 1000 search_item.cover = item['artworkUrl60'].replace( '60x60', '512x512') search_item.smallcover = item['artworkUrl100'] search_item.artists.append(item['artistName']) self._items.append(search_item) GLib.idle_add(self.emit, 'item-found') except Exception as e: print("SpotifySearch::tracks(): %s" % e)
def __fallback(self, current_search): """ Fallback google image search, low quality @param current search as str """ try: from bs4 import BeautifulSoup except: print("$ sudo pip3 install beautifulsoup4") return urls = [] GLib.idle_add(self._label.set_text, _("Low quality, missing API key...")) try: for search in self.__get_current_searches(): url = "https://www.google.fr/search?q=%s&tbm=isch" %\ Lio.uri_escape_string(search, None, True) f = Lio.File.new_for_uri(url) (status, data, tag) = f.load_contents() if status: html = data.decode('utf-8') soup = BeautifulSoup(html, 'html.parser') for link in soup.findAll('img'): try: urls.append(link.attrs['data-src']) except: pass except Exception as e: print("ArtworkSearch::__fallback: %s" % e) self.__add_pixbufs(urls, current_search)
def tracks(self, name): """ Return tracks containing name @param name as str """ try: formated = Lio.uri_escape_string(name, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://api.spotify.com/v1/search?q=%s" "&type=track" % formated) (status, data, tag) = s.load_contents(self._cancel) if status: decode = json.loads(data.decode('utf-8')) tracks = [] for item in decode['tracks']['items']: if item['name'].lower() in tracks: continue search_item = SearchItem() search_item.is_track = True search_item.name = item['name'] tracks.append(search_item.name.lower()) search_item.album = item['album']['name'] search_item.tracknumber = int(item['track_number']) search_item.discnumber = int(item['disc_number']) search_item.duration = int(item['duration_ms']) / 1000 search_item.cover = item['album']['images'][0]['url'] search_item.smallcover = item['album']['images'][2]['url'] for artist in item['artists']: search_item.artists.append(artist['name']) self._items.append(search_item) GLib.idle_add(self.emit, 'item-found') except Exception as e: print("SpotifySearch::tracks(): %s" % e)
def __get_youtube_id_fallback(self, item): """ Get youtube id (fallback) @param item as SearchItem @return youtube id as str """ try: from bs4 import BeautifulSoup except: print("$ sudo pip3 install beautifulsoup4") return None try: # Try to handle compilations (itunes one) if item.artists[0].lower() == "various artists": if len(item.artists) > 1: artist = item.artists[1] else: artist = "" else: artist = item.artists[0] unescaped = "%s %s" % (artist, item.name) search = Lio.uri_escape_string(unescaped.replace(' ', '+'), None, True) f = Lio.File.new_for_uri("https://www.youtube.com/" "results?search_query=%s" % search) (status, data, tag) = f.load_contents(None) if not status: return None html = data.decode('utf-8') soup = BeautifulSoup(html, 'html.parser') ytems = [] for link in soup.findAll('a'): href = link.get('href') title = link.get('title') if href is None or title is None: continue if href.startswith("/watch?v="): href = href.replace("/watch?v=", "") ytems.append((href, title)) dic = {} best = self.__BAD_SCORE for (yid, title) in ytems: score = self.__get_youtube_score(title, item.name, artist, item.album) if score < best: best = score elif score == best: continue # Keep first result dic[score] = yid # Return url from first dic item if best == self.__BAD_SCORE: return None else: return dic[best] except Exception as e: print("WebYouTube::__get_youtube_id_fallback():", e) self.__fallback = True return None
def __on_search_timeout(self, string): """ Populate widget @param string as str """ self.__timeout_id = None url = "http://opml.radiotime.com/Search.ashx?query=%s" %\ Lio.uri_escape_string(string, "/", False) self.populate(url)
def __get_albums(self, name): """ Get albums for name @param name as str """ try: # Read album list formated = Lio.uri_escape_string(name, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://itunes.apple.com/search" "?entity=album&term=%s" % formated) (status, data, tag) = s.load_contents(self._cancel) if not status: raise decode = json.loads(data.decode('utf-8')) # For each album, get cover and tracks for item in decode['results']: album_item = SearchItem() album_item.name = album_item.album_name =\ item['collectionName'] album_item.is_track = False album_item.artists = [item['artistName']] album_item.cover = item['artworkUrl60'].replace( '60x60', '512x512') album_item.smallcover = item['artworkUrl100'] s = Lio.File.new_for_uri("https://itunes.apple.com/lookup" "?id=%s&entity=song" % item['collectionId']) (status, data, tag) = s.load_contents(self._cancel) if not status: raise decode = json.loads(data.decode('utf-8')) for item in decode['results']: if item['wrapperType'] == "collection": continue track_item = SearchItem() track_item.is_track = True try: track_item.year = decode['releaseDate'][:4] except: pass # May be missing track_item.name = item['trackName'] track_item.album = album_item.name track_item.tracknumber = int(item['trackNumber']) track_item.discnumber = int(item['discNumber']) track_item.duration = int(item['trackTimeMillis'])\ / 1000 track_item.artists.append(item['artistName']) album_item.subitems.append(track_item) self._items.append(album_item) GLib.idle_add(self.emit, 'item-found') except Exception as e: print("ItunesSearch::__get_albums(): %s" % e)
def __get_youtube_id(self, item): """ Get youtube id @param item as SearchItem @return youtube id as str """ if self.__fallback: return self.__get_youtube_id_fallback(item) # Try to handle compilations (itunes one) if item.artists[0].lower() == "various artists": if len(item.artists) > 1: artist = item.artists[1] else: artist = "" else: artist = item.artists[0] unescaped = "%s %s" % (artist, item.name) search = Lio.uri_escape_string(unescaped.replace(' ', '+'), None, True) key = Lp().settings.get_value('cs-api-key').get_string() try: f = Lio.File.new_for_uri("https://www.googleapis.com/youtube/v3/" "search?part=snippet&q=%s&" "type=video&key=%s&cx=%s" % (search, key, GOOGLE_API_ID)) (status, data, tag) = f.load_contents(None) if status: decode = json.loads(data.decode('utf-8')) dic = {} best = self.__BAD_SCORE for i in decode['items']: score = self.__get_youtube_score(i['snippet']['title'], item.name, artist, item.album) if score < best: best = score elif score == best: continue # Keep first result dic[score] = i['id']['videoId'] # Return url from first dic item if best == self.__BAD_SCORE: return None else: return dic[best] except IndexError: pass except Exception as e: print("WebYouTube::__get_youtube_id():", e) self.__fallback = True return self.__get_youtube_id_fallback(item) return None
def __get_albums(self, name): """ Get albums for name @param name as str """ try: # Read album list formated = Lio.uri_escape_string(name, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://api.spotify.com/v1/search?q=%s" "&type=album" % formated) (status, data, tag) = s.load_contents(self._cancel) if status: decode = json.loads(data.decode('utf-8')) # For each album, get cover and tracks for item in decode['albums']['items']: album_item = SearchItem() album_item.name = album_item.album_name = item['name'] album_item.is_track = False album_item.cover = item['images'][0]['url'] album_item.smallcover = item['images'][2]['url'] s = Lio.File.new_for_uri("https://api.spotify.com/v1/" "albums/%s" % item['id']) (status, data, tag) = s.load_contents(self._cancel) if status: decode = json.loads(data.decode('utf-8')) for item in decode['tracks']['items']: track_item = SearchItem() track_item.is_track = True try: track_item.year = decode['release_date'][:4] except: pass # May be missing track_item.name = item['name'] track_item.album = album_item.name track_item.tracknumber = int(item['track_number']) track_item.discnumber = int(item['disc_number']) track_item.duration = int(item['duration_ms'])\ / 1000 for artist in item['artists']: track_item.artists.append(artist['name']) if not album_item.artists: album_item.artists = track_item.artists album_item.subitems.append(track_item) self._items.append(album_item) GLib.idle_add(self.emit, 'item-found') except Exception as e: print("SpotifySearch::albums(): %s" % e)
def __get_jgm_id(self, item): """ Get jmg id @param item as SearchItem @return jpg id as str """ # Try to handle compilations (itunes one) if item.artists[0].lower() == "various artists": if len(item.artists) > 1: artist = item.artists[1] else: artist = "" else: artist = item.artists[0] unescaped = "%s %s" % (artist, item.name) for c in ['/', '?', '!']: if c in unescaped: unescaped = unescaped.replace(c, ' ') search = Lio.uri_escape_string(unescaped, '', True) try: # Strip /? as API doesn't like it f = Lio.File.new_for_uri("http://app.jgm90.com/cmapi/search/" "%s/1/10" % search.strip('/?')) (status, data, tag) = f.load_contents(None) if status: decode = json.loads(data.decode('utf-8')) for song in decode['result']['songs']: try: song_artist = escape( song['artists'][0]['name'].lower()) if song_artist == escape(artist.lower()): return song['id'] except Exception as e: print("WebJmg90::__get_jmg_id():", e) except IndexError: pass except KeyError: pass except Exception as e: print("WebJmg90::__get_jmg_id():", e) return None
def _get_deezer_artist_info(self, artist): """ Return deezer artist information @param artist as str @return (url as str/None, content as None) """ try: artist_formated = Lio.uri_escape_string(artist, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://api.deezer.com/search/artist/?" "q=%s&output=json&index=0&limit=1&" % artist_formated) (status, data, tag) = s.load_contents() if status: decode = json.loads(data.decode('utf-8')) return (decode['data'][0]['picture_xl'], None) except Exception as e: debug("Downloader::_get_deezer_artist_artwork(): %s [%s]" % (e, artist)) return (None, None)
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: artist_formated = Lio.uri_escape_string(artist, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://api.spotify.com/v1/search?q=%s" "&type=artist" % artist_formated) (status, data, tag) = s.load_contents() 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: s = Lio.File.new_for_uri("https://api.spotify.com/v1/artists/" "%s/albums" % artist_spotify_id) (status, data, tag) = s.load_contents() if status: decode = json.loads(data.decode('utf-8')) url = None for item in decode['items']: if item['name'] == album: url = item['images'][0]['url'] break if url is not None: s = Lio.File.new_for_uri(url) (status, image, tag) = s.load_contents() break except Exception as e: print("Downloader::_get_album_art_spotify: %s [%s/%s]" % (e, artist, album)) return image
def _get_spotify_artist_info(self, artist): """ Return spotify artist information @param artist as str @return (url as str/None, content as None) """ try: artist_formated = Lio.uri_escape_string(artist, None, True).replace(' ', '+') s = Lio.File.new_for_uri("https://api.spotify.com/v1/search?q=%s" "&type=artist" % artist_formated) (status, data, tag) = s.load_contents() 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'], None) except Exception as e: debug("Downloader::_get_spotify_artist_artwork(): %s [%s]" % (e, artist)) return (None, None)