diff --git a/ChangeLog b/ChangeLog index a9037db..e71f198 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2009-04-12 Thomas Vander Stichele + + * examples/ARcue.py: + * morituri/image/image.py: + * morituri/test/test_image_image.py: + Add a task to verify a disk image, which also calculates + track lengths for tracks the cue file doesn't know the length of. + 2009-04-12 Thomas Vander Stichele * examples/ARcue.py: diff --git a/examples/ARcue.py b/examples/ARcue.py index c87dcdc..c4710c8 100644 --- a/examples/ARcue.py +++ b/examples/ARcue.py @@ -67,11 +67,14 @@ def main(argv): pass cueImage = image.Image(path) + verifytask = image.ImageVerifyTask(cueImage) cuetask = image.AudioRipCRCTask(cueImage) if options.runner == 'cli': + climain(verifytask) climain(cuetask) elif options.runner == 'gtk': + gtkmain(verifytask) gtkmain(cuetask) for i, crc in enumerate(cuetask.crcs): diff --git a/morituri/image/image.py b/morituri/image/image.py index fe65362..1e86154 100644 --- a/morituri/image/image.py +++ b/morituri/image/image.py @@ -39,6 +39,7 @@ class Image: self._path = path self.cue = cue.Cue(path) self.cue.parse() + self._lengths = [] def getRealPath(self, path): """ @@ -65,6 +66,17 @@ class Image: """ Do initial setup, like figuring out track lengths. """ + verify = ImageVerifyTask(self) + runner.run(verify) + self._lengths = verify.lengths + + def getTrackLength(self, track): + length = self.cue.getTrackLength(track) + if length != -1: + return length + + i = self.cue.tracks.index(track) + return self._lengths[i + 1] class MultiTask(task.Task): """ @@ -85,7 +97,7 @@ class MultiTask(task.Task): # initialize task tracking self._task = 0 - self._tasks = self.tasks[:] + self.__tasks = self.tasks[:] self._generic = self.description self._next() @@ -93,8 +105,8 @@ class MultiTask(task.Task): def _next(self): # start next task self.progress = 0.0 # reset progress for each task - task = self._tasks[0] - del self._tasks[0] + task = self.__tasks[0] + del self.__tasks[0] self._task += 1 self.description = "%s (%d of %d) ..." % ( self._generic, self._task, len(self.tasks)) @@ -109,7 +121,7 @@ class MultiTask(task.Task): self.setProgress(value) def stopped(self, task): - if not self._tasks: + if not self.__tasks: self.stop() return @@ -129,7 +141,6 @@ class AudioRipCRCTask(MultiTask): cue = image.cue self.crcs = [] - tasks = [] for trackIndex, track in enumerate(cue.tracks): index = track._indexes[1] length = cue.getTrackLength(track) @@ -188,3 +199,40 @@ class AudioLengthTask(task.Task): self._pipeline.set_state(gst.STATE_NULL) self.stop() + +class ImageVerifyTask(MultiTask): + """ + I verify a disk image and get the necessary track lengths. + """ + + description = "Checking tracks" + lengths = None + + def __init__(self, image): + self._image = image + cue = image.cue + self._tasks = [] + self.lengths = {} + + for trackIndex, track in enumerate(cue.tracks): + index = track._indexes[1] + offset = index[0] + length = cue.getTrackLength(track) + file = index[1] + + if length == -1: + path = image.getRealPath(file.path) + taskk = AudioLengthTask(path) + self.addTask(taskk) + self._tasks.append((trackIndex + 1, track, taskk)) + + def stop(self): + for trackIndex, track, taskk in self._tasks: + # print '%d has length %d' % (trackIndex, taskk.length) + index = track._indexes[1] + offset = index[0] + assert taskk.length % crc.FRAMES_PER_DISC_FRAME == 0 + end = taskk.length / crc.FRAMES_PER_DISC_FRAME + self.lengths[trackIndex] = end - offset + + MultiTask.stop(self) diff --git a/morituri/test/test_image_image.py b/morituri/test/test_image_image.py index 37ba006..5c70246 100644 --- a/morituri/test/test_image_image.py +++ b/morituri/test/test_image_image.py @@ -17,11 +17,12 @@ class TrackSingleTestCase(unittest.TestCase): def setUp(self): self.image = image.Image(os.path.join(os.path.dirname(__file__), 'track-single.cue')) + self.runner = task.SyncRunner() + self.image.setup(self.runner) def testAudioRipCRC(self): crctask = image.AudioRipCRCTask(self.image) - runner = task.SyncRunner() - runner.run(crctask, verbose=False) + self.runner.run(crctask, verbose=False) self.assertEquals(len(crctask.crcs), 4) self.assertEquals(h(crctask.crcs[0]), '0x00000000') @@ -29,15 +30,23 @@ class TrackSingleTestCase(unittest.TestCase): self.assertEquals(h(crctask.crcs[2]), '0x8dd37c26') self.assertEquals(h(crctask.crcs[3]), '0x00000000') -class KingsSeparateTestCase(unittest.TestCase): + def testLength(self): + tracks = self.image.cue.tracks + self.assertEquals(self.image.getTrackLength(tracks[0]), 2) + self.assertEquals(self.image.getTrackLength(tracks[1]), 2) + self.assertEquals(self.image.getTrackLength(tracks[2]), 2) + self.assertEquals(self.image.getTrackLength(tracks[3]), 4) + +class TracSeparateTestCase(unittest.TestCase): def setUp(self): self.image = image.Image(os.path.join(os.path.dirname(__file__), 'track-separate.cue')) + self.runner = task.SyncRunner() + self.image.setup(self.runner) def testAudioRipCRC(self): crctask = image.AudioRipCRCTask(self.image) - runner = task.SyncRunner() - runner.run(crctask, verbose=False) + self.runner.run(crctask, verbose=False) self.assertEquals(len(crctask.crcs), 4) self.assertEquals(h(crctask.crcs[0]), '0xaf18681e') @@ -45,6 +54,13 @@ class KingsSeparateTestCase(unittest.TestCase): self.assertEquals(h(crctask.crcs[2]), '0xd63dc2d2') self.assertEquals(h(crctask.crcs[3]), '0x7271db39') + def testLength(self): + tracks = self.image.cue.tracks + self.assertEquals(self.image.getTrackLength(tracks[0]), 10) + self.assertEquals(self.image.getTrackLength(tracks[1]), 10) + self.assertEquals(self.image.getTrackLength(tracks[2]), 10) + self.assertEquals(self.image.getTrackLength(tracks[3]), 10) + class AudioLengthTestCase(unittest.TestCase): def testLength(self): path = os.path.join(os.path.dirname(__file__), 'track.flac')