Exemple #1
0
  def _update_ranking(self, locked=False):
    benchmark = Benchmark()
    if not locked: self.acquire()

    seed_track = None
    if self._lastplayed_track:
      seed_track = self._lastplayed_track
    elif self._playing_track:
      seed_track = self._playing_track

    if not self._relation_resetted:
      benchmark.start()
      self._relation_resetted = True
      for track in TrackFactory.active_tracks():
        track.relation_old = track.relation
        track.relation_sum = 0.0
        track.relation_cnt = 0
      for artist in ArtistFactory.active_artists():
        artist.relation_old = artist.relation
        artist.relation_sum = 0.0
        artist.relation_cnt = 0
      self._logger.info(u"update ranking: resetting took %s" % benchmark)

    has_active_tracks = False
    for track in TrackFactory.active_tracks():
      has_active_tracks = True
      break

    benchmark.start()
    # new relation = old relation * decay
    # e.g. for decay = 0.5 (0.75)
    # decfacA = 0.5 * 0.5 = 0.25 (0.75 * 0.5 = 0.375)
    # decfacB = 1.0 - 0.5 = 0.5 (1.0 - 0.75 = 0.25)
    # relation_old=0.75 -> 0.25+0.5*0.75=0.625 (0.375+0.25*0.75=0.5625)
    decfacA = self._relation_decay * 0.5
    decfacB = 1.0 - self._relation_decay
    for track in TrackFactory.active_tracks():
      if (track.relation_old > 0.501) or (track.relation_old < 0.499):
        track.relation = (decfacA + decfacB * track.relation_old)
      else:
        track.relation = 0.5

    for artist in ArtistFactory.active_artists():
      if (artist.relation_old > 0.501) or (artist.relation_old < 0.499):
        artist.relation = (decfacA + decfacB * artist.relation_old)
      else:
        artist.relation = 0.5

    self._logger.info(u"update ranking: set old relation + decay took %s" %
        benchmark)

    if has_active_tracks:
      self._ranking_updated = True
      self.seed(seed_track, True)
      benchmark.start()
      at = []
      tt = []
      for track in TrackFactory.active_tracks():
        """
        so we have:
          ranking   [0-1.0] (old)
          rating    [0-1.0]
          relation  [0-1.0]
          random    [0-1.0]
        and:
          factor min(track_lastplayed/started,artist_lastplayed/started) [0-1.0]
          ? moved to next_file()
        """
        artist = track.artist
        r = random()
        # calculate new ranking
        if track.boost:
          self._logger.info(u"pre boost: %s" % track)
          track.relation = (track.relation + 99.0) / 100.0
          self._logger.info(u"post boost: %s" % track)
        elif track.ban:
          track.relation = 0.0

        # mix with artist relation if we don't have a track relation
        if track.relation_cnt == 0:
          if artist.relation_cnt > 0:
            track.relation = (0.75 * track.relation + 0.25 * artist.relation)
            top_ten(at, u'relation cnt = {} with {} now {} to {}'.format(
                artist.relation_cnt, scale_rating(artist.relation),
                scale_rating(track.relation), artist), track.relation)
        else:
          top_ten(tt, u'relation cnt = {} with {} to {}'.format(
              track.relation_cnt, scale_rating(track.relation), track),
              track.relation)

        track.ranking = (
            self._factor_ranking['rating'] * track.get_rating() +
            self._factor_ranking['relation'] * track.relation +
            self._factor_ranking['random'] * r
            )

      self._logger.info(u"update ranking: took %s" % benchmark)
    self._update_queued = False
    if not locked: self.release()
Exemple #2
0
  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()