[SCM] morituri/master: * morituri/rip/Makefile.am: * morituri/rip/main.py: * morituri/rip/offset.py (added): Add first command, 'rip offset find'
js at users.alioth.debian.org
js at users.alioth.debian.org
Sun Oct 19 20:09:03 UTC 2014
The following commit has been merged in the master branch:
commit 9e3e1d53cb76738b6eae49989caa6bb881eea230
Author: Thomas Vander Stichele <thomas (at) apestaart (dot) org>
Date: Sat May 23 09:00:03 2009 +0000
* morituri/rip/Makefile.am:
* morituri/rip/main.py:
* morituri/rip/offset.py (added):
Add first command, 'rip offset find'
diff --git a/ChangeLog b/ChangeLog
index f401110..b1a4edf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2009-05-23 Thomas Vander Stichele <thomas at apestaart dot org>
+ * morituri/rip/Makefile.am:
+ * morituri/rip/main.py:
+ * morituri/rip/offset.py (added):
+ Add first command, 'rip offset find'
+
+2009-05-23 Thomas Vander Stichele <thomas at apestaart dot org>
+
* Makefile.am:
* morituri/test/Makefile.am:
Make distcheck work.
diff --git a/morituri/rip/Makefile.am b/morituri/rip/Makefile.am
index 760ae03..7a47728 100644
--- a/morituri/rip/Makefile.am
+++ b/morituri/rip/Makefile.am
@@ -4,4 +4,5 @@ morituridir = $(PYTHONLIBDIR)/morituri/rip
morituri_PYTHON = \
__init__.py \
- main.py
+ main.py \
+ offset.py
diff --git a/morituri/rip/main.py b/morituri/rip/main.py
index b3a4911..8335e10 100644
--- a/morituri/rip/main.py
+++ b/morituri/rip/main.py
@@ -4,6 +4,7 @@
import sys
from morituri.common import log, logcommand
+from morituri.rip import offset
def main(argv):
c = Rip()
@@ -30,7 +31,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 = []
+ subCommandClasses = [offset.Offset, ]
def addOptions(self):
# FIXME: is this the right place ?
diff --git a/morituri/rip/offset.py b/morituri/rip/offset.py
new file mode 100644
index 0000000..df4a2ef
--- /dev/null
+++ b/morituri/rip/offset.py
@@ -0,0 +1,165 @@
+# -*- 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 <http://www.gnu.org/licenses/>.
+
+import os
+import tempfile
+
+import gobject
+gobject.threads_init()
+
+from morituri.common import logcommand, task, checksum
+from morituri.image import image
+from morituri.program import cdrdao, cdparanoia
+
+
+class Find(logcommand.LogCommand):
+ summary = "find drive read offset"
+ description = """Find drive's read offset by ripping tracks from a
+CD in the AccurateRip database."""
+
+ def addOptions(self):
+ # see http://www.accuraterip.com/driveoffsets.htm
+ default = "0, 6, 12, 48, 91, 97, 102, 108, 120, " + \
+ "564, 594, 667, 685, 691, 704, 738, 1194, 1292, 1336, 1776, -582"
+ self.parser.add_option('-o', '--offsets',
+ action="store", dest="offsets",
+ help="list of offsets, comma-separated, "
+ "colon-separated for ranges (defaults to %s)" % default,
+ default=default)
+
+ def handleOptions(self, options):
+ self.options = options
+ self._offsets = []
+ blocks = options.offsets.split(',')
+ for b in blocks:
+ if ':' in b:
+ a, b = b.split(':')
+ self._offsets.extend(range(int(a), int(b) + 1))
+ else:
+ self._offsets.append(int(b))
+
+ self.debug('Trying with offsets %r', self._offsets)
+
+ def do(self, args):
+ runner = task.SyncRunner()
+
+ # first get the Table Of Contents of the CD
+ t = cdrdao.ReadTOCTask()
+
+ runner.run(t)
+ table = t.table
+
+ self.debug("CDDB disc id: %r", table.getCDDBDiscId())
+ url = table.getAccurateRipURL()
+ self.debug("AccurateRip URL: %s", url)
+
+ # FIXME: download url as a task too
+ responses = []
+ import urllib2
+ try:
+ handle = urllib2.urlopen(url)
+ data = handle.read()
+ responses = image.getAccurateRipResponses(data)
+ except urllib2.HTTPError, e:
+ if e.code == 404:
+ print 'Album not found in AccurateRip database.'
+ return 1
+ else:
+ raise
+
+ if responses:
+ self.debug('%d AccurateRip reponses found.' % len(responses))
+
+ if responses[0].cddbDiscId != table.getCDDBDiscId():
+ self.warning("AccurateRip response discid different: %s",
+ responses[0].cddbDiscId)
+
+ # now rip the first track at various offsets, calculating AccurateRip
+ # CRC, and matching it against the retrieved ones
+
+ def match(archecksum, track, responses):
+ for i, r in enumerate(responses):
+ if archecksum == r.checksums[track - 1]:
+ return archecksum, i
+
+ return None, None
+
+ for offset in self._offsets:
+ print 'Trying read offset %d ...' % offset
+ archecksum = self._arcs(runner, table, 1, offset)
+
+ self.debug('AR checksum calculated: %s' % archecksum)
+
+ c, i = match(archecksum, 1, responses)
+ if c:
+ count = 1
+ self.debug('MATCHED against response %d' % i)
+ print 'Offset of device is likely %d, confirming ...' % offset
+
+ # now try and rip all other tracks as well
+ for track in range(2, len(table.tracks) + 1):
+ archecksum = self._arcs(runner, table, track, offset)
+ c, i = match(archecksum, track, responses)
+ if c:
+ self.debug('MATCHED track %d against response %d' % (
+ track, i))
+ count += 1
+
+ if count == len(table.tracks):
+ print
+ print 'Read offset of device is: %d.' % offset
+ return 0
+ else:
+ print 'Only %d of %d tracks matched, continuing ...' % (
+ count, len(table.tracks))
+
+ print 'No matching offset found.'
+ print 'Consider trying again with a different disc.'
+
+ def _arcs(self, runner, table, track, offset):
+ # rips the track with the given offset, return the arcs checksum
+ self.debug('Ripping track %r with offset %d ...', track, offset)
+
+ fd, path = tempfile.mkstemp(
+ suffix='.track%02d.offset%d.morituri.wav' % (
+ track, offset))
+ os.close(fd)
+
+ t = cdparanoia.ReadTrackTask(path, table, table.getTrackStart(track),
+ table.getTrackEnd(track), offset)
+ t.description = 'Ripping track %d with read offset %d' % (
+ track, offset)
+ runner.run(t)
+
+ t = checksum.AccurateRipChecksumTask(path, trackNumber=track,
+ trackCount=len(table.tracks))
+ runner.run(t)
+
+ os.unlink(path)
+ return "%08x" % t.checksum
+
+class Offset(logcommand.LogCommand):
+ summary = "handle drive offsets"
+
+ subCommandClasses = [Find, ]
+
+
--
morituri packaging
More information about the pkg-multimedia-commits
mailing list