* 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.
This commit is contained in:
Thomas Vander Stichele
2009-06-07 14:20:30 +00:00
parent d75066d1bb
commit 28c2a47d62
5 changed files with 128 additions and 38 deletions

View File

@@ -1,3 +1,13 @@
2009-06-07 Thomas Vander Stichele <thomas at apestaart dot org>
* 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 <thomas at apestaart dot org>
* morituri/rip/cd.py:

View File

@@ -10,6 +10,7 @@ morituri_PYTHON = \
drive.py \
log.py \
logcommand.py \
program.py \
renamer.py \
task.py \
taskgtk.py

103
morituri/common/program.py Normal file
View File

@@ -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 <http://www.gnu.org/licenses/>.
"""
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

View File

@@ -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

View File

@@ -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"