コード例 #1
0
ファイル: library.py プロジェクト: pscn/ads
 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()
コード例 #2
0
ファイル: test_artist_rating.py プロジェクト: pscn/ads
  def testArtistRatingPickle(self):
    Factories.clear()
    trackA= TrackFactory.get(self.artist, self.titleA)
    trackB = TrackFactory.get(self.artist, self.titleB)
    artist = trackA.artist
    trackA.played()
    trackB.skipped()
    rating = artist.rating
    i = 0
    for r in RatingFactory.ratings():
      i+=1
    # track init rating: 1
    # artist init rating: 2
    # track play rating: 3
    # artist play rating: 4
    # track skip rating: 5
    # artist skip rating: 6
    self.assertEqual(i, 6)

    state = pickle.dumps(Factories.getstate())
    Factories.clear()
    pickle.loads(state)

    i = 0
    for r in RatingFactory.ratings():
      i+=1
    self.assertEqual(i, 6)

    track = TrackFactory.get(self.artist, self.titleA)
    artist = track.artist
    self.assertEqual(artist.rating, rating)
コード例 #3
0
ファイル: test_track.py プロジェクト: pscn/ads
  def testTrackClear(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    track.test = self.track_test
    self.assertEqual(track.test, self.track_test)

    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    self.assertEqual(track.test, None)
コード例 #4
0
ファイル: test_track_rating.py プロジェクト: pscn/ads
  def testRatingClear(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    track.played()
    track.skipped()

    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    self.assertEqual(track.ratingref.playcount, 0)
    self.assertEqual(track.ratingref.skipcount, 0)
コード例 #5
0
ファイル: test_artist_rating.py プロジェクト: pscn/ads
  def testArtistRatingClear(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.titleA)
    track.played()
    track.skipped()

    Factories.clear()
    track = TrackFactory.get(self.artist, self.titleA)
    artist = track.artist
    self.assertEqual(artist.rating, 0.5)
コード例 #6
0
ファイル: track_relation.py プロジェクト: pscn/ads
 def __setstate__(self, dict):
   trackA = TrackFactory.by_key(dict['trackA_key'])
   del dict['trackA_key']
   trackB = TrackFactory.by_key(dict['trackB_key'])
   del dict['trackB_key']
   ratingref = RatingFactory.by_key(dict['ratingref_key'])
   del dict['ratingref_key']
   self.__dict__ = dict
   self.trackA = trackA
   self.trackB = trackB
   self.ratingref = ratingref
コード例 #7
0
ファイル: test_track.py プロジェクト: pscn/ads
  def testTrackRef(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    track.test = self.track_test
    track.artist.test = self.artist_test

    trackRef = TrackFactory.get(self.artist, self.title)

    self.assertEqual(trackRef.title, self.title)
    self.assertEqual(trackRef.test, self.track_test)
    self.assertEqual(trackRef.artist.name, self.artist)
    self.assertEqual(trackRef.artist.test, self.artist_test)
コード例 #8
0
ファイル: test_track_rating.py プロジェクト: pscn/ads
 def testRatingRef(self):
   Factories.clear()
   track = TrackFactory.get(self.artist, self.title)
   track1 = TrackFactory.get(self.artist, self.title)
   track.played()
   track.skipped()
   self.assertEqual(track1.ratingref.stable, 0.5)
   track.played(0.5)
   track.skipped(0.5)
   self.assertEqual(track1.ratingref.playcount, 1)
   self.assertEqual(track1.ratingref.skipcount, 1)
   self.assertEqual(track1.ratingref.playfactor, 1.5)
   self.assertEqual(track1.ratingref.skipfactor, 1.5)
コード例 #9
0
ファイル: test_track_rating.py プロジェクト: pscn/ads
 def testRatingRef2(self):
   Factories.clear()
   track = TrackFactory.get(self.artist, self.title)
   track2 = TrackFactory.get(self.artist2, self.title2)
   track.played()
   track.skipped()
   track.played(0.5)
   track.skipped(0.5)
   track.ratingref.test = self.rating_test
   track2.played()
   track2.skipped()
   track2.played(0.5)
   self.assertNotEqual(track.ratingref.test, track2.ratingref.test)
   track2.skipped(0.5)
   self.assertEqual(track.ratingref.test, track2.ratingref.test)
コード例 #10
0
ファイル: test_track_rating.py プロジェクト: pscn/ads
  def testRatingPickle(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    track.played()
    track.skipped()
    track.played(0.5)
    track.skipped(0.5)
    track.ratingref.test = self.rating_test

    state = pickle.dumps(Factories.getstate())
    Factories.clear()
    pickle.loads(state)

    track = TrackFactory.get(self.artist, self.title)
    self.assertEqual(track.ratingref.playcount, 1)
    self.assertEqual(track.ratingref.skipcount, 1)
    self.assertEqual(track.ratingref.playfactor, 1.5)
    self.assertEqual(track.ratingref.skipfactor, 1.5)
    self.assertEqual(track.ratingref.test, self.rating_test)
コード例 #11
0
ファイル: library.py プロジェクト: pscn/ads
 def _reset(self, full=False):
   """ clear recent play history + unset last played track """
   self.acquire()
   self._history.clear()
   self._lastplayed_track = None
   self._playing_track = None
   for track in TrackFactory.active_tracks():
     track.ranking = 0.5
     track.relation = 0.5
     track.relation_old = 0.5
     track.relation_cnt = 0
   if full:
     for track in TrackFactory.active_tracks():
       track.lastplayed = 0
       track.laststarted = 0
       track.lastqueued = 0
     for artist in ArtistFactory.active_artists():
       artist.lastplayed = 0
       artist.laststarted = 0
       artist.lastqueued = 0
   self.release()
コード例 #12
0
ファイル: test_artist_rating.py プロジェクト: pscn/ads
 def testArtistRating(self):
   Factories.clear()
   track = TrackFactory.get(self.artist, self.titleA)
   track.ratingref.mix = 1.0
   artist = track.artist
   artist.ratingref.mix = 1.0
   artist.ratingfactor = 1.0
   track.played()
   self.assertNotEqual(track.rating, 0.5)
   self.assertNotEqual(artist.rating, 0.5)
   track.skipped()
   self.assertEqual(track.rating, 0.5)
   self.assertEqual(artist.rating, 0.5)
コード例 #13
0
ファイル: test_track.py プロジェクト: pscn/ads
  def testTrackPickle(self):
    Factories.clear()
    track = TrackFactory.get(self.artist, self.title)
    track.test = self.track_test
    track.artist.test = self.artist_test

    state = pickle.dumps(Factories.getstate())
    Factories.clear()
    pickle.loads(state)

    self.assertEqual(track.title, self.title)
    self.assertEqual(track.test, self.track_test)
    self.assertEqual(track.artist.name, self.artist)
    self.assertEqual(track.artist.test, self.artist_test)
コード例 #14
0
ファイル: library.py プロジェクト: pscn/ads
 def dump_stats(self):
   self._logger.info(u"%d artists, %d tracks %d files" % (
       ArtistFactory.len(), TrackFactory.len(), FileFactory.len()))
コード例 #15
0
ファイル: library.py プロジェクト: pscn/ads
  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()
コード例 #16
0
ファイル: library.py プロジェクト: pscn/ads
 def reset_boost(self, locked=False):
   if not locked: self.acquire()
   for track in TrackFactory.active_tracks():
     track.boost = False
   if not locked: self.release()
コード例 #17
0
ファイル: library.py プロジェクト: pscn/ads
  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)
コード例 #18
0
ファイル: file.py プロジェクト: pscn/ads
 def __setstate__(self, dict):
   track = TrackFactory.by_key(dict['track_key'])
   del dict['track_key']
   self.__dict__ = dict
   self.track = track
   FileFactory.register(self)
コード例 #19
0
ファイル: file.py プロジェクト: pscn/ads
 def __init__(self, path, artist_name, track_title):
   self.path = path
   self.track = TrackFactory.get(artist_name, track_title)