Skip to content

Commit aee0972

Browse files
committed
Add option to keep unverified tracks. Fixes #612.
Add a -u/--keep-unverified option that keeps the most recent attempt of ripping a track that failed verification. List the status of such tracks as "Copy NOT OK (unverified file kept)" Signed-off-by: leper <leper4@protonmail.com>
1 parent 420d81b commit aee0972

File tree

6 files changed

+51
-7
lines changed

6 files changed

+51
-7
lines changed

man/whipper-cd-rip.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ Options
7373
| continue ripping further tracks instead of giving up if a track can't be
7474
| ripped
7575
76+
| **-u** | **--keep-unverified**
77+
| keep unverified tracks instead of deleting the data if a track can't be
78+
| verified
79+
7680
Template schemes
7781
================
7882

whipper/command/cd.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,9 @@ class Rip(_CD):
231231
skipped_tracks = []
232232
# this holds tracks that fail to rip -
233233
# currently only used when the --keep-going option is used
234+
unverified_tracks = []
235+
# this holds tracks that failed to verify -
236+
# currently only used when the --keep-unverified option is used
234237
description = """
235238
Rips a CD.
236239
@@ -326,6 +329,11 @@ def add_arguments(self):
326329
help="continue ripping further tracks "
327330
"instead of giving up if a track "
328331
"can't be ripped")
332+
self.parser.add_argument('-u', '--keep-unverified',
333+
action='store_true',
334+
help="keep unverified (partial) results "
335+
"instead of deleleting the data if a track "
336+
"can't be verified")
329337

330338
def handle_arguments(self):
331339
self.options.output_directory = os.path.expanduser(
@@ -481,7 +489,8 @@ def _ripIfNotRipped(number):
481489
number,
482490
len(self.itable.tracks),
483491
extra),
484-
coverArtPath=self.coverArtPath)
492+
coverArtPath=self.coverArtPath,
493+
keep=self.options.keep_unverified)
485494
break
486495
# FIXME: catching too general exception (Exception)
487496
except Exception as e:
@@ -492,7 +501,15 @@ def _ripIfNotRipped(number):
492501
tries -= 1
493502
logger.critical('giving up on track %d after %d times',
494503
number, tries)
495-
if self.options.keep_going:
504+
if self.options.keep_unverified and not number == 0:
505+
logger.warning("track %d failed to rip. keeping unverified file.", number)
506+
logger.debug("adding %s to unverified_tracks",
507+
trackResult)
508+
self.unverified_tracks.append(trackResult)
509+
logger.debug("unverified_tracks = %s",
510+
self.unverified_tracks)
511+
trackResult.unverified = True
512+
elif self.options.keep_going:
496513
logger.warning("track %d failed to rip.", number)
497514
logger.debug("adding %s to skipped_tracks",
498515
trackResult)
@@ -504,7 +521,7 @@ def _ripIfNotRipped(number):
504521
raise RuntimeError("track can't be ripped. "
505522
"Rip attempts number is equal "
506523
"to {}".format(self.options.max_retries))
507-
if trackResult in self.skipped_tracks:
524+
if trackResult in (self.skipped_tracks or self.unverified_tracks):
508525
print("Skipping CRC comparison for track %d "
509526
"due to rip failure" % number)
510527
else:
@@ -572,6 +589,8 @@ def _ripIfNotRipped(number):
572589
logger.debug('writing m3u file for %r', discName)
573590
self.program.write_m3u(discName)
574591

592+
if len(self.unverified_tracks) > 0:
593+
self.program.unverified_tracks = self.unverified_tracks
575594
if len(self.skipped_tracks) > 0:
576595
logger.warning("the generated cue sheet references %d track(s) "
577596
"which failed to rip so the associated file(s) "
@@ -587,10 +606,15 @@ def _ripIfNotRipped(number):
587606

588607
self.program.writeLog(discName, self.logger)
589608

609+
# TODO: Return non-zero in case of unverified tracks?
590610
if len(self.skipped_tracks) > 0:
591611
logger.warning('%d tracks have been skipped from this rip attempt',
592612
len(self.skipped_tracks))
593613
return 5
614+
elif len(self.unverified_tracks) > 0:
615+
logger.warning('%d tracks could not be verified from this rip attempt',
616+
len(self.unverified_tracks))
617+
return 6
594618

595619

596620
class CD(BaseCommand):

whipper/common/program.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ class Program:
6060
outdir = None
6161
result = None
6262
skipped_tracks = None
63+
unverified_tracks = None
6364

6465
def __init__(self, config, record=False):
6566
"""
@@ -562,7 +563,7 @@ def verifyTrack(runner, trackResult):
562563
return ret
563564

