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 next_file(self, locked=False): self._logger.info(u"next file: start") if not locked: self.acquire() if not self._ranking_updated: self.update_ranking() best_ranking = 0 best_tracks = [] tt = [] timestamp = now() # calculate last_*_timestamps (played / queued / started) track_lastplayed_timestamp = timestamp - self._thres_track_lastplayed track_laststarted_timestamp = timestamp - self._thres_track_laststarted track_lastqueued_timestamp = timestamp - self._thres_track_lastqueued artist_lastplayed_timestamp = timestamp - self._thres_artist_lastplayed artist_laststarted_timestamp = timestamp - self._thres_artist_laststarted artist_lastqueued_timestamp = timestamp - self._thres_artist_lastqueued has_active_tracks = False for track in TrackFactory.active_tracks(): has_active_tracks = True artist = track.artist factor = 1.0 if (track.lastplayed > track_lastplayed_timestamp): factor = min(factor, 1.0 - ((1.0 * track.lastplayed - track_lastplayed_timestamp) / self._thres_track_lastplayed)) if (artist.lastplayed > artist_lastplayed_timestamp): factor = min(factor, 1.0 - ((1.0 * artist.lastplayed - artist_lastplayed_timestamp) / self._thres_artist_lastplayed)) if (track.laststarted > track_laststarted_timestamp): factor = min(factor, 1.0 - ((1.0 * track.laststarted - track_laststarted_timestamp) / self._thres_track_laststarted)) if (artist.laststarted > artist_laststarted_timestamp): factor = min(factor, 1.0 - ((1.0 * artist.laststarted - artist_laststarted_timestamp) / self._thres_artist_laststarted)) if (track.lastqueued > track_lastqueued_timestamp): factor = min(factor, 1.0 - ((1.0 * track.lastqueued - track_lastqueued_timestamp) / self._thres_track_lastqueued)) if (artist.lastqueued > artist_lastqueued_timestamp): factor = min(factor, 1.0 - ((1.0 * artist.lastqueued - artist_lastqueued_timestamp) / self._thres_artist_lastqueued)) ranking = int(self._ranking_base * factor * track.ranking) if ranking > best_ranking: self._logger.debug("%2.2f (best=): %s" % (ranking, track)) best_ranking = ranking best_tracks = [track] elif ranking == best_ranking: self._logger.debug("%2.2f (best+): %s" % (ranking, track)) best_tracks.append(track) top_ten(tt, track, ranking) if not has_active_tracks: self._logger.error(u"No active tracks") if not locked: self.release() return None top_ten_dump(tt, self._logger.info, u"rank") self._logger.info("best tracks: %d" % (len(best_tracks))) best_track = choice(best_tracks) best_track.started() # pick the best file best_rating = 0.0 best_files = [] for file in best_track.files(): if not file.active: continue t = file.playcount / (1.0 + file.skipcount) if t > best_rating: best_rating = t best_files = [file] elif t == best_rating: best_files.append(file) if not locked: self.release() self._logger.info(u"next file: stop") return choice(best_files)