def set_track_correction(self, lookup, echo_title, echo_id, success=True): if success: self._correction_track[lookup]= { 'expires': now() + self._threshold, 'title': echo_title, 'id': echo_id } else: self._correction_track[lookup]= { 'expires': now() + self._threshold_failed, 'title': echo_title, 'id': echo_id } self._changed = True
def set_artist_correction(self, artist, echo_artist, echo_id, success=True): if success: self._correction_artist[artist]= { 'expires': now() + self._threshold, 'artist': echo_artist, 'id': echo_id } else: self._correction_artist[artist]= { 'expires': now() + self._threshold_failed, 'artist': echo_artist, 'id': echo_id } self._changed = True
def _query(self, method, parameters, post=False): timestamp= now() if abs(timestamp - self._last_request_timestamp) < 5: sleep(5 - abs(timestamp - self._last_request_timestamp)) self._last_request_timestamp= timestamp if post: url, data = self._get_url_post(method, parameters) else: url = self._get_url(method, parameters) try: if post: parameters['format']= 'xml' parameters['api_key']= self._api_key content_type, body = self._encode_multipart_formdata(parameters) headers = { 'Content-Type' : content_type, 'Content-Length' : str(len(body)) } # self.log_d(u"_query(content_type: %s)" % (content_type)) # self.log_d(u"_query(headers: %s)" % (headers)) # self.log_d(u"_query(body: %s)" % (body)) request = Request(url, body, headers) return urlopen(request).read().decode('utf-8') #return urlopen(request).read() else: self.log_d(u"_query(url: %s)" % url) return urlopen(url).read().decode('utf-8') except IOError, e: # Note: we get 400 Bad Request when doing catalog/profile for a none # existing catalog. works in the browser though... hmm... self.log_e(u"_query(IOError: failed to fetch %s, %s)" % (url, e)) self.log_e(u"_query(%s)" % (e.read())) return e.read()
def set_similar_artists(self, artist, result): # unused (copy from lastfm) self._similar_artists[artist]= { 'expires': now() + self._threshold, 'result': result } self._changed = True
def get_similar_artists(self, artist, mbid=None, limit = -1): # unused (copy from lastfm) lfm_artist = self.get_artist_correction(artist) if lfm_artist in self._similar_artists: if self._similar_artists[lfm_artist]['expires'] > now(): self.log_d(u"get_similar_artists(%s: cached)" % (artist)) return self._similar_artists[lfm_artist]['result'] result = [] parameters = { 'artist': lfm_artist } if mbid != None: parameters['mbid']= mbid if limit > 0: parameters['limit']= limit xml = self._query('artist.getsimilar', parameters) for artist_xml in self._get_tags('artist', xml): artist_name = self.urldecode(self._get_tag('name', artist_xml).lower()) artist_mbid = self._get_tag('mbid', artist_xml).lower() artist_match = float(self._get_tag('match', artist_xml)) result.append({ 'artist_name': artist_name, 'mbid': artist_mbid, 'match': artist_match }) self.set_similar_artists(lfm_artist, result) self.log_d(u"get_similar_artists(%s found %d)" % (artist, len(result))) return result
def get_track_correction(self, artist, title): lookup = u"%s-%s" % (artist, title) if lookup in self._correction_track: if self._correction_track[lookup]['expires'] > now(): self.log_d(u"get_track_correction(%s-%s: cached)" % (artist, title)) return self._correction_track[lookup]['title'] result = title parameters = { 'artist': artist, 'track': title } xml = self._query('track.getcorrection', parameters) for track_xml in self._get_tags('track', xml): result = self.urldecode(self._get_tag('name', track_xml)).lower() lfm_artist = self.urldecode( self._get_tag('name', self._get_tag('artist', track_xml)) ).lower() self.set_artist_correction(artist, lfm_artist) break """ even if we don't get a correction from last.fm we 'mark' it as corrected to prevent further api calls """ self.set_track_correction(lookup, result) if title == result: self.log_d(u"get_track_correction(%s-%s)" % (artist, title)) else: self.log_d(u"get_track_correction(%s-%s > %s)" % (artist, title, result)) return result
def get_similar_tracks(self, artist, title, limit = 25): track_id = self.get_track_id(artist, title) if track_id in self._similar_tracks: if self._similar_tracks[track_id]['expires'] > now(): self.log_d(u"get_similar_tracks(%s-%s: cached)" % (artist, title)) return self._similar_tracks[track_id]['result'] result = [] parameters = { 'song_id': track_id, 'type': 'catalog', 'seed_catalog': self.get_catalog_id() } if limit > 0: parameters['results']= limit xml = self._query('playlist/static', parameters) self.log(xml) track_match = 1.0 for track_xml in self._get_tags(u'song', xml): track_title = self.urldecode(self._get_tag(u'title', track_xml)).lower() artist_name = self.urldecode( self._get_tag(u'artist_name', track_xml)).lower() self.log_d(u"%s - %s - %2.2f" % ( artist_name, track_title, track_match ), -1) result.append({ 'artist_name': artist_name , 'track_title': track_title , 'match': track_match}) track_match*=.99 self.log(result) self.set_similar_tracks(track_id, result) self.log_d(u"get_similar_tracks(%s - %s found %d)" % (artist, title, len(result))) return result
def get_top_tracks(self, artist, mbid=None, limit = -1): lfm_artist = self.get_artist_correction(artist) if lfm_artist in self._top_tracks: if self._top_tracks[lfm_artist]['expires'] > now(): self.log_d(u"get_top_tracks(%s: cached)" % (artist)) return self._top_tracks[lfm_artist]['result'] result = [] parameters = { 'artist': lfm_artist } if mbid != None: parameters['mbid']= mbid if limit > 0: parameters['limit']= limit xml = self._query('artist.gettoptracks', parameters) if limit > 0: rank_max = limit else: rank_max = 50 rank = 0 for track_xml in self._get_tags(u'track', xml): track_title = self._get_tag(u'name', track_xml).lower() result.append({ 'track_title': track_title, 'rating': (1.0 * rank_max - rank) / rank_max }) rank+= 1 self.set_top_tracks(lfm_artist, result) return result
def get_artist_correction(self, artist): if artist in self._correction_artist: if self._correction_artist[artist]['expires'] > now(): self.log_d(u"get_artist_correction(%s: cached)" % (artist)) return self._correction_artist[artist]['artist'] result = artist artist_id = "" parameters = { 'name' : artist, 'results' : 1 } xml = self._query('artist/search', parameters) found = False for artist_xml in self._get_tags('artist', xml): result = self.urldecode(self._get_tag('name', artist_xml).lower()) artist_id = self.urldecode(self._get_tag('id', artist_xml)) found = True break """ even if we don't get a correction from last.fm we 'mark' it as corrected to prevent further api calls """ self.set_artist_correction(artist, result, artist_id, found) if artist == result: self.log_d(u"get_artist_correction(%s(%s))" % (artist, artist_id)) else: self.log_d(u"get_artist_correction(%s ~ %s(%s))" % (artist, result , artist_id)) return result
def _expire(self, lookup): timestamp= now() expired_keys= set() for k in lookup: #if lookup[k]['expires'] < timestamp: expired_keys.add(k) for k in expired_keys: lookup.pop(k) return len(expired_keys)
def _query(self, method, parameters): timestamp= now() if abs(timestamp - self._last_request_timestamp) < 5: sleep(5 - abs(timestamp - self._last_request_timestamp)) self._last_request_timestamp= timestamp url = self._get_url(method, parameters) try: self.log_d(u"_query(url: %s)" % url) return urlopen(url).read().decode('utf-8') except IOError: self.log_e(u"_query(IOError: failed to fetch %s)" % (url)) return ""
def get_artist_correction(self, artist): if artist in self._correction_artist: if self._correction_artist[artist]['expires'] > now(): self.log_d(u"get_artist_correction(%s: cached)" % (artist)) return self._correction_artist[artist]['artist'] result = artist parameters = {} parameters['artist']= artist xml = self._query('artist.getcorrection', parameters) for artist_xml in self._get_tags('artist', xml): result = self.urldecode(self._get_tag('name', artist_xml).lower()) break """ even if we don't get a correction from last.fm we 'mark' it as corrected to prevent further api calls """ self.set_artist_correction(artist, result) if artist == result: self.log_d(u"get_artist_correction(%s)" % (artist)) else: self.log_d(u"get_artist_correction(%s ~ %s)" % (artist, result)) return result
def get_similar_tracks(self, artist, title, mbid = None, limit = -1): lfm_title = self.get_track_correction(artist, title) lfm_artist = self.get_artist_correction(artist) lookup = u"%s-%s" % (lfm_artist, lfm_title) if lookup in self._similar_tracks: if self._similar_tracks[lookup]['expires'] > now(): self.log_d(u"get_similar_tracks(%s-%s: cached)" % (artist, title)) return self._similar_tracks[lookup]['result'] result = [] parameters = { 'artist': lfm_artist, 'track': lfm_title } if mbid != None: parameters['mbid']= mbid if limit > 0: parameters['limit']= limit xml = self._query('track.getsimilar', parameters) for track_xml in self._get_tags(u'track', xml): track_title = self.urldecode(self._get_tag(u'name', track_xml)).lower() artist_name = self.urldecode( self._get_tag(u'name', self._get_tag(u'artist', track_xml)) ).lower() artist_mbid = self.urldecode( self._get_tag(u'mbid', self._get_tag(u'artist', track_xml)) ).lower() track_match = float(self._get_tag(u'match', track_xml)) self.log_d(u"%s - %s - %s- %2.2f" % ( artist_name, track_title, artist_mbid, track_match ), -1) result.append({ 'artist_name': artist_name , 'track_title': track_title , 'mbid': artist_mbid , 'match': track_match}) self.set_similar_tracks(lookup, result) self.log_d(u"get_similar_tracks(%s - %s found %d)" % (artist, title, len(result))) return result
def get_track_correction(self, artist, title): lookup = u"%s-%s" % (artist, title) if lookup in self._correction_track: if self._correction_track[lookup]['expires'] > now(): self.log_d(u"get_track_correction(%s-%s: cached)" % (artist, title)) return self._correction_track[lookup]['title'] result = title echo_track_id = "" echo_artist = artist echo_artist_id = "" parameters = { 'artist': artist, 'title': title, 'results': '1' } xml = self._query('song/search', parameters) found = False for track_xml in self._get_tags('song', xml): result = self.urldecode(self._get_tag('title', track_xml)).lower() echo_track_id = self.urldecode(self._get_tag('id', track_xml)) echo_artist = self.urldecode(self._get_tag('artist_name' , track_xml)).lower() echo_artist_id = self.urldecode(self._get_tag('artist_id', track_xml)) self.set_artist_correction(artist, echo_artist, echo_artist_id) found = True break """ even if we don't get a correction from echonest we 'mark' it as corrected to prevent further api calls """ self.set_track_correction(lookup, result, echo_track_id, found) if title == result: self.log_d(u"get_track_correction(%s-%s(%s))" % (artist , title, echo_track_id)) else: self.log_d(u"get_track_correction(%s-%s > %s(%s))" % (artist, title , result, echo_track_id)) return result
def set_top_tracks(self, artist, result): self._top_tracks[artist]= { 'expires': now() + self._threshold, 'result': result } self._changed = True
def set_track_correction(self, lookup, lfm_title): self._correction_track[lookup]= { 'expires': now() + self._threshold, 'title': lfm_title } self._changed = True
def set_similar_tracks(self, lookup, result): self._similar_tracks[lookup]= { 'expires': now() + self._threshold, 'result': result } self._changed = True
def set_similar_artists(self, artist, result): self._similar_artists[artist]= { 'expires': now() + self._threshold, 'result': result } self._changed = True
def set_artist_correction(self, artist, lfm_artist): self._correction_artist[artist]= { 'expires': now() + self._threshold, 'artist': lfm_artist } self._changed = True