* morituri/result/result.py:
Add max confidence from database. * morituri/common/program.py: * morituri/rip/cd.py: Move AccurateRip checking to program.py Re-rip if verification failed when continuing a rip.
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
2009-06-15 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/result/result.py:
|
||||
Add max confidence from database.
|
||||
* morituri/common/program.py:
|
||||
* morituri/rip/cd.py:
|
||||
Move AccurateRip checking to program.py
|
||||
Re-rip if verification failed when continuing a rip.
|
||||
|
||||
2009-06-15 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/image/cue.py:
|
||||
|
||||
@@ -26,9 +26,10 @@ Common functionality and class for all programs using morituri.
|
||||
|
||||
import os
|
||||
|
||||
from morituri.common import common, log
|
||||
from morituri.common import common, log, checksum
|
||||
from morituri.result import result
|
||||
from morituri.program import cdrdao, cdparanoia
|
||||
from morituri.image import image
|
||||
|
||||
import gst
|
||||
|
||||
@@ -121,7 +122,7 @@ def musicbrainz(discid):
|
||||
|
||||
return ret
|
||||
|
||||
class Program(object):
|
||||
class Program(log.Loggable):
|
||||
"""
|
||||
I maintain program state and functionality.
|
||||
|
||||
@@ -229,7 +230,11 @@ class Program(object):
|
||||
v['d'] = mbdiscid
|
||||
|
||||
v['a'] = v['A']
|
||||
v['n'] = 'Unknown Track %d' % i
|
||||
if i == 0:
|
||||
v['n'] = 'Hidden Track One Audio'
|
||||
else:
|
||||
v['n'] = 'Unknown Track %d' % i
|
||||
|
||||
|
||||
if self.metadata:
|
||||
v['A'] = filterForPath(self.metadata.artist)
|
||||
@@ -244,7 +249,6 @@ class Program(object):
|
||||
else:
|
||||
# htoa defaults to disc's artist
|
||||
v['a'] = filterForPath(self.metadata.artist)
|
||||
v['n'] = filterForPath('Hidden Track One Audio')
|
||||
|
||||
import re
|
||||
template = re.sub(r'%(\w)', r'%(\1)s', template)
|
||||
@@ -334,6 +338,13 @@ class Program(object):
|
||||
stop = track.getIndex(1).absolute - 1
|
||||
return (start, stop)
|
||||
|
||||
def verifyTrack(self, runner, trackResult):
|
||||
t = checksum.CRC32Task(trackResult.filename)
|
||||
|
||||
runner.run(t)
|
||||
|
||||
return trackResult.testcrc == t.checksum
|
||||
|
||||
def ripTrack(self, runner, trackResult, offset, device, profile, taglist):
|
||||
"""
|
||||
@param number: track number (1-based)
|
||||
@@ -363,7 +374,51 @@ class Program(object):
|
||||
trackResult.peak = t.peak
|
||||
trackResult.quality = t.quality
|
||||
|
||||
def verifyImage(self, runner, responses):
|
||||
|
||||
cueImage = image.Image(self.cuePath)
|
||||
verifytask = image.ImageVerifyTask(cueImage)
|
||||
cuetask = image.AccurateRipChecksumTask(cueImage)
|
||||
runner.run(verifytask)
|
||||
runner.run(cuetask)
|
||||
|
||||
response = None # track which response matches, for all tracks
|
||||
|
||||
# loop over tracks
|
||||
for i, csum in enumerate(cuetask.checksums):
|
||||
trackResult = self.result.getTrackResult(i + 1)
|
||||
trackResult.accuripCRC = csum
|
||||
|
||||
confidence = None
|
||||
|
||||
# match against each response's checksum
|
||||
for j, r in enumerate(responses or []):
|
||||
if "%08x" % csum == r.checksums[i]:
|
||||
if not response:
|
||||
response = r
|
||||
else:
|
||||
assert r == response, \
|
||||
"checksum %s for %d matches wrong response %d, "\
|
||||
"checksum %s" % (
|
||||
csum, i + 1, j + 1, response.checksums[i])
|
||||
trackResult.accurip = True
|
||||
# FIXME: maybe checksums should be ints
|
||||
trackResult.accuripDatabaseCRC = int(response.checksums[i], 16)
|
||||
# arsum = csum
|
||||
confidence = response.confidences[i]
|
||||
trackResult.accuripDatabaseConfidence = confidence
|
||||
|
||||
if responses:
|
||||
maxConfidence = max(r.confidences[i] for r in responses)
|
||||
self.debug('found max confidence %d' % maxConfidence)
|
||||
trackResult.accuripDatabaseMaxConfidence = maxConfidence
|
||||
if not response:
|
||||
self.warning('none of the responses matched.')
|
||||
|
||||
|
||||
def writeCue(self, discName):
|
||||
self.debug('write .cue file')
|
||||
import code; code.interact(local=locals())
|
||||
assert self.result.table.canCue()
|
||||
|
||||
cuePath = '%s.cue' % discName
|
||||
|
||||
@@ -43,6 +43,9 @@ class TrackResult:
|
||||
accuripCRC = None
|
||||
accuripDatabaseCRC = None
|
||||
accuripDatabaseConfidence = None
|
||||
accuripDatabaseMaxConfidence = None
|
||||
|
||||
classVersion = 2
|
||||
|
||||
class RipResult:
|
||||
"""
|
||||
|
||||
@@ -165,6 +165,13 @@ class Rip(logcommand.LogCommand):
|
||||
trackResult.pregap = itable.tracks[number - 1].getPregap()
|
||||
|
||||
# FIXME: optionally allow overriding reripping
|
||||
if os.path.exists(path):
|
||||
print 'Verifying track %d of %d: %s' % (
|
||||
number, len(itable.tracks), os.path.basename(path))
|
||||
if not prog.verifyTrack(runner, trackResult):
|
||||
print 'Verification failed, reripping...'
|
||||
os.unlink(path)
|
||||
|
||||
if not os.path.exists(path):
|
||||
print 'Ripping track %d of %d: %s' % (
|
||||
number, len(itable.tracks), os.path.basename(path))
|
||||
@@ -224,6 +231,7 @@ class Rip(logcommand.LogCommand):
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
|
||||
self.debug('writing cue file for %s', discName)
|
||||
prog.writeCue(discName)
|
||||
|
||||
# write .m3u file
|
||||
@@ -270,58 +278,30 @@ class Rip(logcommand.LogCommand):
|
||||
|
||||
# FIXME: put accuraterip verification into a separate task/function
|
||||
# and apply here
|
||||
cueImage = image.Image(prog.cuePath)
|
||||
verifytask = image.ImageVerifyTask(cueImage)
|
||||
cuetask = image.AccurateRipChecksumTask(cueImage)
|
||||
function(runner, verifytask)
|
||||
function(runner, cuetask)
|
||||
|
||||
response = None # track which response matches, for all tracks
|
||||
prog.verifyImage(runner, responses)
|
||||
|
||||
# loop over tracks
|
||||
for i, csum in enumerate(cuetask.checksums):
|
||||
trackResult = prog.result.getTrackResult(i + 1)
|
||||
trackResult.accuripCRC = csum
|
||||
for trackResult in prog.result.tracks:
|
||||
|
||||
status = 'rip NOT accurate'
|
||||
|
||||
confidence = None
|
||||
|
||||
# match against each response's checksum
|
||||
for j, r in enumerate(responses or []):
|
||||
if "%08x" % csum == r.checksums[i]:
|
||||
if not response:
|
||||
response = r
|
||||
else:
|
||||
assert r == response, \
|
||||
"checksum %s for %d matches wrong response %d, "\
|
||||
"checksum %s" % (
|
||||
csum, i + 1, j + 1, response.checksums[i])
|
||||
if trackResult.accurip:
|
||||
status = 'rip accurate '
|
||||
trackResult.accurip = True
|
||||
# FIXME: maybe checksums should be ints
|
||||
trackResult.accuripDatabaseCRC = int(response.checksums[i], 16)
|
||||
# arsum = csum
|
||||
confidence = response.confidences[i]
|
||||
trackResult.accuripDatabaseConfidence = confidence
|
||||
|
||||
c = "(not found)"
|
||||
ar = "(not in database)"
|
||||
if responses:
|
||||
if not response:
|
||||
print 'ERROR: none of the responses matched.'
|
||||
else:
|
||||
maxConfidence = max(r.confidences[i] for r in responses)
|
||||
|
||||
c = "(max confidence %3d)" % maxConfidence
|
||||
if confidence is not None:
|
||||
if confidence < maxConfidence:
|
||||
c = "(confidence %3d of %3d)" % (
|
||||
confidence, maxConfidence)
|
||||
if trackResult.accuripDatabaseMaxConfidence:
|
||||
c = "(max confidence %3d)" % trackResult.accuripDatabaseMaxConfidence
|
||||
if trackResult.accuripDatabaseConfidence is not None:
|
||||
if trackResult.accuripDatabaseConfidence \
|
||||
< trackResult.accuripDatabaseMaxConfidence:
|
||||
c = "(confidence %3d of %3d)" % (
|
||||
trackResult.accuripDatabaseConfidence,
|
||||
trackResult.accuripDatabaseMaxConfidence)
|
||||
|
||||
ar = ", AR [%s]" % response.checksums[i]
|
||||
print "Track %2d: %s %s [%08x]%s" % (
|
||||
i + 1, status, c, csum, ar)
|
||||
ar = ", AR [%08x]" % trackResult.accuripDatabaseCRC
|
||||
print "Track %2d: %s %s [%08x]%s" % (
|
||||
i + 1, status, c, trackResult.accuripDatabaseCRC, ar)
|
||||
|
||||
# write log file
|
||||
logger = result.getLogger()
|
||||
|
||||
Reference in New Issue
Block a user