Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions man/whipper-cd-rip.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ Options
| continue ripping further tracks instead of giving up if a track can't be
| ripped

| **-u** | **--keep-unverified**
| keep unverified tracks instead of deleting the data if a track can't be
| verified

Template schemes
================

Expand Down
29 changes: 26 additions & 3 deletions whipper/command/cd.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ class Rip(_CD):
skipped_tracks = []
# this holds tracks that fail to rip -
# currently only used when the --keep-going option is used
unverified_tracks = []
# this holds tracks that failed to verify -
# currently only used when the --keep-unverified option is used
description = """
Rips a CD.

Expand Down Expand Up @@ -326,6 +329,11 @@ def add_arguments(self):
help="continue ripping further tracks "
"instead of giving up if a track "
"can't be ripped")
self.parser.add_argument('-u', '--keep-unverified',
action='store_true',
help="keep unverified (partial) results "
"instead of deleleting the data if a track "
"can't be verified")

def handle_arguments(self):
self.options.output_directory = os.path.expanduser(
Expand Down Expand Up @@ -481,7 +489,8 @@ def _ripIfNotRipped(number):
number,
len(self.itable.tracks),
extra),
coverArtPath=self.coverArtPath)
coverArtPath=self.coverArtPath,
keep=self.options.keep_unverified)
break
# FIXME: catching too general exception (Exception)
except Exception as e:
Expand All @@ -492,7 +501,15 @@ def _ripIfNotRipped(number):
tries -= 1
logger.critical('giving up on track %d after %d times',
number, tries)
if self.options.keep_going:
if self.options.keep_unverified and not number == 0:
logger.warning("track %d failed to rip. keeping unverified file.", number)
logger.debug("adding %s to unverified_tracks",
trackResult)
self.unverified_tracks.append(trackResult)
logger.debug("unverified_tracks = %s",
self.unverified_tracks)
trackResult.unverified = True
elif self.options.keep_going:
logger.warning("track %d failed to rip.", number)
logger.debug("adding %s to skipped_tracks",
trackResult)
Expand All @@ -504,7 +521,7 @@ def _ripIfNotRipped(number):
raise RuntimeError("track can't be ripped. "
"Rip attempts number is equal "
"to {}".format(self.options.max_retries))
if trackResult in self.skipped_tracks:
if trackResult in (self.skipped_tracks or self.unverified_tracks):
print("Skipping CRC comparison for track %d "
"due to rip failure" % number)
else:
Expand Down Expand Up @@ -572,6 +589,8 @@ def _ripIfNotRipped(number):
logger.debug('writing m3u file for %r', discName)
self.program.write_m3u(discName)

if len(self.unverified_tracks) > 0:
self.program.unverified_tracks = self.unverified_tracks
if len(self.skipped_tracks) > 0:
logger.warning("the generated cue sheet references %d track(s) "
"which failed to rip so the associated file(s) "
Expand All @@ -591,6 +610,10 @@ def _ripIfNotRipped(number):
logger.warning('%d tracks have been skipped from this rip attempt',
len(self.skipped_tracks))
return 5
elif len(self.unverified_tracks) > 0:
logger.warning('%d tracks could not be verified from this rip attempt',
len(self.unverified_tracks))
return 6


class CD(BaseCommand):
Expand Down
6 changes: 4 additions & 2 deletions whipper/common/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Program:
outdir = None
result = None
skipped_tracks = None
unverified_tracks = None

def __init__(self, config, record=False):
"""
Expand Down Expand Up @@ -562,7 +563,7 @@ def verifyTrack(runner, trackResult):
return ret

def ripTrack(self, runner, trackResult, offset, device, taglist,
overread, what=None, coverArtPath=None):
overread, what=None, coverArtPath=None, keep=False):
"""
Rip and store a track of the disc.

Expand Down Expand Up @@ -606,7 +607,8 @@ def ripTrack(self, runner, trackResult, offset, device, taglist,
device=device,
taglist=taglist,
what=what,
coverArtPath=coverArtPath)
coverArtPath=coverArtPath,
keep=keep)

runner.run(t)

Expand Down
10 changes: 8 additions & 2 deletions whipper/program/cdparanoia.py
Original file line number Diff line number Diff line change
Expand Up @@ -439,8 +439,10 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
_tmpwavpath = None
_tmppath = None

_keep = False

def __init__(self, path, table, start, stop, overread, offset=0,
device=None, taglist=None, what="track", coverArtPath=None):
device=None, taglist=None, what="track", coverArtPath=None, keep=False):
"""
Init ReadVerifyTrackTask.

Expand Down Expand Up @@ -471,6 +473,8 @@ def __init__(self, path, table, start, stop, overread, offset=0,
os.close(fd)
self._tmpwavpath = tmppath

self._keep = keep

from whipper.common import checksum

self.tasks = []
Expand Down Expand Up @@ -547,9 +551,11 @@ def stop(self):
# delete the unencoded file
os.unlink(self._tmpwavpath)

if not self.exception:
if not self.exception or self._keep:
try:
logger.debug('moving to final path %r', self.path)
if self.exception:
logger.debug('keeping unverified result')
shutil.move(self._tmppath, self.path)
# FIXME: catching too general exception (Exception)
except Exception as e:
Expand Down
7 changes: 7 additions & 0 deletions whipper/result/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class WhipperLogger(result.Logger):
_inARDatabase = 0
_errors = False
_skippedTracks = False
_unverifiedTracks = False

def log(self, ripResult, epoch=time.time()):
"""Return logfile as string."""
Expand Down Expand Up @@ -142,6 +143,8 @@ def logRip(self, ripResult, epoch):
message = "There were errors"
elif self._skippedTracks:
message = "Some tracks were not ripped (skipped)"
elif self._unverifiedTracks:
message = "Some tracks could not be verified (but were kept)"
else:
message = "No errors occurred"
data["Health status"] = message
Expand Down Expand Up @@ -250,6 +253,10 @@ def trackLog(self, trackResult):
if trackResult.skipped:
track["Status"] = "Track not ripped (skipped)"
self._skippedTracks = True
# Check if the track has failed verification, but has been kept
elif trackResult.unverified:
track["Status"] = "Copy NOT OK (unverified file kept)"
self._unverifiedTracks = True
# Check if Test & Copy CRCs are equal
elif trackResult.testcrc == trackResult.copycrc:
track["Status"] = "Copy OK"
Expand Down
1 change: 1 addition & 0 deletions whipper/result/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class TrackResult:
AR = None
classVersion = 3
skipped = False
unverified = False

def __init__(self):
"""
Expand Down