From 28c2a47d629e2cd5cd3ac17e02f04311ece642cb Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 7 Jun 2009 14:20:30 +0000 Subject: [PATCH] * morituri/result/result.py: Change toctable to table since it's a full index table. * morituri/common/Makefile.am: * morituri/common/program.py (added): Add module and class for program state. * morituri/rip/cd.py: Use the program state to clean up the do() function. --- ChangeLog | 10 ++++ morituri/common/Makefile.am | 1 + morituri/common/program.py | 103 ++++++++++++++++++++++++++++++++++++ morituri/result/result.py | 4 +- morituri/rip/cd.py | 48 ++++------------- 5 files changed, 128 insertions(+), 38 deletions(-) create mode 100644 morituri/common/program.py diff --git a/ChangeLog b/ChangeLog index 15928c4..51a7aeb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2009-06-07 Thomas Vander Stichele + + * morituri/result/result.py: + Change toctable to table since it's a full index table. + * morituri/common/Makefile.am: + * morituri/common/program.py (added): + Add module and class for program state. + * morituri/rip/cd.py: + Use the program state to clean up the do() function. + 2009-06-07 Thomas Vander Stichele * morituri/rip/cd.py: diff --git a/morituri/common/Makefile.am b/morituri/common/Makefile.am index cf9fa0b..5cd8503 100644 --- a/morituri/common/Makefile.am +++ b/morituri/common/Makefile.am @@ -10,6 +10,7 @@ morituri_PYTHON = \ drive.py \ log.py \ logcommand.py \ + program.py \ renamer.py \ task.py \ taskgtk.py diff --git a/morituri/common/program.py b/morituri/common/program.py new file mode 100644 index 0000000..9c674a2 --- /dev/null +++ b/morituri/common/program.py @@ -0,0 +1,103 @@ +# -*- Mode: Python; test-case-name: morituri.test.test_common_program -*- +# vi:si:et:sw=4:sts=4:ts=4 + +# Morituri - for those about to RIP + +# Copyright (C) 2009 Thomas Vander Stichele + +# This file is part of morituri. +# +# morituri is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# morituri is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with morituri. If not, see . + +""" +Common functionality and class for all programs using morituri. +""" + +from morituri.common import common +from morituri.result import result +from morituri.program import cdrdao + +import os + + +class Program(object): + """ + I maintain program state and functionality. + """ + + cuePath = None + logPath = None + + def __init__(self): + self.result = result.RipResult() + + def _getTableCachePath(self): + path = os.path.join(os.path.expanduser('~'), '.morituri', 'cache', + 'table') + return path + + def unmountDevice(self, device): + """ + Unmount the given device if it is mounted, as happens with automounted + data tracks. + """ + proc = open('/proc/mounts').read() + if device in proc: + print 'Device %s is mounted, unmounting' % device + os.system('umount %s' % device) + + def getTable(self, runner, cddbdiscid, device): + """ + Retrieve the Table either from the cache or the drive. + + @rtype: L{table.Table} + """ + path = self._getTableCachePath() + + pcache = common.PersistedCache(path) + ptable = pcache.get(cddbdiscid) + + if not ptable.object: + t = cdrdao.ReadTableTask(device=device) + runner.run(t) + ptable.persist(t.table) + itable = ptable.object + assert itable.hasTOC() + + self.result.table = itable + + return itable + + def writeCue(self, discName): + assert self.result.table.canCue() + + cuePath = '%s.cue' % discName + handle = open(cuePath, 'w') + # FIXME: do we always want utf-8 ? + handle.write(self.result.table.cue().encode('utf-8')) + handle.close() + + self.cuePath = cuePath + + return cuePath + + def writeLog(self, discName, logger): + logPath = '%s.log' % discName + handle = open(logPath, 'w') + handle.write(logger.log(res).encode('utf-8')) + handle.close() + + self.logPath = logPath + + return logPath diff --git a/morituri/result/result.py b/morituri/result/result.py index 48ca495..b7a1339 100644 --- a/morituri/result/result.py +++ b/morituri/result/result.py @@ -50,10 +50,12 @@ class RipResult: I can be used to write log files. @ivar offset: sample read offset + @ivar table: the full index table + @type table: L{morituri.common.table.Table} """ offset = 0 - toctable = None + table = None artist = None title = None diff --git a/morituri/rip/cd.py b/morituri/rip/cd.py index 3279371..d443e09 100644 --- a/morituri/rip/cd.py +++ b/morituri/rip/cd.py @@ -30,7 +30,7 @@ gobject.threads_init() import gst from morituri.common import logcommand, task, checksum, common, accurip, log -from morituri.common import drive, encode +from morituri.common import drive, encode, program from morituri.result import result from morituri.image import image, cue, table from morituri.program import cdrdao, cdparanoia @@ -261,10 +261,6 @@ class Rip(logcommand.LogCommand): action="store", dest="output_directory", help="output directory (defaults to current directory)") # FIXME: have a cache of these pickles somewhere - self.parser.add_option('-t', '--table-pickle', - action="store", dest="table_pickle", - help="pickle to use for reading and writing the table", - default=default) self.parser.add_option('-T', '--toc-pickle', action="store", dest="toc_pickle", help="pickle to use for reading and writing the TOC", @@ -289,7 +285,9 @@ class Rip(logcommand.LogCommand): def do(self, args): + prog = program.Program() runner = task.SyncRunner() + def function(r, t): r.run(t) @@ -297,10 +295,7 @@ class Rip(logcommand.LogCommand): device = self.parentCommand.options.device print 'Checking device', device - proc = open('/proc/mounts').read() - if device in proc: - print 'Device %s is mounted, unmounting' % device - os.system('umount %s' % device) + prog.unmountDevice(device) # first, read the normal TOC, which is fast ptoc = common.Persister(self.options.toc_pickle or None) @@ -322,17 +317,7 @@ class Rip(logcommand.LogCommand): print ittoc.getMusicBrainzSubmitURL() # now, read the complete index table, which is slower - path = os.path.join(os.path.expanduser('~'), '.morituri', 'cache', - 'table') - pcache = common.PersistedCache(path) - ptable = pcache.get(ittoc.getCDDBDiscId()) - if not ptable.object: - t = cdrdao.ReadTableTask(device=self.parentCommand.options.device) - function(runner, t) - ptable.persist(t.table) - itable = ptable.object - - assert itable.hasTOC() + itable = prog.getTable(runner, ittoc.getCDDBDiscId(), device) assert itable.getCDDBDiscId() == ittoc.getCDDBDiscId(), \ "full table's id %s differs from toc id %s" % ( @@ -349,9 +334,8 @@ class Rip(logcommand.LogCommand): extension = profile.extension # result - res = result.RipResult() + res = prog.result res.offset = int(self.options.offset) - res.toctable = itable res.artist = metadata and metadata.artist or 'Unknown Artist' res.title = metadata and metadata.title or 'Unknown Title' # cdio is optional for now @@ -462,18 +446,12 @@ class Rip(logcommand.LogCommand): ### write disc files discName = getPath(outdir, self.options.disc_template, metadata, - mbdiscid, i) + mbdiscid, 0) dirname = os.path.dirname(discName) if not os.path.exists(dirname): os.makedirs(dirname) - # write .cue file - assert itable.canCue() - cuePath = '%s.cue' % discName - handle = open(cuePath, 'w') - # FIXME: do we always want utf-8 ? - handle.write(itable.cue().encode('utf-8')) - handle.close() + prog.writeCue(discName) # write .m3u file m3uPath = '%s.m3u' % discName @@ -519,7 +497,7 @@ class Rip(logcommand.LogCommand): # FIXME: put accuraterip verification into a separate task/function # and apply here - cueImage = image.Image(cuePath) + cueImage = image.Image(prog.cuePath) verifytask = image.ImageVerifyTask(cueImage) cuetask = image.AccurateRipChecksumTask(cueImage) function(runner, verifytask) @@ -573,13 +551,9 @@ class Rip(logcommand.LogCommand): i + 1, status, c, csum, ar) # write log file - discName = getPath(outdir, self.options.disc_template, metadata, - mbdiscid, i) - logPath = '%s.log' % discName logger = result.getLogger() - handle = open(logPath, 'w') - handle.write(logger.log(res).encode('utf-8')) - handle.close() + prog.writeLog(discName, logger) + class CD(logcommand.LogCommand): summary = "handle CD's"