* morituri/image/table.py:
* morituri/test/test_image_table.py: Implement MusicBrainz disc id. Works for audio-only discs, have to figure out why it fails for an Enhanced CD like the Ladyhawke one.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2009-05-05 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/table.py:
|
||||
* morituri/test/test_image_table.py:
|
||||
Implement MusicBrainz disc id. Works for audio-only discs,
|
||||
have to figure out why it fails for an Enhanced CD like the
|
||||
Ladyhawke one.
|
||||
|
||||
2009-05-05 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/table.py:
|
||||
|
||||
@@ -349,6 +349,55 @@ class IndexTable(object, log.Loggable):
|
||||
|
||||
return "%08x" % value
|
||||
|
||||
def getMusicBrainzDiscId(self):
|
||||
"""
|
||||
Calculate the MusicBrainz disc ID.
|
||||
|
||||
@rtype: str
|
||||
@returns: the 28-character base64-encoded disc ID
|
||||
"""
|
||||
# MusicBrainz disc id does not take into account data tracks
|
||||
import sha
|
||||
import base64
|
||||
|
||||
sha1 = sha.new()
|
||||
|
||||
# number of first track
|
||||
sha1.update("%02X" % 1)
|
||||
|
||||
# number of last track
|
||||
sha1.update("%02X" % self.getAudioTracks())
|
||||
|
||||
# treat leadout offset as track 0 offset
|
||||
sha1.update("%08X" % (150 + self.leadout))
|
||||
|
||||
# offsets of tracks
|
||||
for i in range(1, 100):
|
||||
try:
|
||||
offset = self.tracks[i - 1].getIndex(1).absolute + 150
|
||||
except IndexError:
|
||||
#print 'track', i - 1, '0 offset'
|
||||
offset = 0
|
||||
sha1.update("%08X" % offset)
|
||||
|
||||
digest = sha1.digest()
|
||||
assert len(digest) == 20, \
|
||||
"digest should be 20 chars, not %d" % len(digest)
|
||||
|
||||
# The RFC822 spec uses +, /, and = characters, all of which are special
|
||||
# HTTP/URL characters. To avoid the problems with dealing with that, I
|
||||
# (Rob) used ., _, and -
|
||||
|
||||
# base64 altchars specify replacements for + and /
|
||||
result = base64.b64encode(digest, '._')
|
||||
|
||||
# now replace =
|
||||
result = "-".join(result.split("="))
|
||||
assert len(result) == 28, \
|
||||
"Result should be 28 characters, not %d" % len(result)
|
||||
|
||||
return result
|
||||
|
||||
def getAccurateRipIds(self):
|
||||
"""
|
||||
Calculate the two AccurateRip ID's.
|
||||
|
||||
@@ -39,6 +39,37 @@ class LadyhawkeTestCase(unittest.TestCase):
|
||||
def testCDDB(self):
|
||||
self.assertEquals(self.table.getCDDBDiscId(), "c60af50d")
|
||||
|
||||
def testMusicBrainz(self):
|
||||
# FIXME: doesn't seem to be the correct id, so try the example on this
|
||||
# track
|
||||
#print self.table.getMusicBrainzDiscId()
|
||||
pass
|
||||
|
||||
def testAccurateRip(self):
|
||||
self.assertEquals(self.table.getAccurateRipIds(), (
|
||||
"0013bd5a", "00b8d489"))
|
||||
|
||||
class MusicBrainzTestCase(unittest.TestCase):
|
||||
# example taken from http://musicbrainz.org/doc/DiscIDCalculation
|
||||
# disc is Ettella Diamant
|
||||
|
||||
def setUp(self):
|
||||
self.table = table.IndexTable()
|
||||
|
||||
for i in range(6):
|
||||
self.table.tracks.append(table.ITTrack(i + 1, audio=True))
|
||||
|
||||
offsets = [0, 15213, 32164, 46442, 63264, 80339]
|
||||
t = self.table.tracks
|
||||
for i, offset in enumerate(offsets):
|
||||
t[i].index(1, absolute=offset)
|
||||
|
||||
self.failIf(self.table.hasTOC())
|
||||
|
||||
self.table.leadout = 95312
|
||||
|
||||
self.failUnless(self.table.hasTOC())
|
||||
|
||||
def testMusicBrainz(self):
|
||||
self.assertEquals(self.table.getMusicBrainzDiscId(),
|
||||
'49HHV7Eb8UKF3aQiNmu1GR8vKTY-')
|
||||
|
||||
Reference in New Issue
Block a user