def do_search(self): self.cancel_request() base = 'https://api.soundcloud.com' self.new_model() self.containers.clear() term = self.search_text if term.startswith('https://soundcloud.com/') or term.startswith( "http://soundcloud.com/"): # ignore the selected search type and try to resolve whatever the url is print("resolving " + term) self.scrolled.hide() url = base + '/resolve.json?url=' + term + '&client_id=' + CLIENT_ID self.loader = rb.Loader() self.loader.get_url(url, self.resolve_api_cb) return if self.search_type not in self.search_types: print("not sure how to search for " + self.search_type) return print("searching for " + self.search_type + " matching " + term) st = self.search_types[self.search_type] self.container_view.get_column(0).set_title(st['title']) url = base + st['endpoint'] + '?q=' + urllib.parse.quote( term) + '&client_id=' + CLIENT_ID self.loader = rb.Loader() if st['containers']: self.scrolled.show() self.loader.get_url(url, self.search_containers_api_cb) else: self.scrolled.hide() self.loader.get_url(url, self.search_tracks_api_cb)
def got_lyrics(self, xmltext, callback, *data): # retrieve xml content if xmltext is None: callback(None, *data) return try: xmltext = xmltext.decode('gbk').encode('UTF-8') xmltext = xmltext.replace('encoding="gb2312"', 'encoding="UTF-8"') xmldoc = minidom.parseString(xmltext) root = xmldoc.documentElement lrcurl = root.getElementsByTagName( 'LyricUrl')[0].childNodes[0].data if lrcurl is None: callback(xmltext, *data) return # download the lyrics file lrcurl_encode = urllib.quote(detect_charset(lrcurl).encode('gbk')) lrcurl_encode = lrcurl_encode.replace('%3A', ':') loader = rb.Loader() loader.get_url(lrcurl_encode, self.parse_lyrics, callback, *data) except: callback(None, *data)
def do_get_playback_uri(self, entry): db = self.props.db song_id = entry.get_string(RB.RhythmDBPropType.LOCATION)[6:] artist = entry.get_string(RB.RhythmDBPropType.ARTIST) title = entry.get_string(RB.RhythmDBPropType.TITLE) songinfo = self.client.get_song_links( [song_id], False, self.settings.get_boolean("hq") ) song = songinfo[0]["file_list"][0] lyric = songinfo[0]["lyric_url"] db.entry_set(entry, RB.RhythmDBPropType.DURATION, song["duration"]) db.entry_set(entry, RB.RhythmDBPropType.FILE_SIZE, song["size"]) db.entry_set(entry, RB.RhythmDBPropType.BITRATE, song["kbps"]) def save_lyric_cb(data): path = os.path.expanduser(self.settings["lyric-path"]) filename = "%s-%s.lrc" % (artist, title) with open(os.path.join(path, filename), "wb") as lyric: lyric.write(data) lyric.close() if lyric: loader = rb.Loader() loader.get_url(lyric, save_lyric_cb) return song["url"]
def __auth_download(self, sku): # http://magnatune.com/info/api def auth_data_cb(data, userpass): (username, password) = userpass dl_album_handler = DownloadAlbumHandler(self.__settings['format']) auth_parser = xml.sax.make_parser() auth_parser.setContentHandler(dl_album_handler) if data is None: # hmm. return try: data = data.decode("utf-8") data = data.replace( "<br>", "" ) # get rid of any stray <br> tags that will mess up the parser data = data.replace( " & ", " & ") # clean up some missing escaping # print data auth_parser.feed(data) auth_parser.close() # process the URI: add authentication info, quote the filename component for some reason parsed = urllib.parse.urlparse(dl_album_handler.url) netloc = "%s:%s@%s" % (username, password, parsed.hostname) spath = os.path.split(urllib.request.url2pathname(parsed.path)) basename = spath[1] path = urllib.request.pathname2url( os.path.join(spath[0], urllib.parse.quote(basename))) authed = (parsed[0], netloc, path) + parsed[3:] audio_dl_uri = urllib.parse.urlunparse(authed) print("download uri for %s is %s" % (sku, audio_dl_uri)) self.__download_album(audio_dl_uri, sku) except MagnatuneDownloadError as e: RB.error_dialog( title=_("Download Error"), message= _("An error occurred while trying to authorize the download.\nThe Magnatune server returned:\n%s" ) % str(e)) except Exception as e: sys.excepthook(*sys.exc_info()) RB.error_dialog( title=_("Error"), message= _("An error occurred while trying to download the album.\nThe error text is:\n%s" ) % str(e)) print("downloading album: " + sku) account = MagnatuneAccount.instance() (account_type, username, password) = account.get() url_dict = {'id': magnatune_partner_id, 'sku': sku} url = magnatune_api_download_uri % (username, password) url = url + urllib.parse.urlencode(url_dict) l = rb.Loader() l.get_url(url, auth_data_cb, (username, password))
def search_lyrics(self, callback, cache_only=False): self.callback = callback status = self.verify_lyric() if status: l = rb.Loader() l.get_url('file://' + urllib.pathname2url(self.cache_path), callback) elif cache_only: self.callback(_("No lyrics found")) elif self.artist == "" and self.title == "": self.callback(_("No lyrics found")) else: def lyric_callback(text): if text is not None: f = file(self.cache_path, 'w') f.write(text) f.close() self.callback(text) else: self.callback(_("No lyrics found")) parser = LyricsParse.Parser(self.artist, self.title) parser.get_lyrics(lyric_callback)
def show_more_cb(self, button): button.set_sensitive(False) if self.more_tracks_url: self.cancel_request(False) print("fetching more tracks") self.loader = rb.Loader() self.loader.get_url(self.more_tracks_url, self.search_tracks_api_cb)
def cover_art_uri_notify(self, db, entry, field, metadata): if entry != self.current_entry: return if not metadata: print "got no-cover-art notification" self.art_widget.set(entry, None, None, False) db.emit_entry_extra_metadata_notify(entry, "rb:coverArt", None) return uri = str(metadata) def loader_cb(data): if data and len(data) >= 1000: pbl = gtk.gdk.PixbufLoader() try: if pbl.write(data) and pbl.close(): pixbuf = pbl.get_pixbuf() if pixbuf: self.art_db.cancel_get_pixbuf(entry) self.on_get_pixbuf_completed( entry, pixbuf, uri, None, None) except GError: pass print "got cover art URI notification: %s" % (uri) l = rb.Loader() l.get_url(uri, loader_cb)
def got_results (self, result, callback, *data): if result is None: callback (None, *data) return result = result.decode('iso-8859-1') # no indication of anything else.. results = re.sub('\n', '', re.sub('\r', '', result)) if re.search('(<tr><td bgcolor="#BBBBBB".*)(More Songs >)', results) is not None: body = re.split('(<tr><td bgcolor="#BBBBBB".*)(More Songs >)', results)[1] entries = re.split('<tr><td bgcolor="#BBBBBB"', body) entries.pop(0) print("found %d entries; looking for [%s,%s]" % (len(entries), self.title, self.artist)) for entry in entries: url = re.split('(\/display[^"]*)', entry)[1] artist = re.split('(Artist:.*html">)([^<]*)', entry)[2].strip() title = re.split('(\/display[^>]*)([^<]*)', entry)[2][1:].strip() if self.artist != "": artist_str = rb.string_match(self.artist, artist) else: artist_str = artist_match + 0.1 title_str = rb.string_match(self.title, title) print("checking [%s,%s]: match strengths [%f,%f]" % (title.strip(), artist.strip(), title_str, artist_str)) if title_str > title_match and artist_str > artist_match: loader = rb.Loader() loader.get_url ('http://display.lyrics.astraweb.com' + url, self.parse_lyrics, callback, *data) return callback (None, *data) return
def search_song(self, songlist, callback, *data): """If artist's page is found, search_song looks for the song. The artist page contains a list of all the albums and links to the songs lyrics from this. """ if songlist is None: callback(None, *data) return # Search for all the <a> # filter for those that has the artist name string_match # and for those which its content is artist string_match # Sort by values given from string_match # and get the best link_section = re.split('LYRICS<BR></FONT>', songlist)[1] link_section = link_section.lower() pattern_song = '<a href="../lyrics/(.*)/(.*).html#([^"]+)" target="_blank"><FONT COLOR="#CCCCCC">(.*)</FONT></a><br>' matches = re.findall(pattern_song.lower(), link_section) best_match = "" for line in matches: artist, album, number, title = line smvalue = rb.string_match(title.lower().replace(' ', ''), self.title.lower().replace(' ', '')) if smvalue > min_song_match: best_match = self.SongFound(smvalue, title, number, album, artist) if not best_match: callback(None, *data) return loader = rb.Loader() url = 'http://www.darklyrics.com/lyrics/%s/%s.html' % ( best_match.artist, best_match.album) self.title = best_match.title self.titlenumber = best_match.number loader.get_url(url, self.parse_lyrics, callback, *data)
def search_artist(self, artist_page, callback, *data): """Search for the link to the page of artist in artists_page """ if artist_page is None: callback(None, *data) return link_section = re.split( '<SCRIPT LANGUAGE="javascript" src="tban2.js"></SCRIPT>', artist_page, 1)[1] pattern_link = '<a href="' pattern_artist = '([^"]*)">*([^<]*)</a><br><br>' links = re.split(pattern_link, link_section.lower()) links.pop(0) best_match = () for line in links: artist = re.findall(pattern_artist, line) if len(artist) == 0: continue artist_link, artist_name = artist[0] artist_url = 'http://www.darklyrics.com/%s' % (artist_link) if artist_link[:5] == 'http:': continue artist_name = artist_name.strip() smvalue = rb.string_match(artist_name, self.artist_ascii) if smvalue > min_artist_match: best_match = (smvalue, artist_url, artist_name) if not best_match: # Lyrics are located in external site callback(None, *data) return loader = rb.Loader() self.artist = best_match[2] loader.get_url(best_match[1], self.search_song, callback, *data)
def search(self, callback, *data): artist = urllib.parse.quote_plus(self.artist) title = urllib.parse.quote_plus(self.title) q = title + ' - ' + artist url = 'http://www.jetlyrics.com/search.php?q=%s' % (q) loader = rb.Loader() loader.get_url(url, self.got_results, callback, *data)
def search(self, db, entry, is_playing, callback, *args): self.callback = callback self.callback_args = args self.entry = entry # if we've got an album ID, we can get the album info directly album_id = db.entry_get(entry, rhythmdb.PROP_MUSICBRAINZ_ALBUMID) if album_id != "": # these sometimes look like full URLs, sometimes not if album_id.startswith(MUSICBRAINZ_RELEASE_PREFIX): album_id = album_id[len(MUSICBRAINZ_RELEASE_PREFIX):] if album_id.endswith(MUSICBRAINZ_RELEASE_SUFFIX): album_id = album_id[:-len(MUSICBRAINZ_RELEASE_SUFFIX)] print "stripped release ID: %s" % album_id url = MUSICBRAINZ_RELEASE_URL % (album_id) loader = rb.Loader() loader.get_url(url, self.__get_release_cb) return # otherwise, maybe we can search for the album.. # nothing to do callback(self, entry, [], *args)
def get(url, complete_cb): def real_complete_cb(resp, loader): data = json.loads(resp.decode("utf-8")) loader.rhythmsub_result = complete_cb(data) loader = rb.Loader() loader.get_url(url, real_complete_cb, loader)
def search_artist(self, artist_page, callback, *data): """Search for the link to the page of artist in artists_page """ if artist_page is None: callback(None, *data) return artist_page = artist_page.decode('iso-8859-1') link_section = re.split('tban.js', artist_page, 1)[1] pattern_link = '<a href="' pattern_artist = '([^"]*)">*([^<]*)<' links = re.split(pattern_link, link_section.lower()) links.pop(0) best_match = () smvalue_bestmatch = 0 for line in links: artist = re.findall(pattern_artist, line) if len(artist) == 0: continue artist_link, artist_name = artist[0] artist_url = 'http://www.darklyrics.com/%s' % (artist_link) if artist_link[:5] == 'http:': continue artist_name = artist_name.strip() smvalue = stringmatch.string_match(artist_name, self.artist_ascii) if smvalue > min_artist_match and smvalue > smvalue_bestmatch: best_match = (smvalue, artist_url, artist_name) smvalue_bestmatch = smvalue if not best_match: # Lyrics are located in external site callback(None, *data) return loader = rb.Loader() self.artist = best_match[2] loader.get_url(best_match[1], self.search_song, callback, *data)
def search_next(self): if len(self.keywords) == 0: print "no keywords left to search" self.on_search_completed(None) return False self.searching = True url = "http://ecs.amazonaws." + self.tld + "/onca/xml" \ "?Service=AWSECommerceService" \ "&AWSAccessKeyId=" + LICENSE_KEY + \ "&AssociateTag=" + ASSOCIATE + \ "&ResponseGroup=Images,ItemAttributes" \ "&Operation=ItemSearch" \ "&ItemSearch.Shared.SearchIndex=Music" job = 1 while job <= MAX_BATCH_JOBS and len(self.keywords) > 0: keyword = self.keywords.pop(0) print "searching keyword: \"%s\"" % keyword keyword = keyword.encode(self.encoding, "ignore") keyword = keyword.strip() keyword = urllib.quote(keyword) url += "&ItemSearch.%d.Keywords=%s" % (job, keyword) job += 1 # Retrieve search for keyword l = rb.Loader() l.get_url(url, self.on_search_response) return True
def selection_changed_cb(self, selection): self.new_model() self.cancel_request() self.build_sc_menu() (model, aiter) = selection.get_selected() if aiter is None: return if self.container_marker_path is not None: apath = self.containers.get_path(aiter) if apath.compare(self.container_marker_path) == 0: print("marker row selected") return [itemtype, url] = model.get(aiter, 1, 2) if itemtype not in self.container_types: return print("loading %s %s" % (itemtype, url)) ct = self.container_types[itemtype] trackurl = url + ct['tracks-url'] + '?linked_partitioning=1&client_id=' + CLIENT_ID self.loader = rb.Loader() if ct['tracks-type'] == 'playlist': self.loader.get_url(trackurl, self.playlist_api_cb) else: self.loader.get_url(trackurl, self.search_tracks_api_cb)
def fetch(self, key, url, callback, *args): """ Retrieve the specified URL, satisfying the request from the cache if possible, and refreshing the cache if necessary. The callback function may return False to indicate that the data passed to it is invalid. Generally this should only happen if the data cannot be parsed and it is likely that a later attempt to fetch from the origin site will result in valid data. """ # check if we've got a fresh entry in the cache print "fetching cache entry %s:%s [%s]" % (self.name, key, url) cachefile = self.check(key, True) if cachefile is not None: # could use a loader here, maybe f = open(cachefile) data = f.read() f.close() if callback(data, *args) is not False: return print "cache entry %s:%s invalidated by callback" % (self.name, key) os.unlink(cachefile) ld = rb.Loader() ld.get_url(url, self.__fetch_cb, url, key, callback, args)
def search(self, callback, *data): wartist = re.sub('%20', '+', urllib.quote(self.artist)) wtitle = re.sub('%20', '+', urllib.quote(self.title)) wurl = 'http://search.lyrics.astraweb.com/?word=%s+%s' % (wartist, wtitle) loader = rb.Loader() loader.get_url (wurl, self.got_results, callback, *data)
def search(self, callback): title_token = clean_token(self._songinfo.ti).encode('GBK', 'ignore') urldata = {'key':title_token, 'go':'go', 'y':1} url = 'http://lrc.bzmtv.com/So.asp?%s' % urllib.urlencode(urldata) log.debug('search url <%s>' % url) rb.Loader().get_url(url, self._on_meta_arrive, callback) return
def _get_next_lyrics(self, callback): if len(self._job) > 0: url = self._job.pop(0) log.info('%s <%s>' % (self.__class__.__name__, url)) rb.Loader().get_url(url, self._on_lyrics_arrive, callback) else: callback(self.__class__.__name__, self._candidate) return
def search(self, callback, *data): artist = urllib.quote(self.artist) title = urllib.quote(self.title) htstring = 'http://api.leoslyrics.com/api_search.php?auth=Rhythmbox&artist=%s&songtitle=%s' % (artist, title) loader = rb.Loader() loader.get_url (htstring, self.got_lyrics, callback, *data)
def search(self, callback, *data): wartist = urllib.parse.quote_plus(self.artist) wtitle = urllib.parse.quote_plus(self.title) wurl = 'http://search.lyrics.astraweb.com/?word=%s+%s' % (wartist, wtitle) loader = rb.Loader() loader.get_url (wurl, self.got_results, callback, *data)
def search(self, callback, *data): artist = urllib.quote(self.artist.replace(' ', '_')) title = urllib.quote(self.title.replace(' ', '_')) htstring = 'http://lyricwiki.org/api.php?artist=%s&song=%s&fmt=text' % (artist, title) loader = rb.Loader() loader.get_url (htstring, self.got_lyrics, callback, *data)
def search(self, callback, *data): path = 'http://www.lyrc.com.ar/en/' wartist = urllib.quote(self.artist) wtitle = urllib.quote(self.title) wurl = 'tema1en.php?artist=%s&songname=%s' % (wartist, wtitle) loader = rb.Loader() loader.get_url (path + wurl, self.got_lyrics, callback, *data)
def search(self, callback, *data): """Do a request of a specific url based on artist's first letter name.""" self.artist_ascii = ''.join(c for c in self.artist.lower() \ if c in string.ascii_letters) self.artist_ascii = self.artist_ascii.lower() firstcharurl = 'http://www.darklyrics.com/%s.html' % ( self.artist_ascii[0]) loader = rb.Loader() loader.get_url(firstcharurl, self.search_artist, callback, *data)
def try_image_urls(self, storekey, store, urls, callback, *args): if len(urls) == 0: print("no more image urls to try") callback(*args) return print("%d urls to try, trying %s" % (len(urls), urls[0])) loader = rb.Loader() loader.get_url(urls[0], self.get_image_cb, (storekey, store, urls, callback, args))
def search(self, callback): artist = clean_token(self._songinfo.ar) if artist == clean_token('Unknown'): artist = '' title = clean_token(self._songinfo.ti) artist_token = urllib.quote(self._clean_token(artist)) title_token = urllib.quote(self._clean_token(title)) url = 'http://www.winampcn.com/lrceng/get.aspx?song=%s&artist=%s&lsong=%s&prec=1&Datetime=20060601' % (title_token, artist_token, title_token) log.debug('search url <%s>' % url) rb.Loader().get_url(url, self._on_meta_arrive, callback) return
def search(self, callback, *data): path = 'http://letras.mus.br/' artist = urllib.parse.quote(self.artist) title = urllib.parse.quote(self.title) join = urllib.parse.quote(' - ') wurl = 'winamp.php?t=%s%s%s' % (artist, join, title) print("search URL: " + wurl) loader = rb.Loader() loader.get_url(path + wurl, self.got_lyrics, callback, *data)
def search(self, callback, *data): # encode search string title_encode = urllib.quote( detect_charset(self.title).encode('gbk').replace(' ', '')) artist_encode = urllib.quote( detect_charset(self.artist).encode('gbk').replace(' ', '')) url = 'http://www.winampcn.com/lyrictransfer/get.aspx?song=%s&artist=%s&lsong=%s&Datetime=20060601' % ( title_encode, artist_encode, title_encode) loader = rb.Loader() loader.get_url(url, self.got_lyrics, callback, *data)
def maybe_more_containers(self): self.more_containers_idle = 0 if self.container_loader is not None: return False (start, end) = self.container_view.get_visible_range() if self.container_marker_path.compare(end) == 1: return False self.container_loader = rb.Loader() self.container_loader.get_url(self.more_containers_url, self.search_containers_api_cb) return False