From 82db5d3b1d90449b7a0d90fd534cbc75985fdc5f Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Thu, 14 May 2009 08:21:28 +0000 Subject: [PATCH] * morituri/image/table.py: * morituri/image/toc.py: Add parsing of ISRC codes. Add first part of CDTEXT stuff. * morituri/test/test_image_toc.py: Add test for converting .toc to .cue * morituri/test/cure.cue Add reference for converted cure.toc --- ChangeLog | 11 +++++++ morituri/image/table.py | 40 +++++++++++++++++++++--- morituri/image/toc.py | 23 +++++++++++++- morituri/test/cure.cue | 54 +++++++++++++++++++++++++++++++++ morituri/test/test_image_toc.py | 5 +++ 5 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 morituri/test/cure.cue diff --git a/ChangeLog b/ChangeLog index c134a21..4260b29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-05-14 Thomas Vander Stichele + + * morituri/image/table.py: + * morituri/image/toc.py: + Add parsing of ISRC codes. + Add first part of CDTEXT stuff. + * morituri/test/test_image_toc.py: + Add test for converting .toc to .cue + * morituri/test/cure.cue + Add reference for converted cure.toc + 2009-05-10 Thomas Vander Stichele * examples/readhtoa.py: diff --git a/morituri/image/table.py b/morituri/image/table.py index d8b019a..8a33165 100644 --- a/morituri/image/table.py +++ b/morituri/image/table.py @@ -31,20 +31,41 @@ import gst from morituri.common import task, checksum, common, log +CDTEXT_FIELDS = [ + 'ARRANGER', + 'COMPOSER', + 'DISCID', + 'GENRE', + 'MESSAGE', + 'ISRC', + 'PERFORMER', + 'SIZE_INFO', + 'SONGWRITER', + 'TITLE', + 'TOC_INFO', + 'TOC_INFO2', + 'UPC_EAN', +] + + class ITTrack: """ I represent a track entry in an IndexTable. - @ivar number: track number (1-based) - @type number: int - @ivar audio: whether the track is audio - @type audio: bool + @ivar number: track number (1-based) + @type number: int + @ivar audio: whether the track is audio + @type audio: bool @type indexes: dict of number -> L{Index} + @ivar isrc: ISRC code (12 alphanumeric characters) + @type isrc: str """ number = None audio = None indexes = None + isrc = None + cdtext = None def __repr__(self): return '' % self.number @@ -53,6 +74,7 @@ class ITTrack: self.number = number self.audio = audio self.indexes = {} + self.cdtext = {} def index(self, number, absolute=None, path=None, relative=None, counter=None): i = Index(number, absolute, path, relative, counter) @@ -94,10 +116,13 @@ class IndexTable(object, log.Loggable): @ivar tracks: tracks on this CD @type tracks: list of L{ITTrack} + @ivar catalog: catalog number + @type catalog: str """ tracks = None # list of ITTrack leadout = None # offset where the leadout starts + catalog = None # catalog number; FIXME: is this UPC ? def __init__(self, tracks=None): if not tracks: @@ -298,6 +323,11 @@ class IndexTable(object, log.Loggable): """ lines = [] + # header + lines.append('REM COMMENT "Morituri"') + if self.catalog: + lines.append("CATALOG %s" % self.catalog) + # add the first FILE line path = self.tracks[0].getFirstIndex().path currentPath = path @@ -305,6 +335,8 @@ class IndexTable(object, log.Loggable): for i, track in enumerate(self.tracks): lines.append(" TRACK %02d %s" % (i + 1, 'AUDIO')) + if track.isrc is not None: + lines.append(" ISRC %s" % track.isrc) indexes = track.indexes.keys() indexes.sort() diff --git a/morituri/image/toc.py b/morituri/image/toc.py index 42e46cc..1571205 100644 --- a/morituri/image/toc.py +++ b/morituri/image/toc.py @@ -30,6 +30,9 @@ import re from morituri.common import common, log from morituri.image import table +# shared +_CDTEXT_CANDIDATE_RE = re.compile(r'(?Ps+) "(?P.+")') + # header _CATALOG_RE = re.compile(r'^CATALOG "(?P\d+)"$') @@ -39,6 +42,8 @@ _TRACK_RE = re.compile(r""" \s(?P.+)$ # mode (AUDIO, MODEx/2xxx, ...) """, re.VERBOSE) +_ISRC_RE = re.compile(r'^ISRC "(?P\w+)"$') + # a HTOA is marked in the cdrdao's TOC as SILENCE _SILENCE_RE = re.compile(r""" ^SILENCE # SILENCE @@ -91,9 +96,18 @@ class TocFile(object, log.Loggable): for number, line in enumerate(handle.readlines()): line = line.rstrip() + # look for CDTEXT stuff in either header or tracks + m = _CDTEXT_CANDIDATE_RE.search(line) + if m: + key = m.group('key') + value = m.group('value') + # print key, value + + # look for header elements m = _CATALOG_RE.search(line) if m: - catalog = m.group('catalog') + self.table.catalog = m.group('catalog') + self.debug("Found catalog number %s", self.table.catalog) # look for TRACK lines m = _TRACK_RE.search(line) @@ -120,6 +134,13 @@ class TocFile(object, log.Loggable): self.table.tracks.append(currentTrack) continue + # look for ISRC lines + m = _ISRC_RE.search(line) + if m: + isrc = m.group('isrc') + currentTrack.isrc = isrc + self.debug('Found ISRC code %s', isrc) + # look for SILENCE lines m = _SILENCE_RE.search(line) if m: diff --git a/morituri/test/cure.cue b/morituri/test/cure.cue new file mode 100644 index 0000000..52d211a --- /dev/null +++ b/morituri/test/cure.cue @@ -0,0 +1,54 @@ +REM COMMENT "Morituri" +CATALOG 0602517642256 +FILE "data.wav" WAVE + TRACK 01 AUDIO + ISRC USUM70839873 + INDEX 01 00:00:00 + TRACK 02 AUDIO + ISRC USUM70839874 + INDEX 00 06:16:45 + INDEX 01 06:17:49 + TRACK 03 AUDIO + ISRC USUM70839875 + INDEX 00 10:13:02 + INDEX 01 10:14:60 + TRACK 04 AUDIO + ISRC USUM70839876 + INDEX 00 14:50:07 + INDEX 01 14:50:17 + TRACK 05 AUDIO + ISRC USUM70839877 + INDEX 00 17:18:42 + INDEX 01 17:20:47 + TRACK 06 AUDIO + ISRC USUM70839878 + INDEX 00 19:43:06 + INDEX 01 19:43:10 + TRACK 07 AUDIO + ISRC USUM70839879 + INDEX 00 24:25:07 + INDEX 01 24:26:41 + TRACK 08 AUDIO + ISRC USUM70839880 + INDEX 00 28:56:00 + INDEX 01 28:56:09 + TRACK 09 AUDIO + ISRC USUM70839881 + INDEX 00 32:38:11 + INDEX 01 32:40:45 + TRACK 10 AUDIO + ISRC USUM70839882 + INDEX 00 36:01:58 + INDEX 01 36:02:04 + TRACK 11 AUDIO + ISRC USUM70839883 + INDEX 00 40:08:30 + INDEX 01 40:08:53 + TRACK 12 AUDIO + ISRC USUM70839884 + INDEX 00 43:59:51 + INDEX 01 44:00:27 + TRACK 13 AUDIO + ISRC USUM70839885 + INDEX 00 48:35:63 + INDEX 01 48:36:71 diff --git a/morituri/test/test_image_toc.py b/morituri/test/test_image_toc.py index 535c964..4697f2f 100644 --- a/morituri/test/test_image_toc.py +++ b/morituri/test/test_image_toc.py @@ -78,6 +78,11 @@ class CureTestCase(unittest.TestCase): self._assertPath(2, 1, None) self._assertRelative(2, 1, None) + def testConvertCue(self): + cue = self.toc.table.cue() + ref = open(os.path.join(os.path.dirname(__file__), 'cure.cue')).read() + self.assertEquals(cue, ref) + # Bloc Party - Silent Alarm has a Hidden Track One Audio class BlocTestCase(unittest.TestCase): def setUp(self):