def track_played(self, track, skipped= False, locked=False): if not locked: self.acquire() if len(self._history) == 0 or self._history[0]['track'] != track: self._logger.error(u"played: no record of starting this track") if not locked: self.release() return if not skipped: self._lastplayed_track = track timestamp= now() self._history[0]['skipped']= skipped if len(self._history) > 1: for i in range(min(self.maxhistory, len(self._history) - 1)): if skipped and self._history[1+i]['skipped']: continue factor= self.__factor_relation(i, self.maxhistory) hist_track= self._history[1+i]['track'] hist_skipped = self._history[1+i]['skipped'] track_relation = TrackRelationFactory.get(track, hist_track) track_relation.update(not hist_skipped, factor) self._logger.info(u"relation updated: %s" % track_relation) self._relation_resetted = False self.update_ranking() if not locked: self.release()
def _similar_tracks(self, artist_nameA, track_titleA, artist_nameB, track_titleB, match, source, locked=False): if not locked: self.acquire() #self._logger.debug(u"%s: [%s-%s]-[%s-%s] %2.2f" % (source, artist_nameA, # track_titleA, artist_nameB, track_titleB, match)) trackA = TrackFactory.by_key(TrackFactory.get_key(artist_nameA, track_titleA)) trackB = TrackFactory.by_key(TrackFactory.get_key(artist_nameB, track_titleB)) #if not trackA: self._logger.debug(u"similar_tracks[%s-%s]: not found" % # (artist_nameA, track_titleA)) #if not trackB: self._logger.debug(u"similar_tracks[%s-%s]: not found" % # (artist_nameB, track_titleB)) if trackA and trackB: relation = TrackRelationFactory.get(trackA, trackB) old_rating = relation.rating relation.rate(0.75 + 0.25 * match) self._logger.debug(u"%s [%s]-[%s] m(%2.2f) r(%2.2f|%2.2f)" % (source, trackA, trackB, match, relation.rating, old_rating)) if self._queue_lookup_results: if self._lastfm: self._lastfm.similar_tracks_low(self.similar_tracks, artist_nameB, track_titleB, self._thres_lastfm_lookup) if self._echonest: self._echonest.similar_tracks_low(self.similar_tracks, artist_nameB, track_titleB, self._thres_lastfm_lookup) if not locked: self.release()
def lookup(self, track, locked=False): if not locked: self.acquire() ArtistRelationFactory.load_artist(track.artist) TrackRelationFactory.load_track(track) # queue similar artists / tracks lookup from lastfm if self._lastfm: self._lastfm.similar_artists(self.similar_artists, track.artist.name, self._thres_lastfm_lookup) self._lastfm.similar_tracks(self.similar_tracks, track.artist.name, track.title, self._thres_lastfm_lookup) # queue similar artists / tracks lookup from echonest if self._echonest: self._echonest.similar_artists(self.similar_artists, track.artist.name, self._thres_echonest_lookup) self._echonest.similar_tracks(self.similar_tracks, track.artist.name, track.title, self._thres_echonest_lookup) if not locked: self.release()
def _track_queue_updated(self, track, skipped, locked=False): if self._playing_track: reference_track = self._playing_track elif self._lastplayed_track: reference_track = self._lastplayed_track else: return if not locked: self.acquire() relation = TrackRelationFactory.get(track, reference_track) relation.update(not skipped, self._queue_update_factor) self._logger.debug(relation) self.update_ranking() if not locked: self.release()
def seed(self, track, locked=False): """Calculate relations based on track as seed. """ if not locked: self.acquire() benchmark = Benchmark() timestamp = now() seed_track = set() seed_artist = set() if track: seed_track.add(track) seed_artist.add(track.artist) self.lookup(track, True) # check artist relations cnt = 0 benchmark.start() tt = [] for seed_a in seed_artist.union(self._seed_artists): self._logger.info(u'check artist relations for {}'.format(seed_a)) for artist_relation in ArtistRelationFactory.by_artist(seed_a): cnt += 1 other_artist = artist_relation.artistA if artist_relation.artistA.name == seed_a.name: other_artist = artist_relation.artistB other_artist.relation_sum += artist_relation.rating other_artist.relation_cnt += 1 other_artist.relation = (other_artist.relation_sum / other_artist.relation_cnt) top_ten(tt, u'artist related with {}({}/{}={}) to {}'.format( scale_rating(artist_relation.rating), scale_rating(other_artist.relation_sum), scale_rating(other_artist.relation_cnt), scale_rating(other_artist.relation), other_artist), artist_relation.rating) artist_relation.lastused = timestamp top_ten_dump(tt, self._logger.info) self._logger.info(u"update ranking: check artist took %s" % benchmark) self._logger.info(u"updated %d artist(s)" % cnt) cnt = 0 benchmark.start() tt = [] for seed_t in seed_track.union(self._seed_tracks): self._logger.info(u'check track relations for {}'.format(seed_t)) for track_relation in TrackRelationFactory.by_track(seed_t): other_track = track_relation.trackA if track_relation.trackA.title == seed_t.title and \ track_relation.trackA.artist.name == seed_t.artist.name: other_track = track_relation.trackB cnt += 1 if not track.ban: other_track.relation_sum += track_relation.rating other_track.relation_cnt += 1 other_track.relation = (other_track.relation_sum / other_track.relation_cnt) top_ten(tt, u'track related with {} to {}'.format( scale_rating(track_relation.rating), other_track), track_relation.rating) track_relation.lastused = timestamp top_ten_dump(tt, self._logger.info) self._logger.info(u"update ranking: check track took %s" % benchmark) self._logger.info(u"updated %d track(s)" % cnt) if not locked: self.release()
def _activate(self, dummy=None): self.acquire() TrackRelationFactory.check_active() ArtistRelationFactory.check_active() self.release()
def __init__(self, config): Log.__init__(self, self._title) self._logger.info(u"init") Worker.__init__(self, lifo=False) self._config = config self._library_filename = self._config.get('Library', 'path', join(self._config.configdir(), 'library.pkl')) Factories.clear() Logger.set_logger(self._logger) if self._config.get('TrackRelation', 'use_db', True): TrackRelationFactory.use_db() TrackRelationFactory.set_path(self._config.get('TrackRelation', 'path', join(self._config.configdir(), ''))) else: TrackRelationFactory.use_fs() TrackRelationFactory.set_path(self._config.get('TrackRelation', 'path', join(self._config.configdir(), 'track'))) TrackRelationFactory.set_maxentries( self._config.get('TrackRelation', 'maxentries', 500)) if self._config.get('ArtistRelation', 'use_db', True): ArtistRelationFactory.use_db() ArtistRelationFactory.set_path(self._config.get('ArtistRelation', 'path', join(self._config.configdir(), ''))) else: ArtistRelationFactory.use_fs() ArtistRelationFactory.set_path(self._config.get('ArtistRelation', 'path', join(self._config.configdir(), 'artist'))) ArtistRelationFactory.set_maxentries( self._config.get('ArtistRelation', 'maxentries', 500)) if self._config.get('Lookup', 'QueueResults', 'False') == 'True': self._queue_lookup_results = True else: self._queue_lookup_results = False # FIXME: log if one of those libs is not present if self._config.get('Lookup', 'UseLastFM', 'True') == 'True': self._lastfm = LastFM(config) self._lastfm.start() self._thres_lastfm_lookup = self._config.getint('Lookup', 'ThresholdLastFM', self._thres_lastfm_lookup) if self._config.get('Lookup', 'UseEchoNest', 'True') == 'True': self._echonest = EchoNest(config) self._echonest.start() self._thres_echonest_lookup = self._config.getint('Lookup', 'ThresholdEchoNest', self._thres_echonest_lookup) # read, normalize and update ranking factors factor = 0.0 for k in self._factor_ranking.keys(): self._factor_ranking[k] = self._config.getfloat('Ranking', "factor%s" % k, self._factor_ranking[k]) factor += self._factor_ranking[k] for k in self._factor_ranking.keys(): self._factor_ranking[k] /= factor self._config.set('Ranking', "factor%s" % k, self._factor_ranking[k]) self._relation_decay = self._config.getfloat('Ranking', 'RelationDecay', self._relation_decay) self._queue_update_factor = self._config.getfloat('Rating', 'QueueUpdateFactor', self._queue_update_factor) self._unplayed_rating = self._config.getfloat('Ranking', 'UnplayedRating', self._unplayed_rating) self._thres_track_lastplayed = self._config.getint('Ranking', 'ThresholdTrackLastPlayed', self._thres_track_lastplayed) self._thres_track_laststarted= self._config.getint('Ranking', 'ThresholdTrackLastStarted', self._thres_track_laststarted) self._thres_track_lastqueued= self._config.getint('Ranking', 'ThresholdTrackLastQueued', self._thres_track_lastqueued) self._thres_artist_lastplayed = self._config.getint('Ranking', 'ThresholdArtistLastPlayed', self._thres_artist_lastplayed) self._thres_artist_laststarted= self._config.getint('Ranking', 'ThresholdArtistLastStarted', self._thres_artist_laststarted) self._thres_artist_lastqueued= self._config.getint('Ranking', 'ThresholdArtistLastQueued', self._thres_artist_lastqueued)