* morituri/image/table.py:
Add CDText writing to .cue() method. * morituri/image/toc.py: Add CDText parsing. * morituri/test/test_image_toc.py: * morituri/test/breeders.cue (added): Add a test for cue'ing the breeders' toc.
This commit is contained in:
10
ChangeLog
10
ChangeLog
@@ -1,3 +1,13 @@
|
||||
2009-05-14 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/table.py:
|
||||
Add CDText writing to .cue() method.
|
||||
* morituri/image/toc.py:
|
||||
Add CDText parsing.
|
||||
* morituri/test/test_image_toc.py:
|
||||
* morituri/test/breeders.cue (added):
|
||||
Add a test for cue'ing the breeders' toc.
|
||||
|
||||
2009-05-14 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/table.py:
|
||||
|
||||
@@ -31,6 +31,8 @@ import gst
|
||||
|
||||
from morituri.common import task, checksum, common, log
|
||||
|
||||
# FIXME: taken from libcdio, but no reference found for these
|
||||
|
||||
CDTEXT_FIELDS = [
|
||||
'ARRANGER',
|
||||
'COMPOSER',
|
||||
@@ -123,12 +125,14 @@ class IndexTable(object, log.Loggable):
|
||||
tracks = None # list of ITTrack
|
||||
leadout = None # offset where the leadout starts
|
||||
catalog = None # catalog number; FIXME: is this UPC ?
|
||||
cdtext = None
|
||||
|
||||
def __init__(self, tracks=None):
|
||||
if not tracks:
|
||||
tracks = []
|
||||
|
||||
self.tracks = tracks
|
||||
self.cdtext = {}
|
||||
|
||||
def getTrackStart(self, number):
|
||||
"""
|
||||
@@ -324,10 +328,21 @@ class IndexTable(object, log.Loggable):
|
||||
lines = []
|
||||
|
||||
# header
|
||||
main = ['PERFORMER', 'TITLE']
|
||||
|
||||
for key in CDTEXT_FIELDS:
|
||||
if key not in main and self.cdtext.has_key(key):
|
||||
lines.append(" %s %s" % (key, track.cdtext[key]))
|
||||
|
||||
lines.append('REM COMMENT "Morituri"')
|
||||
|
||||
if self.catalog:
|
||||
lines.append("CATALOG %s" % self.catalog)
|
||||
|
||||
for key in main:
|
||||
if self.cdtext.has_key(key):
|
||||
lines.append('%s "%s"' % (key, self.cdtext[key]))
|
||||
|
||||
# add the first FILE line
|
||||
path = self.tracks[0].getFirstIndex().path
|
||||
currentPath = path
|
||||
@@ -335,6 +350,10 @@ class IndexTable(object, log.Loggable):
|
||||
|
||||
for i, track in enumerate(self.tracks):
|
||||
lines.append(" TRACK %02d %s" % (i + 1, 'AUDIO'))
|
||||
for key in CDTEXT_FIELDS:
|
||||
if track.cdtext.has_key(key):
|
||||
lines.append(' %s "%s"' % (key, track.cdtext[key]))
|
||||
|
||||
if track.isrc is not None:
|
||||
lines.append(" ISRC %s" % track.isrc)
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ from morituri.common import common, log
|
||||
from morituri.image import table
|
||||
|
||||
# shared
|
||||
_CDTEXT_CANDIDATE_RE = re.compile(r'(?P<key>s+) "(?P<value>.+")')
|
||||
_CDTEXT_CANDIDATE_RE = re.compile(r'(?P<key>\w+) "(?P<value>.+)"')
|
||||
|
||||
# header
|
||||
_CATALOG_RE = re.compile(r'^CATALOG "(?P<catalog>\d+)"$')
|
||||
@@ -101,7 +101,15 @@ class TocFile(object, log.Loggable):
|
||||
if m:
|
||||
key = m.group('key')
|
||||
value = m.group('value')
|
||||
# print key, value
|
||||
if key in table.CDTEXT_FIELDS:
|
||||
# FIXME: consider ISRC separate for now, but this
|
||||
# is a limitation of our parser approach
|
||||
if state == 'HEADER':
|
||||
self.table.cdtext[key] = value
|
||||
elif state == 'TRACK':
|
||||
if key != 'ISRC' or not currentTrack \
|
||||
or currentTrack.isrc is not None:
|
||||
currentTrack.cdtext[key] = value
|
||||
|
||||
# look for header elements
|
||||
m = _CATALOG_RE.search(line)
|
||||
|
||||
63
morituri/test/breeders.cue
Normal file
63
morituri/test/breeders.cue
Normal file
@@ -0,0 +1,63 @@
|
||||
REM COMMENT "Morituri"
|
||||
CATALOG 0652637280326
|
||||
PERFORMER "THE BREEDERS"
|
||||
TITLE "MOUNTAIN BATTLES"
|
||||
FILE "data.wav" WAVE
|
||||
TRACK 01 AUDIO
|
||||
TITLE "OVERGLAZED"
|
||||
ISRC GBAFL0700213
|
||||
INDEX 01 00:00:00
|
||||
TRACK 02 AUDIO
|
||||
TITLE "BANG ON"
|
||||
ISRC GBAFL0700214
|
||||
INDEX 00 02:14:51
|
||||
INDEX 01 02:15:26
|
||||
TRACK 03 AUDIO
|
||||
TITLE "NIGHT OF JOY"
|
||||
ISRC GBAFL0700215
|
||||
INDEX 00 04:17:74
|
||||
INDEX 01 04:18:34
|
||||
TRACK 04 AUDIO
|
||||
TITLE "WE'RE GONNA RISE"
|
||||
ISRC GBAFL0700216
|
||||
INDEX 01 07:44:22
|
||||
TRACK 05 AUDIO
|
||||
TITLE "GERMAN STUDIES"
|
||||
ISRC GBAFL0700217
|
||||
INDEX 01 11:37:39
|
||||
TRACK 06 AUDIO
|
||||
TITLE "SPARK"
|
||||
ISRC GBAFL0700218
|
||||
INDEX 00 13:51:54
|
||||
INDEX 01 13:53:38
|
||||
TRACK 07 AUDIO
|
||||
TITLE "INSTANBUL"
|
||||
ISRC GBAFL0700219
|
||||
INDEX 00 16:31:20
|
||||
INDEX 01 16:32:49
|
||||
TRACK 08 AUDIO
|
||||
TITLE "WALK IT OFF"
|
||||
ISRC GBAFL0700220
|
||||
INDEX 01 19:30:19
|
||||
TRACK 09 AUDIO
|
||||
TITLE "REGLAME ESTA NOCHE"
|
||||
ISRC GBAFL0700221
|
||||
INDEX 00 22:14:69
|
||||
INDEX 01 22:16:27
|
||||
TRACK 10 AUDIO
|
||||
TITLE "HERE NO MORE"
|
||||
ISRC GBAFL0700222
|
||||
INDEX 00 25:06:18
|
||||
INDEX 01 25:08:01
|
||||
TRACK 11 AUDIO
|
||||
TITLE "NO WAY"
|
||||
ISRC GBAFL0700223
|
||||
INDEX 01 27:46:64
|
||||
TRACK 12 AUDIO
|
||||
TITLE "IT'S THE LOVE"
|
||||
ISRC GBAFL0700224
|
||||
INDEX 01 30:19:39
|
||||
TRACK 13 AUDIO
|
||||
TITLE "MOUNTAIN BATTLES"
|
||||
ISRC GBAFL0700225
|
||||
INDEX 01 32:47:56
|
||||
@@ -105,3 +105,27 @@ class BlocTestCase(unittest.TestCase):
|
||||
t = self.toc.table.tracks[0]
|
||||
self.assertEquals(t.getIndex(0).relative, 0)
|
||||
self.assertEquals(t.getIndex(1).relative, 15220)
|
||||
|
||||
# The Breeders - Mountain Battles has CDText
|
||||
class BreedersTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.toc = toc.TocFile(os.path.join(os.path.dirname(__file__),
|
||||
'breeders.toc'))
|
||||
self.toc.parse()
|
||||
self.assertEquals(len(self.toc.table.tracks), 13)
|
||||
|
||||
def testCDText(self):
|
||||
cdt = self.toc.table.cdtext
|
||||
self.assertEquals(cdt['PERFORMER'], 'THE BREEDERS')
|
||||
self.assertEquals(cdt['TITLE'], 'MOUNTAIN BATTLES')
|
||||
|
||||
t = self.toc.table.tracks[0]
|
||||
cdt = t.cdtext
|
||||
self.assertRaises(AttributeError, getattr, cdt, 'PERFORMER')
|
||||
self.assertEquals(cdt['TITLE'], 'OVERGLAZED')
|
||||
|
||||
def testConvertCue(self):
|
||||
cue = self.toc.table.cue()
|
||||
ref = open(os.path.join(os.path.dirname(__file__),
|
||||
'breeders.cue')).read()
|
||||
self.assertEquals(cue, ref)
|
||||
|
||||
Reference in New Issue
Block a user