From 5f872bdaf86fcd2c3452be92cd93a533ba843eb4 Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sat, 23 May 2009 16:03:05 +0000 Subject: [PATCH] * morituri/rip/Makefile.am: * morituri/rip/main.py: * morituri/rip/drive.py (added): Add 'rip drive list' command to list available drives. * morituri/common/accurip.py: Add force. * morituri/rip/cd.py: Add --output-directory argument. --- ChangeLog | 11 ++++++++++ morituri/common/accurip.py | 5 ++++- morituri/rip/Makefile.am | 1 + morituri/rip/cd.py | 19 ++++++++++------ morituri/rip/drive.py | 44 ++++++++++++++++++++++++++++++++++++++ morituri/rip/main.py | 5 +++-- 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 morituri/rip/drive.py diff --git a/ChangeLog b/ChangeLog index 22180be..0559922 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-05-23 Thomas Vander Stichele + + * morituri/rip/Makefile.am: + * morituri/rip/main.py: + * morituri/rip/drive.py (added): + Add 'rip drive list' command to list available drives. + * morituri/common/accurip.py: + Add force. + * morituri/rip/cd.py: + Add --output-directory argument. + 2009-05-23 Thomas Vander Stichele * morituri/common/Makefile.am: diff --git a/morituri/common/accurip.py b/morituri/common/accurip.py index 23bc5f0..7b9c16b 100644 --- a/morituri/common/accurip.py +++ b/morituri/common/accurip.py @@ -43,7 +43,10 @@ class AccuCache(log.Loggable): self.debug("Retrieving AccurateRip URL %s", url) path = self._getPath(url) self.debug("Cached path: %s", path) - if not os.path.exists(path): + if force: + self.debug("forced to download") + self.download(url) + elif not os.path.exists(path): self.debug("%s does not exist, downloading", path) self.download(url) diff --git a/morituri/rip/Makefile.am b/morituri/rip/Makefile.am index 840a904..a584cb8 100644 --- a/morituri/rip/Makefile.am +++ b/morituri/rip/Makefile.am @@ -5,5 +5,6 @@ morituridir = $(PYTHONLIBDIR)/morituri/rip morituri_PYTHON = \ __init__.py \ cd.py \ + drive.py \ main.py \ offset.py diff --git a/morituri/rip/cd.py b/morituri/rip/cd.py index 4eda333..3882329 100644 --- a/morituri/rip/cd.py +++ b/morituri/rip/cd.py @@ -101,6 +101,7 @@ def musicbrainz(discid): sys.exit(2) + # convert to our objects isSingleArtist = release.isSingleArtistRelease() metadata.various = not isSingleArtist metadata.title = release.title @@ -121,7 +122,7 @@ def musicbrainz(discid): return metadata -def getPath(template, metadata, i): +def getPath(outdir, template, metadata, i): # returns without extension v = {} @@ -149,7 +150,7 @@ def getPath(template, metadata, i): import re template = re.sub(r'%(\w)', r'%(\1)s', template) - return template % v + return os.path.join(outdir, template % v) class Rip(logcommand.LogCommand): summary = "rip CD" @@ -159,8 +160,11 @@ class Rip(logcommand.LogCommand): default = 0 self.parser.add_option('-o', '--offset', action="store", dest="offset", - help="sample offset (defaults to %d)" % default, + help="sample read offset (defaults to %d)" % default, default=default) + self.parser.add_option('-O', '--output-directory', + 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", @@ -222,6 +226,7 @@ class Rip(logcommand.LogCommand): itable.getCDDBDiscId(), ittoc.getCDDBDiscId()) assert itable.getMusicBrainzDiscId() == ittoc.getMusicBrainzDiscId() + outdir = self.options.output_directory or os.getcwd() lastTrackStart = 0 # check for hidden track one audio @@ -239,7 +244,7 @@ class Rip(logcommand.LogCommand): print 'Found Hidden Track One Audio from frame %d to %d' % (start, stop) # rip it - htoapath = getPath(self.options.track_template, metadata, -1) + '.wav' + htoapath = getPath(outdir, self.options.track_template, metadata, -1) + '.wav' htoalength = stop - start if not os.path.exists(htoapath): print 'Ripping track %d: %s' % (0, os.path.basename(htoapath)) @@ -256,7 +261,7 @@ class Rip(logcommand.LogCommand): for i, track in enumerate(itable.tracks): - path = getPath(self.options.track_template, metadata, i) + '.wav' + path = getPath(outdir, self.options.track_template, metadata, i) + '.wav' dirname = os.path.dirname(path) if not os.path.exists(dirname): os.makedirs(dirname) @@ -280,7 +285,7 @@ class Rip(logcommand.LogCommand): ### write disc files - discName = getPath(self.options.disc_template, metadata, i) + discName = getPath(outdir, self.options.disc_template, metadata, i) dirname = os.path.dirname(discName) if not os.path.exists(dirname): os.makedirs(dirname) @@ -302,7 +307,7 @@ class Rip(logcommand.LogCommand): handle.write('%s\n' % os.path.basename(htoapath)) for i, track in enumerate(itable.tracks): - path = getPath(self.options.track_template, metadata, i) + '.wav' + path = getPath(outdir, self.options.track_template, metadata, i) + '.wav' handle.write('#EXTINF:%d,%s\n' % ( itable.getTrackLength(i + 1) / common.FRAMES_PER_SECOND, os.path.basename(path))) diff --git a/morituri/rip/drive.py b/morituri/rip/drive.py new file mode 100644 index 0000000..009e0ec --- /dev/null +++ b/morituri/rip/drive.py @@ -0,0 +1,44 @@ +# -*- Mode: Python -*- +# 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 . + +import pycdio +import cdio + +from morituri.common import logcommand + +class List(logcommand.LogCommand): + summary = "list drives" + + def do(self, args): + paths = cdio.get_devices_with_cap(pycdio.FS_AUDIO, False) + for path in paths: + device = cdio.Device(path) + ok, vendor, model, release = device.get_hwinfo() + print "drive: %s, vendor: %s, model: %s, release: %s" % ( + path, vendor, model, release) + +class Drive(logcommand.LogCommand): + summary = "handle drives" + + subCommandClasses = [List, ] + + diff --git a/morituri/rip/main.py b/morituri/rip/main.py index e924bb3..e797d33 100644 --- a/morituri/rip/main.py +++ b/morituri/rip/main.py @@ -4,7 +4,7 @@ import sys from morituri.common import log, logcommand -from morituri.rip import cd, offset +from morituri.rip import cd, offset, drive def main(argv): c = Rip() @@ -21,6 +21,7 @@ def main(argv): if ret is None: return 0 + return ret class Rip(logcommand.LogCommand): @@ -31,7 +32,7 @@ Rip gives you a tree of subcommands to work with. You can get help on subcommands by using the -h option to the subcommand. """ - subCommandClasses = [cd.CD, offset.Offset, ] + subCommandClasses = [cd.CD, drive.Drive, offset.Offset, ] def addOptions(self): # FIXME: is this the right place ?