From 54c7322a0426fa4e3c66b5b3455c1e0eec96fd44 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Fri, 1 May 2009 18:52:51 +0000 Subject: [PATCH] * examples/readtrack.py: * morituri/program/cdparanoia.py: Move ReadTrackTask to cdparanoia module. --- ChangeLog | 6 ++ examples/readtrack.py | 136 +++++++-------------------------- morituri/program/cdparanoia.py | 106 +++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 109 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2b5299b..3ddf613 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-05-01 Thomas Vander Stichele + + * examples/readtrack.py: + * morituri/program/cdparanoia.py: + Move ReadTrackTask to cdparanoia module. + 2009-05-01 Thomas Vander Stichele * examples/readtrack.py (added): diff --git a/examples/readtrack.py b/examples/readtrack.py index 26f1e28..0301496 100644 --- a/examples/readtrack.py +++ b/examples/readtrack.py @@ -6,122 +6,40 @@ import os import subprocess import tempfile -from morituri.common import task, log, common +from morituri.common import task, checksum, log from morituri.program import cdparanoia -from morituri.extern import asyncsub -# FIXME: handle errors - -class ReadTrackTask(task.Task): - """ - I am a task that reads a track using cdparanoia. - """ - - description = "Reading Track..." - - - def __init__(self, path, start, stop, offset=0): - """ - Read the given track. - - @param path: where to store the ripped track - @type path: str - @param start: first frame to rip - @type start: int - @param stop: last frame to rip (inclusive) - @type stop: int - @param offset: read offset, in samples - @type offset: int - """ - self.path = path - self._start = start - self._stop = stop - self._offset = offset - self._parser = cdparanoia.ProgressParser() - - self._buffer = "" # accumulate characters - - def start(self, runner): - task.Task.start(self, runner) - - bufsize = 1024 - argv = ["cdparanoia", - "--sample-offset=%d" % self._offset, - "--stderr-progress", - "[%s]-[%s]" % ( - common.framesToHMSF(self._start), - common.framesToHMSF(self._stop)), self.path] - self.debug('Running %s' % (" ".join(argv), )) - self._popen = asyncsub.Popen(argv, - bufsize=bufsize, - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True) - - self.runner.schedule(1.0, self._read, runner) - - def _read(self, runner): - ret = self._popen.recv_err() - if not ret: - if self._popen.poll() is not None: - self._done() - return - self.runner.schedule(0.01, self._read, runner) - return - - self._buffer += ret - - # parse buffer into lines if possible, and parse them - if "\n" in self._buffer: - lines = self._buffer.split('\n') - if lines[-1] != "\n": - # last line didn't end yet - self._buffer = lines[-1] - del lines[-1] - else: - self._buffer = "" - - for line in lines: - self._parser.parse(line) - # FIXME: self._parser.read *will* go past self._stop, - # and only indicates read frames, not written frames. - # but we can't rely on anything else. - num = float(self._parser.read) - self._start - den = float(self._stop) - self._start - progress = num / den - if progress < 1.0: - self.setProgress(progress) - - # 0 does not give us output before we complete, 1.0 gives us output - # too late - self.runner.schedule(0.01, self._read, runner) - - def _poll(self, runner): - if self._popen.poll() is None: - self.runner.schedule(1.0, self._poll, runner) - return - - self._done() - - def _done(self): - self.setProgress(1.0) - if self._popen.returncode != 0: - if self._errors: - print "\n".join(self._errors) - else: - print 'ERROR: exit code %r' % self._popen.returncode - else: - print - print 'done' - - self.stop() - return +import gobject +gobject.threads_init() def main(): log.init() runner = task.SyncRunner() - t = ReadTrackTask('/tmp/track.wav', 1000, 3000, offset=0) - runner.run(t) + + checksums = [] + for i in range(2): + fd, path = tempfile.mkstemp(suffix='.morituri') + os.close(fd) + + t = cdparanoia.ReadTrackTask(path, 1000, 3000, offset=0) + if i == 1: + t.description = 'Verifying track...' + + runner.run(t) + + t = checksum.CRC32Task(path) + runner.run(t) + + if i == 0: + os.unlink(path) + + checksums.append(t.checksum) + print 'runner done' + if checksums[0] == checksums[1]: + print 'Checksums match' + else: + print 'Checksums do not match' main() diff --git a/morituri/program/cdparanoia.py b/morituri/program/cdparanoia.py index 268f2dd..aaf7aab 100644 --- a/morituri/program/cdparanoia.py +++ b/morituri/program/cdparanoia.py @@ -21,6 +21,10 @@ # along with morituri. If not, see . import re +import subprocess + +from morituri.common import task, log, common +from morituri.extern import asyncsub _PROGRESS_RE = re.compile(r""" ^\#\#: (?P.+)\s # function code @@ -48,3 +52,105 @@ class ProgressParser(object): print line else: self.read = offset / 1176 + +# FIXME: handle errors +class ReadTrackTask(task.Task): + """ + I am a task that reads a track using cdparanoia. + """ + + description = "Reading Track..." + + + def __init__(self, path, start, stop, offset=0): + """ + Read the given track. + + @param path: where to store the ripped track + @type path: str + @param start: first frame to rip + @type start: int + @param stop: last frame to rip (inclusive) + @type stop: int + @param offset: read offset, in samples + @type offset: int + """ + self.path = path + self._start = start + self._stop = stop + self._offset = offset + self._parser = ProgressParser() + + self._buffer = "" # accumulate characters + + def start(self, runner): + task.Task.start(self, runner) + + bufsize = 1024 + argv = ["cdparanoia", + "--sample-offset=%d" % self._offset, + "--stderr-progress", + "[%s]-[%s]" % ( + common.framesToHMSF(self._start), + common.framesToHMSF(self._stop)), self.path] + self.debug('Running %s' % (" ".join(argv), )) + self._popen = asyncsub.Popen(argv, + bufsize=bufsize, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, close_fds=True) + + self.runner.schedule(1.0, self._read, runner) + + def _read(self, runner): + ret = self._popen.recv_err() + if not ret: + if self._popen.poll() is not None: + self._done() + return + self.runner.schedule(0.01, self._read, runner) + return + + self._buffer += ret + + # parse buffer into lines if possible, and parse them + if "\n" in self._buffer: + lines = self._buffer.split('\n') + if lines[-1] != "\n": + # last line didn't end yet + self._buffer = lines[-1] + del lines[-1] + else: + self._buffer = "" + + for line in lines: + self._parser.parse(line) + # FIXME: self._parser.read *will* go past self._stop, + # and only indicates read frames, not written frames. + # but we can't rely on anything else. + num = float(self._parser.read) - self._start + den = float(self._stop) - self._start + progress = num / den + if progress < 1.0: + self.setProgress(progress) + + # 0 does not give us output before we complete, 1.0 gives us output + # too late + self.runner.schedule(0.01, self._read, runner) + + def _poll(self, runner): + if self._popen.poll() is None: + self.runner.schedule(1.0, self._poll, runner) + return + + self._done() + + def _done(self): + self.setProgress(1.0) + if self._popen.returncode != 0: + if self._errors: + print "\n".join(self._errors) + else: + print 'ERROR: exit code %r' % self._popen.returncode + + self.stop() + return