[SCM] morituri/master: * morituri/program/cdrdao.py: * morituri/test/test_program_cdrdao.py (added): Split out the parser from the task. Test the parser.

js at users.alioth.debian.org js at users.alioth.debian.org
Sun Oct 19 20:08:55 UTC 2014


The following commit has been merged in the master branch:
commit aee0a2f1283b5b00829e10cf49dea8deaf931d30
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date:   Mon May 4 09:23:22 2009 +0000

    	* morituri/program/cdrdao.py:
    	* morituri/test/test_program_cdrdao.py (added):
    	  Split out the parser from the task.  Test the parser.

diff --git a/ChangeLog b/ChangeLog
index 4a249eb..9018e5f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2009-05-04  Thomas Vander Stichele  <thomas at apestaart dot org>
 
+	* morituri/program/cdrdao.py:
+	* morituri/test/test_program_cdrdao.py (added):
+	  Split out the parser from the task.  Test the parser.
+
+2009-05-04  Thomas Vander Stichele  <thomas at apestaart dot org>
+
 	* morituri/image/cue.py:
 	* morituri/image/image.py:
 	* morituri/image/table.py:
diff --git a/morituri/program/cdrdao.py b/morituri/program/cdrdao.py
index f827a14..93c0d4f 100644
--- a/morituri/program/cdrdao.py
+++ b/morituri/program/cdrdao.py
@@ -1,4 +1,4 @@
-# -*- Mode: Python -*-
+# -*- Mode: Python; test-case-name:morituri.test.test_program_cdrdao -*-
 # vi:si:et:sw=4:sts=4:ts=4
 
 # Morituri - for those about to RIP
@@ -33,6 +33,7 @@ from morituri.extern import asyncsub
 states = ['START', 'TRACK', 'LEADOUT', 'DONE']
 
 _ANALYZING_RE = re.compile(r'^Analyzing track (?P<track>\d+).*')
