diff --git a/ChangeLog b/ChangeLog index bb35b33..a7d5770 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2009-06-24 Thomas Vander Stichele + + * morituri/test/test_common_program.py (added): + * morituri/common/program.py: + Break verifyImage into two so we can test it. + Test it using an AccurateRip result for Luke Haines Is Dead + which had a wrongly ripped track 10. + + 2009-06-24 Thomas Vander Stichele * morituri/result/result.py: diff --git a/morituri/common/program.py b/morituri/common/program.py index c2df9f3..057d6c3 100644 --- a/morituri/common/program.py +++ b/morituri/common/program.py @@ -347,7 +347,10 @@ class Program(log.Loggable): def ripTrack(self, runner, trackResult, offset, device, profile, taglist): """ - @param number: track number (1-based) + @param trackResult: the object to store information in. + @type trackResult: L{result.TrackResult} + @param number: track number (1-based) + @type number: int """ if trackResult.number == 0: start, stop = self.getHTOA() @@ -375,6 +378,15 @@ class Program(log.Loggable): trackResult.quality = t.quality def verifyImage(self, runner, responses): + """ + Verify our image against the given AccurateRip responses. + + Needs an initialized self.result. + Will set accurip and friends on each TrackResult. + """ + + self.debug('verifying Image against %d AccurateRip responses', + len(responses)) cueImage = image.Image(self.cuePath) verifytask = image.ImageVerifyTask(cueImage) @@ -382,17 +394,29 @@ class Program(log.Loggable): runner.run(verifytask) runner.run(cuetask) - response = None # track which response matches, for all tracks + self._verifyImageWithChecksums(responses, cuetask.checksums) - # loop over tracks - for i, csum in enumerate(cuetask.checksums): + def _verifyImageWithChecksums(self, responses, checksums): + # loop over tracks to set our calculated AccurateRip CRC's + for i, csum in enumerate(checksums): trackResult = self.result.getTrackResult(i + 1) trackResult.ARCRC = csum + + if not responses: + self.warning('No AccurateRip responses, cannot verify.') + return + + response = None # track which response matches, for all tracks + + # now loop to match responses + for i, csum in enumerate(checksums): + trackResult = self.result.getTrackResult(i + 1) + confidence = None - # match against each response's checksum - for j, r in enumerate(responses or []): + # match against each response's checksum for this track + for j, r in enumerate(responses): if "%08x" % csum == r.checksums[i]: if not response: response = r @@ -401,6 +425,8 @@ class Program(log.Loggable): "checksum %s for %d matches wrong response %d, "\ "checksum %s" % ( csum, i + 1, j + 1, response.checksums[i]) + self.debug("Track: %02d matched in AccurateRip database", + i + 1) trackResult.accurip = True # FIXME: maybe checksums should be ints trackResult.ARDBCRC = int(response.checksums[i], 16) @@ -408,20 +434,29 @@ class Program(log.Loggable): confidence = response.confidences[i] trackResult.ARDBConfidence = confidence - if responses: - maxConfidence = 0 - maxResponse = None - for r in responses: - if r.confidences[i] > maxConfidence: - maxConfidence = r.confidences[i] - maxResponse = r + if not trackResult.accurip: + self.warning("Track %02d: not matched in AccurateRip database", + i + 1) - self.debug('found max confidence %d' % maxConfidence) - trackResult.ARDBMaxConfidence = maxConfidence - if not response: - self.warning('none of the responses matched.') - trackResult.ARDBCRC = int( - maxResponse.checksums[i], 16) + # I have seen AccurateRip responses with 0 as confidence + # for example, Best of Luke Haines, disc 1, track 1 + maxConfidence = -1 + maxResponse = None + for r in responses: + if r.confidences[i] > maxConfidence: + maxConfidence = r.confidences[i] + maxResponse = r + + self.debug('Track %02d: found max confidence %d' % ( + i + 1, maxConfidence)) + trackResult.ARDBMaxConfidence = maxConfidence + if not response: + self.warning('iTrack %02d: none of the responses matched.', + i + 1) + trackResult.ARDBCRC = int( + maxResponse.checksums[i], 16) + else: + trackResult.ARDBCRC = int(response.checksums[i], 16) def writeCue(self, discName): self.debug('write .cue file') diff --git a/morituri/test/test_common_program.py b/morituri/test/test_common_program.py new file mode 100644 index 0000000..45f38f8 --- /dev/null +++ b/morituri/test/test_common_program.py @@ -0,0 +1,53 @@ +# -*- Mode: Python; test-case-name: morituri.test.test_common_program -*- +# vi:si:et:sw=4:sts=4:ts=4 + +import os +import unittest + +from morituri.result import result +from morituri.common import program, accurip + +class TrackImageVerifyTestCase(unittest.TestCase): + # example taken from a rip of Luke Haines Is Dead, disc 1 + # AccurateRip database has 0 confidence for 1st track + # Rip had a wrong result for track 9 + + def testVerify(self): + path = os.path.join(os.path.dirname(__file__), + 'dBAR-020-002e5023-029d8e49-040eaa14.bin') + data = open(path, "rb").read() + responses = accurip.getAccurateRipResponses(data) + + # these crc's were calculated from an actual rip + checksums = [1644890007, 2945205445, 3983436658, 1528082495, + 1203704270, 1163423644, 3649097244, 100524219, 1583356174, 373652058, + 1842579359, 2850056507, 1329730252, 2526965856, 2525886806, 209743350, + 3184062337, 2099956663, 2943874164, 2321637196] + + prog = program.Program() + prog.result = result.RipResult() + # fill it with empty trackresults + for i, c in enumerate(checksums): + r = result.TrackResult() + r.number = i + 1 + prog.result.tracks.append(r) + + prog._verifyImageWithChecksums(responses, checksums) + + # now check if the results were filled in properly + tr = prog.result.getTrackResult(1) + self.assertEquals(tr.accurip, False) + self.assertEquals(tr.ARDBMaxConfidence, 0) + self.assertEquals(tr.ARDBCRC, 0) + self.assertEquals(tr.ARDBCRC, 0) + + tr = prog.result.getTrackResult(2) + self.assertEquals(tr.accurip, True) + self.assertEquals(tr.ARDBMaxConfidence, 2) + self.assertEquals(tr.ARDBCRC, checksums[2 - 1]) + + tr = prog.result.getTrackResult(10) + self.assertEquals(tr.accurip, False) + self.assertEquals(tr.ARDBMaxConfidence, 2) + # we know track 10 was ripped wrong + self.assertNotEquals(tr.ARDBCRC, checksums[10 - 1])