def getTrackInfo(track, artist): """ Returns a dictionary with possible keys: 'title', 'artist', 'album', 'trackPosition', 'picture' If no match found, returns empty dictionary """ track = track.encode('utf-8') artist = artist.encode('utf-8') try: url = 'http://ws.audioscrobbler.com/2.0/?' url += urllib.urlencode({ 'method' :'track.getinfo', 'api_key' :LASTFM_API_KEY, 'artist' :artist, 'track' :track, 'autocorrect' :1 }) ret = getSourceCode(url) #except urllib2.HTTPError: except AttributeError: return {} else: info = {} tree = xml.etree.ElementTree.XML(ret) if tree is not None: tree = tree.find('track') info['title'] = tree.find('name').text info['artist'] = tree.find('artist').find('name').text try: tree = tree.find('album') info['album'] = tree.find('title').text info['trackPosition'] = tree.attrib['position'] info['picture'] = getPicture(tree.findall('image')[-1].text) except AttributeError: pass return info
def __getEncryptedLyrics(trackUid, lyricId, checkSum, nonExplicit, authToken): url = "http://www.pandora.com/services/ajax/?" url += urllib.urlencode({ 'method' :'lyrics.getLyrics', 'trackUid' :trackUid, 'checkSum' :checkSum, 'nonExplicit' :nonExplicit, 'authToken' :authToken }) ret = getSourceCode(url) decryptionKey = re.search('var k="([^"]*)"', ret).group(1) # functions in javascript can contain ", which makes python dictionary # parsing throw errors, workaround by replacing them out ret = re.sub('(function[^,]*)', '0', ret).replace('\\u00',r'\x') # use ast.literal_eval vs. eval because it's safer encrypted = ast.literal_eval(ret) encryptedLyrics= encrypted['lyrics'] return __decryptLyrics(encryptedLyrics, decryptionKey)
def getLyrics(track, artist): """ Returns a dictionary with possible keys: lyrics If no match found, returns empty dictionary """ track = track.encode('utf-8') artist = artist.encode('utf-8') url = 'http://www.pandora.com/music/song/%s/%s' % (urllib.quote_plus(artist.lower()), urllib.quote_plus(track.lower())) ret = getSourceCode(url) try: trackUid = regex_trackUid.search(ret).group(1) intermMatch = regex_lyricIdCheckSum.search(ret) lyricId = intermMatch.group(1) checkSum = intermMatch.group(2) nonExplicit = 'false' authToken = 'null' except AttributeError: return {} else: return __getEncryptedLyrics(trackUid, lyricId, checkSum, nonExplicit, authToken)
def getAlbumInfo(album, artist): """ Returns a dictionary with possible keys: 'album', 'artist', 'picture', 'totalTracks' If no match found, returns empty dictionary """ if (album, artist) in albumCache: return albumCache[(album,artist)] album = album.encode('utf-8') artist = artist.encode('utf-8') try: url = 'http://ws.audioscrobbler.com/2.0/?' url += urllib.urlencode({ 'method' :'album.getinfo', 'api_key' :LASTFM_API_KEY, 'album' :album, 'artist' :artist, 'autocorrect' :1 }) ret = getSourceCode(url) except urllib2.HTTPError: return {} else: info = {} tree = xml.etree.ElementTree.XML(ret) if tree is not None: tree = tree.find('album') info['album'] = tree.find('name').text info['artist'] = tree.find('artist').text try: info['picture'] = getPicture(tree.findall('image')[-1].text) except AttributeError: pass tree = tree.find('tracks') info['totalTracks'] = str(len(list(tree))) albumCache[(album,artist)] = info return info