From 4647d107a910a57328ba98e65a99d21948a5dd4f Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Tue, 4 Dec 2012 00:14:42 +0000 Subject: [PATCH] * morituri/program/cdparanoia.py: * morituri/test/test_program_cdparanoia.py: Add a task that can analyze the drive for whether it defeats the audio cache. * morituri/result/result.py: * morituri/rip/cd.py: Make it possible to store whether a drive defeats audio cache in the result. * morituri/rip/drive.py: Add rip drive analyze command to analyze caching of a drive, and store it in the config. --- ChangeLog | 14 ++++++ morituri/program/cdparanoia.py | 43 ++++++++++++++++++ morituri/result/result.py | 1 + morituri/rip/cd.py | 7 +++ morituri/rip/drive.py | 56 +++++++++++++++++++++++- morituri/test/test_program_cdparanoia.py | 35 ++++++++++++--- 6 files changed, 150 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 580302b..ae9eefc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2012-12-04 Thomas Vander Stichele + + * morituri/program/cdparanoia.py: + * morituri/test/test_program_cdparanoia.py: + Add a task that can analyze the drive for whether it defeats + the audio cache. + * morituri/result/result.py: + * morituri/rip/cd.py: + Make it possible to store whether a drive defeats audio cache + in the result. + * morituri/rip/drive.py: + Add rip drive analyze command to analyze caching of a drive, + and store it in the config. + 2012-12-04 Thomas Vander Stichele * morituri/common/task.py: diff --git a/morituri/program/cdparanoia.py b/morituri/program/cdparanoia.py index b8de4ae..c86ff02 100644 --- a/morituri/program/cdparanoia.py +++ b/morituri/program/cdparanoia.py @@ -30,6 +30,7 @@ import subprocess import tempfile from morituri.common import log, common +from morituri.common import task as ctask from morituri.extern import asyncsub from morituri.extern.task import task @@ -562,3 +563,45 @@ def getCdParanoiaVersion(): raise return version + + +_OK_RE = re.compile(r'Drive tests OK with Paranoia.') + + +class AnalyzeTask(ctask.PopenTask): + + logCategory = 'AnalyzeTask' + description = 'Analyzing drive caching behaviour' + + defeatsCache = None + + cwd = None + + _output = [] + + def __init__(self, device=None): + # cdparanoia -A *always* writes cdparanoia.log + self.cwd = tempfile.mkdtemp(suffix='.morituri.cache') + self.command = ['cdparanoia', '-A'] + if device: + self.command += ['-d', device] + + def commandMissing(self): + raise common.MissingDependencyException('cdparanoia') + + def readbyteserr(self, bytes): + self._output.append(bytes) + + def done(self): + if self.cwd: + shutil.rmtree(self.cwd) + output = "".join(self._output) + m = _OK_RE.search(output) + if m: + self.defeatsCache = True + else: + self.defeatsCache = False + + def failed(self): + if self.cwd: + shutil.rmtree(self.cwd) diff --git a/morituri/result/result.py b/morituri/result/result.py index 2ebed3a..7d25707 100644 --- a/morituri/result/result.py +++ b/morituri/result/result.py @@ -103,6 +103,7 @@ class RipResult: cdrdaoVersion = None cdparanoiaVersion = None + cdparanoiaDefeatsCache = None gstreamerVersion = None gstPythonVersion = None diff --git a/morituri/rip/cd.py b/morituri/rip/cd.py index 83486cc..e8e6543 100644 --- a/morituri/rip/cd.py +++ b/morituri/rip/cd.py @@ -214,6 +214,13 @@ Log files will log the path to tracks relative to this directory. prog.result.cdrdaoVersion = version prog.result.cdparanoiaVersion = cdparanoia.getCdParanoiaVersion() + info = drive.getDeviceInfo(self.parentCommand.options.device) + if info: + try: + prog.result.cdparanoiaDefeatsCache = self.getRootCommand( + ).config.getDefeatsCache(*info) + except KeyError: + pass prog.result.offset = int(self.options.offset) prog.result.artist = prog.metadata and prog.metadata.artist \ or 'Unknown Artist' diff --git a/morituri/rip/drive.py b/morituri/rip/drive.py index 27eb12f..adc1dc7 100644 --- a/morituri/rip/drive.py +++ b/morituri/rip/drive.py @@ -20,7 +20,61 @@ # You should have received a copy of the GNU General Public License # along with morituri. If not, see . +import os + +from morituri.extern.task import task + from morituri.common import logcommand, drive +from morituri.program import cdparanoia + + +class Analyze(logcommand.LogCommand): + + summary = "analyze caching behaviour of drive" + + def addOptions(self): + self.parser.add_option('-d', '--device', + action="store", dest="device", + help="CD-DA device") + + def handleOptions(self, options): + if not options.device: + drives = drive.getAllDevicePaths() + if not drives: + self.error('No CD-DA drives found!') + return 3 + + # pick the first + self.options.device = drives[0] + + # this can be a symlink to another device + self.options.device = os.path.realpath(self.options.device) + + def do(self, args): + runner = task.SyncRunner() + t = cdparanoia.AnalyzeTask(self.options.device) + runner.run(t) + + if t.defeatsCache is None: + self.stdout.write( + 'Cannot analyze the drive. Is there a CD in it?\n') + return + if not t.defeatsCache: + self.stdout.write( + 'cdparanoia cannot defeat the audio cache on this drive.\n') + else: + self.stdout.write( + 'cdparanoia can defeat the audio cache on this drive.\n') + + info = drive.getDeviceInfo(self.options.device) + if not info: + return + + self.stdout.write( + 'Adding drive cache behaviour to configuration file.\n') + + self.getRootCommand().config.setDefeatsCache(info[0], info[1], info[2], + t.defeatsCache) class List(logcommand.LogCommand): @@ -66,4 +120,4 @@ class Drive(logcommand.LogCommand): summary = "handle drives" - subCommandClasses = [List, ] + subCommandClasses = [Analyze, List, ] diff --git a/morituri/test/test_program_cdparanoia.py b/morituri/test/test_program_cdparanoia.py index 4caedda..58e0bbc 100644 --- a/morituri/test/test_program_cdparanoia.py +++ b/morituri/test/test_program_cdparanoia.py @@ -2,12 +2,15 @@ # vi:si:et:sw=4:sts=4:ts=4 import os -import unittest + +from morituri.extern.task import task from morituri.program import cdparanoia +from morituri.test import common -class ParseTestCase(unittest.TestCase): + +class ParseTestCase(common.TestCase): def setUp(self): # report from Afghan Whigs - Sweet Son Of A Bitch @@ -25,7 +28,7 @@ class ParseTestCase(unittest.TestCase): self.assertEquals(q, '99.7 %') -class ErrorTestCase(unittest.TestCase): +class ErrorTestCase(common.TestCase): def setUp(self): # report from a rip with offset -1164 causing scsi errors @@ -43,7 +46,29 @@ class ErrorTestCase(unittest.TestCase): self.assertEquals(q, '79.6 %') -class VersionTestCase(unittest.TestCase): +class VersionTestCase(common.TestCase): def testGetVersion(self): - self.failUnless(cdparanoia.getCdparanoiaVersion()) + self.failUnless(cdparanoia.getCdParanoiaVersion()) + + +class AnalyzeFileTask(cdparanoia.AnalyzeTask): + + def __init__(self, path): + self.command = ['cat', path] + + def readbytesout(self, bytes): + self.readbyteserr(bytes) + + +class CacheTestCase(common.TestCase): + + def testDefeatsCache(self): + self.runner = task.SyncRunner(verbose=False) + + path = os.path.join(os.path.dirname(__file__), + 'cdparanoia', 'PX-L890SA.cdparanoia-A.stderr') + t = AnalyzeFileTask(path) + self.runner.run(t) + self.failUnless(t.defeatsCache) +