From 05e90de6e3f23155ea46e1c6ceaf1a73dfbc4a5d Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Sun, 3 May 2009 10:08:03 +0000 Subject: [PATCH] * examples/ARcalibrate.py (added): Add an example that calculates the read offset of your drive using AccurateRip. --- ChangeLog | 6 ++ examples/ARcalibrate.py | 151 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 examples/ARcalibrate.py diff --git a/ChangeLog b/ChangeLog index 2f054c2..febf7d6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-05-03 Thomas Vander Stichele + + * examples/ARcalibrate.py (added): + Add an example that calculates the read offset of your drive + using AccurateRip. + 2009-05-03 Thomas Vander Stichele * morituri/program/cdrdao.py: diff --git a/examples/ARcalibrate.py b/examples/ARcalibrate.py new file mode 100644 index 0000000..7e7aac6 --- /dev/null +++ b/examples/ARcalibrate.py @@ -0,0 +1,151 @@ +# -*- Mode: Python; test-case-name: morituri.test.test_header -*- +# 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 os +import sys +import tempfile +import optparse + +import gobject +gobject.threads_init() +import gtk + +from morituri.image import image +from morituri.common import task, checksum +from morituri.program import cdrdao, cdparanoia + +""" +Find read offset by ripping a track from an AccurateRip CD. +""" + +from morituri.common import log +log.init() + +def gtkmain(runner, taskk): + runner.connect('stop', lambda _: gtk.main_quit()) + + window = gtk.Window() + window.add(runner) + window.show_all() + + runner.run(taskk) + + gtk.main() + +def climain(runner, taskk): + runner.run(taskk) + + +def main(argv): + parser = optparse.OptionParser() + + default = 'cli' + parser.add_option('-r', '--runner', + action="store", dest="runner", + help="runner ('cli' or 'gtk', defaults to %s)" % default, + default=default) + + # 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" + 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) + + options, args = parser.parse_args(argv[1:]) + + offsets = [] + blocks = options.offsets.split(',') + for b in blocks: + if ':' in b: + a, b = b.split(':') + offsets.extend(range(int(a), int(b) + 1)) + else: + offsets.append(int(b)) + + # first get the Table Of Contents of the CD + t = cdrdao.ReadTableTask() + + if options.runner == 'cli': + runner = task.SyncRunner() + function = climain + elif options.runner == 'gtk': + runner = task.GtkProgressRunner() + function = gtkmain + + function(runner, t) + table = t.table + + print "CDDB disc id", table.getCDDBDiscId() + url = table.getAccurateRipURL() + print "AccurateRip URL", 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' + else: + raise + + if responses: + print '%d AccurateRip reponses found' % len(responses) + + if responses[0].cddbDiscId != table.getCDDBDiscId(): + print "AccurateRip response discid different: %s" % \ + responses[0].cddbDiscId + + response = None + + # now rip the first track at various offsets, calculating AccurateRip + # CRC, and matching it against the retrieved ones + for offset in offsets: + fd, path = tempfile.mkstemp(suffix='.morituri') + os.close(fd) + + print 'ripping track 1 with offset', offset + track = table.tracks[0] + t = cdparanoia.ReadTrackTask(path, track.start, track.end, offset) + t.description = 'Ripping with offset %d' % offset + function(runner, t) + + t = checksum.AccurateRipChecksumTask(path, trackNumber=1, + trackCount = len(table.tracks)) + function(runner, t) + arcs = "%08x" % t.checksum + print 'AR checksum calculated: %s' % arcs + + for i, r in enumerate(responses): + if arcs == r.checksums[0]: + print 'MATCHED against response %d' % i + print 'offset of device is', offset + + +main(sys.argv)