diff --git a/server/djrandom/model/mp3.py b/server/djrandom/model/mp3.py index 755af8a6c4a2b32057afdf0df3759deb14635203..ecaeabbdf0ea795c489318ccdf5d27bd7876f72f 100644 --- a/server/djrandom/model/mp3.py +++ b/server/djrandom/model/mp3.py @@ -80,6 +80,20 @@ class MP3(Base): except: pass + @classmethod + def deduplicate(cls, hashes): + result = [] + for sha1 in hashes: + if sha1: + mp3 = cls.query.get(sha1) + while mp3 and mp3.state == cls.DUPLICATE: + mp3 = cls.query.get(mp3.duplicate_of) + if mp3: + result.append(mp3.sha1) + continue + result.append(None) + return result + def get_fingerprint(self): if self.has_fingerprint: return self.echoprint_fp.echoprint_fp @@ -180,7 +194,8 @@ class PlayLog(Base): hashes = ([None] * (n - len(hashes))) + hashes else: hashes = [None] * n - yield (plog.sha1, hashes) + target = MP3.deduplicate([plog.sha1])[0] + yield (target, MP3.deduplicate(hashes)) @classmethod def top_songs_for_user(cls, userid, days=30, n=10): diff --git a/server/djrandom/test/test_model.py b/server/djrandom/test/test_model.py index 67ea9edbeafb149792bd6ee283bb1451ce3a927a..428c9df502019b1118ef98282279bb13f71a25bc 100644 --- a/server/djrandom/test/test_model.py +++ b/server/djrandom/test/test_model.py @@ -7,18 +7,19 @@ from djrandom.model.mp3 import MP3, PlayLog, SearchLog, DUPLICATE_DIR from djrandom.model.playlist import Playlist -class MP3Test(DbTestCase): +def create_mp3(sha1='1234', **kw): + mp3_data = {'title': u'title', 'artist': u'artist', 'album': u'album', + 'genre': u'genre', 'sha1': sha1, 'size': 2601, + 'uploaded_at': datetime(2011, 10, 10, 9, 18, 0)} + mp3_data.update(kw) + return MP3(path='/storage/' + sha1, **mp3_data), mp3_data + - def _create_mp3(self, sha1='1234', **kw): - mp3_data = {'title': u'title', 'artist': u'artist', 'album': u'album', - 'genre': u'genre', 'sha1': sha1, 'size': 2601, - 'uploaded_at': datetime(2011, 10, 10, 9, 18, 0)} - mp3_data.update(kw) - return MP3(path='/storage/' + sha1, **mp3_data), mp3_data +class MP3Test(DbTestCase): def test_mp3_std(self): # Simple tests building and serializing an MP3 object. - mp3, mp3_data = self._create_mp3() + mp3, mp3_data = create_mp3() Session.add(mp3) Session.commit() @@ -43,7 +44,7 @@ class MP3Test(DbTestCase): os.path.join(DUPLICATE_DIR, '1234')) self.mox.ReplayAll() - mp3, _ = self._create_mp3() + mp3, _ = create_mp3() mp3.mark_as_duplicate('2345') self.assertEquals('2345', mp3.duplicate_of) @@ -51,7 +52,7 @@ class MP3Test(DbTestCase): def test_mp3_fingerprint(self): fp = 'a fingerprint' - mp3, _ = self._create_mp3() + mp3, _ = create_mp3() mp3.set_fingerprint(fp) Session.add(mp3) Session.commit() @@ -61,9 +62,9 @@ class MP3Test(DbTestCase): self.assertEquals(fp, mp3b.get_fingerprint()) def test_mp3_get_with_no_fingerprint(self): - mp3_1, _ = self._create_mp3('1001') - mp3_2, _ = self._create_mp3('1002') - mp3_3, _ = self._create_mp3('1003') + mp3_1, _ = create_mp3('1001') + mp3_2, _ = create_mp3('1002') + mp3_3, _ = create_mp3('1003') mp3_1.state = MP3.READY mp3_2.state = MP3.BAD_METADATA for x in (mp3_1, mp3_2, mp3_3): @@ -81,8 +82,8 @@ class MP3Test(DbTestCase): pass def test_mp3_get_songs_for_album(self): - mp3_1, _ = self._create_mp3('1001', album=u'other album', state=MP3.READY) - mp3_2, _ = self._create_mp3('1002', state=MP3.READY) + mp3_1, _ = create_mp3('1001', album=u'other album', state=MP3.READY) + mp3_2, _ = create_mp3('1002', state=MP3.READY) Session.add(mp3_1) Session.add(mp3_2) Session.commit() @@ -91,9 +92,9 @@ class MP3Test(DbTestCase): self.assertEquals(['1002'], [x.sha1 for x in results]) #def test_mp3_get_random_songs(self): - # mp3_1, _ = self._create_mp3('1001', state=MP3.READY) - # mp3_2, _ = self._create_mp3('1002', state=MP3.READY) - # mp3_3, _ = self._create_mp3('1003', state=MP3.READY) + # mp3_1, _ = create_mp3('1001', state=MP3.READY) + # mp3_2, _ = create_mp3('1002', state=MP3.READY) + # mp3_3, _ = create_mp3('1003', state=MP3.READY) # for x in (mp3_1, mp3_2, mp3_3): # Session.add(x) # Session.commit() @@ -125,6 +126,11 @@ class PlayLogTest(DbTestCase): self.assertEquals(2, result[0][1]) def test_playlog_generate_tuples(self): + for i in range(1, 5): + mp3, _ = create_mp3(unicode(i)) + Session.add(mp3) + Session.commit() + result = list(PlayLog.generate_tuples(n=2)) result.sort() expected = [(u'1', [None]), @@ -134,6 +140,24 @@ class PlayLogTest(DbTestCase): (u'4', [u'3'])] self.assertEquals(expected, result) + def test_playlog_generate_tuples_with_duplicates(self): + for i in range(1, 4): + mp3, _ = create_mp3(unicode(i)) + Session.add(mp3) + mp3, _ = create_mp3(u'4', state=MP3.DUPLICATE, + duplicate_of=u'2') + Session.add(mp3) + Session.commit() + + result = list(PlayLog.generate_tuples(n=2)) + result.sort() + expected = [(u'1', [None]), + (u'1', [u'2']), + (u'2', [u'1']), + (u'2', [u'3']), + (u'3', [u'2'])] + self.assertEquals(expected, result) + class PlayListTest(DbTestCase):