564565
def ripTrack(self, runner, trackResult, offset, device, taglist,
565-
overread, what=None, coverArtPath=None):
566+
overread, what=None, coverArtPath=None, keep=False):
566567
"""
567568
Rip and store a track of the disc.
568569
@@ -606,7 +607,8 @@ def ripTrack(self, runner, trackResult, offset, device, taglist,
606607
device=device,
607608
taglist=taglist,
608609
what=what,
609-
coverArtPath=coverArtPath)
610+
coverArtPath=coverArtPath,
611+
keep=keep)
610612

611613
runner.run(t)
612614

whipper/program/cdparanoia.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,10 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
439439
_tmpwavpath = None
440440
_tmppath = None
441441

442+
_keep = False
443+
442444
def __init__(self, path, table, start, stop, overread, offset=0,
443-
device=None, taglist=None, what="track", coverArtPath=None):
445+
device=None, taglist=None, what="track", coverArtPath=None, keep=False):
444446
"""
445447
Init ReadVerifyTrackTask.
446448
@@ -471,6 +473,8 @@ def __init__(self, path, table, start, stop, overread, offset=0,
471473
os.close(fd)
472474
self._tmpwavpath = tmppath
473475

476+
self._keep = keep
477+
474478
from whipper.common import checksum
475479

476480
self.tasks = []
@@ -547,9 +551,11 @@ def stop(self):
547551
# delete the unencoded file
548552
os.unlink(self._tmpwavpath)
549553

550-
if not self.exception:
554+
if not self.exception or self._keep:
551555
try:
552556
logger.debug('moving to final path %r', self.path)
557+
if self.exception:
558+
logger.debug('keeping unverified result')
553559
shutil.move(self._tmppath, self.path)
554560
# FIXME: catching too general exception (Exception)
555561
except Exception as e:

whipper/result/logger.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class WhipperLogger(result.Logger):
1616
_inARDatabase = 0
1717
_errors = False
1818
_skippedTracks = False
19+
_unverifiedTracks = False
1920

2021
def log(self, ripResult, epoch=time.time()):
2122
"""Return logfile as string."""
@@ -142,6 +143,8 @@ def logRip(self, ripResult, epoch):
142143
message = "There were errors"
143144
elif self._skippedTracks:
144145
message = "Some tracks were not ripped (skipped)"
146+
elif self._unverifiedTracks:
147+
message = "Some tracks could not be verified (but were kept)"
145148
else:
146149
message = "No errors occurred"
147150
data["Health status"] = message
@@ -250,6 +253,10 @@ def trackLog(self, trackResult):
250253
if trackResult.skipped:
251254
track["Status"] = "Track not ripped (skipped)"
252255
self._skippedTracks = True
256+
# Check if the track has failed verification, but has been kept
257+
elif trackResult.unverified:
258+
track["Status"] = "Copy NOT OK (unverified file kept)"
259+
self._unverifiedTracks = True
253260
# Check if Test & Copy CRCs are equal
254261
elif trackResult.testcrc == trackResult.copycrc:
255262
track["Status"] = "Copy OK"

whipper/result/result.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class TrackResult:
3939
AR = None
4040
classVersion = 3
4141
skipped = False
42+
unverified = False
4243

4344
def __init__(self):
4445
"""

0 commit comments

Comments
 (0)