+
 _TRACK_RE = re.compile(r"""
     ^(?P<track>[\d\s]{2})\s+ # Track
     (?P<mode>\w+)\s+         # Mode; AUDIO
@@ -42,6 +43,7 @@ _TRACK_RE = re.compile(r"""
     \d\d:\d\d:\d\d           # Length in HH:MM:FF
     \((?P<length>.+)\)       # Length in frames
 """, re.VERBOSE)
+
 _LEADOUT_RE = re.compile(r"""
     ^Leadout\s
     \w+\s+               # Mode
@@ -50,57 +52,26 @@ _LEADOUT_RE = re.compile(r"""
     \((?P<start>.+)\)    # Start in frames
 """, re.VERBOSE)
 
-# FIXME: handle errors
-
-class ReadTOCTask(task.Task):
-    """
-    I am a task that reads the TOC of a CD, including pregaps.
-
-    @ivar toc: the .toc object
-    @type toc: L{toc.TOC}
-    """
-
-    description = "Reading TOC..."
+_POSITION_RE = re.compile(r"""
+    ^(?P<hh>\d\d):       # HH
+    (?P<mm>\d\d):        # MM
+    (?P<ss>\d\d)         # SS
+""", re.VERBOSE)
 
 
-    def __init__(self):
-        self._buffer = "" # accumulate characters
-        self._lines = [] # accumulate lines
-        self._errors = [] # accumulate error lines
-        self._lineIndex = 0 # where we are
+class OutputParser(object, log.Loggable):
+    def __init__(self, taskk):
+        self._buffer = ""     # accumulate characters
+        self._lines = []      # accumulate lines
+        self._errors = []     # accumulate error lines
         self._state = 'START'
         self._frames = None # number of frames
         self._starts = [] # start of each track, in frames
         self._track = None # which track are we analyzing?
-        self._toc = None # path to temporary .toc file
-
-        self.toc = None # result
+        self._task = taskk
 
-    def start(self, runner):
-        task.Task.start(self, runner)
-
-        # FIXME: create a temporary file instead
-        (fd, self._toc) = tempfile.mkstemp(suffix='.morituri')
-        os.close(fd)
-        os.unlink(self._toc)
-
-        bufsize = 1024
-        self._popen = asyncsub.Popen(["cdrdao", "read-toc", self._toc],
-                  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()
-        self.log(ret)
-        if not ret:
-            # could be finished now
-            self.runner.schedule(1.0, self._poll, runner)
-            return
-
-        self._buffer += ret
+    def read(self, bytes):
+        self._buffer += bytes
 
         # find counter in LEADOUT state
         if self._buffer and  self._state == 'LEADOUT':
@@ -109,17 +80,19 @@ class ReadTOCTask(task.Task):
             # length 03:40:71...\n00:01:00
             times = self._buffer.split('\r')
             position = ""
-            while times and len(position) != 8:
+            m = None
+            while times and not m:
+                m = _POSITION_RE.search(position)
                 position = times.pop()
 
             # we need both a position reported and an Analyzing line
             # to have been parsed to report progress
-            if position and self._track is not None:
+            if m and self._track is not None:
                 frame = self._starts[self._track - 1]  or 0 \
-                    + int(position[0:2]) * 60 * 75 \
-                    + int(position[3:5]) * 75 \
-                    + int(position[6:8])
-                self.setProgress(float(frame) / self._frames)
+                    + int(m.group('hh')) * 60 * 75 \
+                    + int(m.group('mm')) * 75 \
+                    + int(m.group('ss'))
+                self._task.setProgress(float(frame) / self._frames)
 
         # parse buffer into lines if possible, and parse them
         if "\n" in self._buffer:
@@ -138,29 +111,6 @@ class ReadTOCTask(task.Task):
             self._parse(lines)
             self._lines.extend(lines)
 
-        self.runner.schedule(1.0, 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:
-                self.toc = toc.TOC(self._toc)
-                self.toc.parse()
-                os.unlink(self._toc)
-                
-            self.stop()
-            return
 
     def _parse(self, lines):
         for line in lines:
@@ -205,6 +155,76 @@ class ReadTOCTask(task.Task):
             #self.setProgress(float(track - 1) / self._tracks)
             #print 'analyzing', track
 
+
+
+# FIXME: handle errors
+
+class ReadTOCTask(task.Task):
+    """
+    I am a task that reads the TOC of a CD, including pregaps.
+
+    @ivar toc: the .toc object
+    @type toc: L{toc.TOC}
+    """
+
+    description = "Reading TOC..."
+
+
+    def __init__(self):
+        self._parser = OutputParser(self)
+        self._toc = None # path to temporary .toc file
+        self.toc = None # result
+
+    def start(self, runner):
+        task.Task.start(self, runner)
+
+        # FIXME: create a temporary file instead
+        (fd, self._toc) = tempfile.mkstemp(suffix='.morituri')
+        os.close(fd)
+        os.unlink(self._toc)
+
+        bufsize = 1024
+        self._popen = asyncsub.Popen(["cdrdao", "read-toc", self._toc],
+                  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()
+        self.log(ret)
+        if not ret:
+            # could be finished now
+            self.runner.schedule(1.0, self._poll, runner)
+            return
+
+        self._parser.read(ret)
+
+        self.runner.schedule(1.0, 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:
+                self.toc = toc.TOC(self._toc)
+                self.toc.parse()
+                os.unlink(self._toc)
+                
+            self.stop()
+            return
+
 class ReadTableTask(task.Task):
     """
     I am a task that reads the TOC of a CD, without pregaps.
@@ -217,7 +237,6 @@ class ReadTableTask(task.Task):
         self._buffer = "" # accumulate characters
         self._lines = [] # accumulate lines
         self._errors = [] # accumulate error lines
-        self._lineIndex = 0 # where we are
         self._state = 'START'
         self._frames = None # number of frames
         self._starts = [] # start of each track, in frames
diff --git a/morituri/test/test_program_cdrdao.py b/morituri/test/test_program_cdrdao.py
new file mode 100644
index 0000000..4fab8b2
--- /dev/null
+++ b/morituri/test/test_program_cdrdao.py
@@ -0,0 +1,26 @@
+# -*- Mode: Python; test-case-name: morituri.test.test_program_cdparanoia -*-
+# vi:si:et:sw=4:sts=4:ts=4
+
+import os
+import unittest
+
+from morituri.program import cdrdao
+
+class FakeTask:
+    def setProgress(self, value):
+        pass
+
+class ParseTestCase(unittest.TestCase):
+    def setUp(self):
+        path = os.path.join(os.path.dirname(__file__),
+            'cdrdao.readtoc.progress')
+        self._parser = cdrdao.OutputParser(FakeTask())
+
+        self._handle = open(path)
+
+    def testParse(self):
+        for line in self._handle.readlines():
+            self._parser.read(line)
+        self.assertEquals(self._parser._starts,
+            [0, 13864, 31921, 48332, 61733, 80961,
+             100219, 116291, 136188, 157504, 175275])

-- 
morituri packaging



More information about the pkg-multimedia-commits mailing list