* morituri/rip/cd.py:
Use RipResult to store result information. * morituri/result/logger.py (added): Add a Logger to handle the RipResult, much like EAC's log file.
This commit is contained in:
@@ -1,3 +1,11 @@
|
||||
2009-06-05 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/rip/cd.py:
|
||||
Use RipResult to store result information.
|
||||
* morituri/result/logger.py (added):
|
||||
Add a Logger to handle the RipResult, much like
|
||||
EAC's log file.
|
||||
|
||||
2009-06-05 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||
|
||||
* morituri/rip/cd.py:
|
||||
|
||||
127
morituri/result/logger.py
Normal file
127
morituri/result/logger.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# -*- Mode: Python; test-case-name: morituri.test.test_result_logger -*-
|
||||
# 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 time
|
||||
|
||||
from morituri.common import common
|
||||
from morituri.configure import configure
|
||||
|
||||
class MorituriLogger(object):
|
||||
|
||||
def log(self, ripResult, epoch=time.time()):
|
||||
lines = self.logRip(ripResult, epoch=epoch)
|
||||
return '\n'.join(lines)
|
||||
|
||||
|
||||
def logRip(self, ripResult, epoch):
|
||||
|
||||
lines = []
|
||||
|
||||
### global
|
||||
|
||||
lines.append("Logfile created by: morituri %s" % configure.version)
|
||||
date = time.strftime("%b %d %H:%M:%S", time.localtime(epoch))
|
||||
lines.append("Logfile created on: %s" % date)
|
||||
lines.append("")
|
||||
|
||||
# album
|
||||
lines.append("Album: %s - %s" % (ripResult.artist, ripResult.title))
|
||||
lines.append("")
|
||||
|
||||
# drive
|
||||
lines.append(
|
||||
"Drive: vendor %s, model %s" % (
|
||||
ripResult.vendor, ripResult.model))
|
||||
lines.append("")
|
||||
|
||||
lines.append("Read offset correction: %d" %
|
||||
ripResult.offset)
|
||||
lines.append("")
|
||||
|
||||
# toc
|
||||
lines.append("Table of Contents:")
|
||||
lines.append("")
|
||||
lines.append(
|
||||
" Track | Start | Length")
|
||||
lines.append(
|
||||
" ------------------------------------------------")
|
||||
table = ripResult.toctable
|
||||
|
||||
|
||||
for t in table.tracks:
|
||||
start = t.getIndex(1).absolute
|
||||
length = table.getTrackLength(t.number)
|
||||
lines.append(
|
||||
" %2d | %6d - %s | %6d - %s" % (
|
||||
t.number,
|
||||
start, common.framesToMSF(start),
|
||||
length, common.framesToMSF(length)))
|
||||
|
||||
lines.append("")
|
||||
lines.append("")
|
||||
|
||||
### per-track
|
||||
for t in ripResult.tracks:
|
||||
lines.extend(self.trackLog(t))
|
||||
lines.append('')
|
||||
|
||||
return lines
|
||||
|
||||
def trackLog(self, trackResult):
|
||||
|
||||
lines = []
|
||||
|
||||
lines.append('Track %2d' % trackResult.number)
|
||||
lines.append('')
|
||||
lines.append(' Filename %s' % trackResult.filename)
|
||||
lines.append('')
|
||||
if trackResult.pregap:
|
||||
lines.append(' Pre-gap: %s' % common.framesToMSF(
|
||||
trackResult.pregap))
|
||||
lines.append('')
|
||||
|
||||
lines.append(' Peak level %.1f %%' % (trackResult.peak * 100.0))
|
||||
if trackResult.copycrc is not None:
|
||||
lines.append(' Copy CRC %08X' % trackResult.copycrc)
|
||||
if trackResult.testcrc is not None:
|
||||
lines.append(' Test CRC %08X' % trackResult.testcrc)
|
||||
if trackResult.testcrc == trackResult.copycrc:
|
||||
lines.append(' Copy OK')
|
||||
else:
|
||||
lines.append(" WARNING: CRCs don't match!")
|
||||
else:
|
||||
lines.append(" WARNING: no CRC check done")
|
||||
|
||||
if trackResult.accurip:
|
||||
if trackResult.accuripCRC == trackResult.accuripDatabaseCRC:
|
||||
lines.append(' Accurately ripped (confidence %d) [%08X]' % (
|
||||
trackResult.accuripDatabaseConfidence, trackResult.accuripCRC))
|
||||
else:
|
||||
lines.append(' Cannot be verified as accurate '
|
||||
'(confidence %d), [%08X], AccurateRip returned [%08x]' % (
|
||||
trackResult.accuripDatabaseConfidence,
|
||||
trackResult.accuripCRC, trackResult.accuripDatabaseCRC))
|
||||
else:
|
||||
lines.append(' Track not present in AccurateRip database')
|
||||
|
||||
return lines
|
||||
@@ -24,13 +24,16 @@ import os
|
||||
import sys
|
||||
import math
|
||||
|
||||
import cdio
|
||||
|
||||
import gobject
|
||||
gobject.threads_init()
|
||||
|
||||
import gst
|
||||
|
||||
from morituri.common import logcommand, task, checksum, common, accurip
|
||||
from morituri.common import logcommand, task, checksum, common, accurip, log
|
||||
from morituri.common import drive, encode
|
||||
from morituri.result import result
|
||||
from morituri.image import image, cue, table
|
||||
from morituri.program import cdrdao, cdparanoia
|
||||
|
||||
@@ -344,6 +347,14 @@ class Rip(logcommand.LogCommand):
|
||||
profile = encode.PROFILES[self.options.profile]()
|
||||
extension = profile.extension
|
||||
|
||||
# result
|
||||
res = result.RipResult()
|
||||
res.offset = int(self.options.offset)
|
||||
res.toctable = itable
|
||||
res.artist = metadata and metadata.artist or 'Unknown Artist'
|
||||
res.title = metadata and metadata.title or 'Unknown Title'
|
||||
_, res.vendor, res.model, __ = cdio.Device(device).get_hwinfo()
|
||||
|
||||
# check for hidden track one audio
|
||||
htoapath = None
|
||||
index = None
|
||||
@@ -389,11 +400,18 @@ class Rip(logcommand.LogCommand):
|
||||
for i, track in enumerate(itable.tracks):
|
||||
# FIXME: rip data tracks differently
|
||||
if not track.audio:
|
||||
print 'Skipping data track %d' % (i + 1, )
|
||||
# FIXME: make it work for now
|
||||
track.indexes[1].relative = 0
|
||||
continue
|
||||
|
||||
trackResult = result.TrackResult()
|
||||
res.tracks.append(trackResult)
|
||||
|
||||
path = getPath(outdir, self.options.track_template, metadata, i + 1) + '.' + extension
|
||||
trackResult.number = i + 1
|
||||
trackResult.filename = path
|
||||
|
||||
dirname = os.path.dirname(path)
|
||||
if not os.path.exists(dirname):
|
||||
os.makedirs(dirname)
|
||||
@@ -415,6 +433,10 @@ class Rip(logcommand.LogCommand):
|
||||
print 'Checksums match for track %d' % (i + 1)
|
||||
else:
|
||||
print 'ERROR: checksums did not match for track %d' % (i + 1)
|
||||
trackResult.testcrc = t.testchecksum
|
||||
trackResult.copycrc = t.copychecksum
|
||||
trackResult.peak = t.peak
|
||||
|
||||
print 'Peak level: %.2f %%' % (math.sqrt(t.peak) * 100.0, )
|
||||
|
||||
# overlay this rip onto the Table
|
||||
@@ -486,6 +508,9 @@ class Rip(logcommand.LogCommand):
|
||||
|
||||
# loop over tracks
|
||||
for i, csum in enumerate(cuetask.checksums):
|
||||
trackResult = res.tracks[i]
|
||||
trackResult.accuripCRC = csum
|
||||
|
||||
status = 'rip NOT accurate'
|
||||
|
||||
confidence = None
|
||||
@@ -501,8 +526,12 @@ class Rip(logcommand.LogCommand):
|
||||
"checksum %s" % (
|
||||
csum, i + 1, j + 1, response.checksums[i])
|
||||
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)"
|
||||
@@ -521,6 +550,14 @@ class Rip(logcommand.LogCommand):
|
||||
print "Track %2d: %s %s [%08x]%s" % (
|
||||
i + 1, status, c, csum, ar)
|
||||
|
||||
# write log file
|
||||
discName = getPath(outdir, self.options.disc_template, metadata, i)
|
||||
logPath = '%s.log' % discName
|
||||
logger = result.getLogger()
|
||||
handle = open(logPath, 'w')
|
||||
handle.write(logger.log(res))
|
||||
handle.close()
|
||||
|
||||
class CD(logcommand.LogCommand):
|
||||
summary = "handle CD's"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user