Solve all flake8 warnings (#163)

Whipper is now fully PEP8 compliant.
Revised version which includes all the changes suggested by Freso.
This commit is contained in:
JoeLametta
2017-05-31 23:09:36 +02:00
committed by GitHub
parent b331f53b47
commit b6fb7e8a86
49 changed files with 614 additions and 539 deletions

View File

@@ -26,6 +26,7 @@ from whipper.common import accurip
import logging
logger = logging.getLogger(__name__)
class Show(BaseCommand):
summary = "show accuraterip data"
description = """
@@ -52,7 +53,6 @@ retrieves and display accuraterip data from the given URL
"Warning: response %d has %d tracks instead of %d\n" % (
i, r.trackCount, count))
# checksum and confidence by track
for track in range(count):
sys.stdout.write("Track %d:\n" % (track + 1))

View File

@@ -24,6 +24,7 @@ logger = logging.getLogger(__name__)
# A: The prefix matching prevents passing '-h' (and possibly other
# options) to the child command.
class BaseCommand():
"""
A base command class for whipper commands.

View File

@@ -24,10 +24,8 @@ import glob
import urllib2
import socket
import sys
import logging
import gobject
gobject.threads_init()
from whipper.command.basecommand import BaseCommand
from whipper.common import (
accurip, common, config, drive, program, task
@@ -35,7 +33,8 @@ from whipper.common import (
from whipper.program import cdrdao, cdparanoia, utils
from whipper.result import result
import logging
gobject.threads_init()
logger = logging.getLogger(__name__)
@@ -81,24 +80,26 @@ class _CD(BaseCommand):
def add_arguments(parser):
# FIXME: have a cache of these pickles somewhere
parser.add_argument('-T', '--toc-pickle',
action="store", dest="toc_pickle",
help="pickle to use for reading and writing the TOC")
action="store", dest="toc_pickle",
help="pickle to use for reading and "
"writing the TOC")
parser.add_argument('-R', '--release-id',
action="store", dest="release_id",
help="MusicBrainz release id to match to (if there are multiple)")
action="store", dest="release_id",
help="MusicBrainz release id to match to "
"(if there are multiple)")
parser.add_argument('-p', '--prompt',
action="store_true", dest="prompt",
help="Prompt if there are multiple matching releases")
action="store_true", dest="prompt",
help="Prompt if there are multiple "
"matching releases")
parser.add_argument('-c', '--country',
action="store", dest="country",
help="Filter releases by country")
action="store", dest="country",
help="Filter releases by country")
def do(self):
self.config = config.Config()
self.program = program.Program(self.config,
record=self.options.record,
stdout=sys.stdout)
record=self.options.record,
stdout=sys.stdout)
self.runner = task.SyncRunner()
# if the device is mounted (data session), unmount it
@@ -110,8 +111,8 @@ class _CD(BaseCommand):
# first, read the normal TOC, which is fast
self.ittoc = self.program.getFastToc(self.runner,
self.options.toc_pickle,
self.device)
self.options.toc_pickle,
self.device)
# already show us some info based on this
self.program.getRipResult(self.ittoc.getCDDBDiscId())
@@ -120,13 +121,14 @@ class _CD(BaseCommand):
sys.stdout.write("MusicBrainz disc id %s\n" % self.mbdiscid)
sys.stdout.write("MusicBrainz lookup URL %s\n" %
self.ittoc.getMusicBrainzSubmitURL())
self.ittoc.getMusicBrainzSubmitURL())
self.program.metadata = self.program.getMusicBrainz(self.ittoc,
self.mbdiscid,
release=self.options.release_id,
country=self.options.country,
prompt=self.options.prompt)
self.program.metadata = (
self.program.getMusicBrainz(self.ittoc, self.mbdiscid,
release=self.options.release_id,
country=self.options.country,
prompt=self.options.prompt)
)
if not self.program.metadata:
# fall back to FreeDB for lookup
@@ -153,8 +155,9 @@ class _CD(BaseCommand):
# now, read the complete index table, which is slower
self.itable = self.program.getTable(self.runner,
self.ittoc.getCDDBDiscId(),
self.ittoc.getMusicBrainzDiscId(), self.device, offset)
self.ittoc.getCDDBDiscId(),
self.ittoc.getMusicBrainzDiscId(),
self.device, offset)
assert self.itable.getCDDBDiscId() == self.ittoc.getCDDBDiscId(), \
"full table's id %s differs from toc id %s" % (
@@ -220,6 +223,7 @@ class Info(_CD):
def add_arguments(self):
_CD.add_arguments(self.parser)
class Rip(_CD):
summary = "rip CD"
# see whipper.common.program.Program.getPath for expansion
@@ -247,49 +251,62 @@ Log files will log the path to tracks relative to this directory.
try:
default_offset = config.Config().getReadOffset(*info)
sys.stdout.write("Using configured read offset %d\n" %
default_offset)
default_offset)
except KeyError:
pass
_CD.add_arguments(self.parser)
self.parser.add_argument('-L', '--logger',
action="store", dest="logger", default='whipper',
help="logger to use (choose from '" + "', '".join(loggers) + "')")
action="store", dest="logger",
default='whipper',
help="logger to use (choose from '"
"', '".join(loggers) + "')")
# FIXME: get from config
self.parser.add_argument('-o', '--offset',
action="store", dest="offset", default=default_offset,
help="sample read offset")
action="store", dest="offset",
default=default_offset,
help="sample read offset")
self.parser.add_argument('-x', '--force-overread',
action="store_true", dest="overread", default=False,
help="Force overreading into the lead-out portion of the disc. "
"Works only if the patched cdparanoia package is installed "
"and the drive supports this feature. ")
action="store_true", dest="overread",
default=False,
help="Force overreading into the "
"lead-out portion of the disc. Works only "
"if the patched cdparanoia package is "
"installed and the drive "
"supports this feature. ")
self.parser.add_argument('-O', '--output-directory',
action="store", dest="output_directory",
default=os.path.relpath(os.getcwd()),
help="output directory; will be included in file paths in log")
action="store", dest="output_directory",
default=os.path.relpath(os.getcwd()),
help="output directory; will be included "
"in file paths in log")
self.parser.add_argument('-W', '--working-directory',
action="store", dest="working_directory",
help="working directory; whipper will change to this directory "
"and files will be created relative to it when not absolute")
action="store", dest="working_directory",
help="working directory; whipper will "
"change to this directory "
"and files will be created relative to "
"it when not absolute")
self.parser.add_argument('--track-template',
action="store", dest="track_template",
default=DEFAULT_TRACK_TEMPLATE,
help="template for track file naming (default default)")
action="store", dest="track_template",
default=DEFAULT_TRACK_TEMPLATE,
help="template for track file naming "
"(default default)")
self.parser.add_argument('--disc-template',
action="store", dest="disc_template",
default=DEFAULT_DISC_TEMPLATE,
help="template for disc file naming (default default)")
action="store", dest="disc_template",
default=DEFAULT_DISC_TEMPLATE,
help="template for disc file naming "
"(default default)")
self.parser.add_argument('-U', '--unknown',
action="store_true", dest="unknown",
help="whether to continue ripping if the CD is unknown",
default=False)
action="store_true", dest="unknown",
help="whether to continue ripping if "
"the CD is unknown", default=False)
def handle_arguments(self):
self.options.output_directory = os.path.expanduser(self.options.output_directory)
self.options.output_directory = os.path.expanduser(
self.options.output_directory)
self.options.track_template = self.options.track_template.decode('utf-8')
self.options.track_template = self.options.track_template.decode(
'utf-8')
self.options.disc_template = self.options.disc_template.decode('utf-8')
if self.options.offset is None:
@@ -300,9 +317,9 @@ Log files will log the path to tracks relative to this directory.
"also be specified at runtime using the "
"'--offset=value' argument")
if self.options.working_directory is not None:
self.options.working_directory = os.path.expanduser(self.options.working_directory)
self.options.working_directory = os.path.expanduser(
self.options.working_directory)
if self.options.logger:
try:
@@ -312,7 +329,6 @@ Log files will log the path to tracks relative to this directory.
logger.critical(msg)
raise ValueError(msg)
def doCommand(self):
self.program.setWorkingDirectory(self.options.working_directory)
self.program.outdir = self.options.output_directory.decode('utf-8')
@@ -320,16 +336,17 @@ Log files will log the path to tracks relative to this directory.
self.program.result.overread = self.options.overread
self.program.result.logger = self.options.logger
### write disc files
# write disc files
disambiguate = False
while True:
discName = self.program.getPath(self.program.outdir,
self.options.disc_template, self.mbdiscid, 0,
disambiguate=disambiguate)
self.options.disc_template,
self.mbdiscid, 0,
disambiguate=disambiguate)
dirname = os.path.dirname(discName)
if os.path.exists(dirname):
sys.stdout.write("Output directory %s already exists\n" %
dirname.encode('utf-8'))
dirname.encode('utf-8'))
logs = glob.glob(os.path.join(dirname, '*.log'))
if logs:
sys.stdout.write(
@@ -344,14 +361,13 @@ Log files will log the path to tracks relative to this directory.
else:
sys.stdout.write("Creating output directory %s\n" %
dirname.encode('utf-8'))
dirname.encode('utf-8'))
os.makedirs(dirname)
break
# FIXME: say when we're continuing a rip
# FIXME: disambiguate if the pre-existing rip is different
# FIXME: turn this into a method
def ripIfNotRipped(number):
@@ -363,12 +379,12 @@ Log files will log the path to tracks relative to this directory.
self.program.result.tracks.append(trackResult)
else:
logger.debug('ripIfNotRipped have trackresult, path %r' %
trackResult.filename)
trackResult.filename)
path = self.program.getPath(self.program.outdir,
self.options.track_template,
self.mbdiscid, number,
disambiguate=disambiguate) \
self.options.track_template,
self.mbdiscid, number,
disambiguate=disambiguate) \
+ '.' + 'flac'
logger.debug('ripIfNotRipped: path %r' % path)
trackResult.number = number
@@ -378,7 +394,9 @@ Log files will log the path to tracks relative to this directory.
if number > 0:
trackResult.pregap = self.itable.tracks[number - 1].getPregap()
trackResult.pre_emphasis = self.itable.tracks[number - 1].pre_emphasis
trackResult.pre_emphasis = (
self.itable.tracks[number - 1].pre_emphasis
)
# FIXME: optionally allow overriding reripping
if os.path.exists(path):
@@ -411,19 +429,21 @@ Log files will log the path to tracks relative to this directory.
os.path.basename(path).encode('utf-8')))
try:
logger.debug('ripIfNotRipped: track %d, try %d',
number, tries)
number, tries)
self.program.ripTrack(self.runner, trackResult,
offset=int(self.options.offset),
device=self.device,
taglist=self.program.getTagList(number),
overread=self.options.overread,
what='track %d of %d%s' % (
number, len(self.itable.tracks), extra))
offset=int(self.options.offset),
device=self.device,
taglist=self.program.getTagList(
number),
overread=self.options.overread,
what='track %d of %d%s' % (
number,
len(self.itable.tracks),
extra))
break
except Exception, e:
logger.debug('Got exception %r on try %d',
e, tries)
e, tries)
if tries == MAX_TRIES:
logger.critical('Giving up on track %d after %d times' % (
@@ -433,39 +453,43 @@ Log files will log the path to tracks relative to this directory.
"Rip attempts number is equal to 'MAX_TRIES'")
if trackResult.testcrc == trackResult.copycrc:
sys.stdout.write('Checksums match for track %d\n' %
number)
number)
else:
sys.stdout.write(
'ERROR: checksums did not match for track %d\n' %
number)
raise
sys.stdout.write('Peak level: {:.2%} \n'.format(trackResult.peak))
sys.stdout.write(
'Peak level: {:.2%} \n'.format(trackResult.peak))
sys.stdout.write('Rip quality: {:.2%}\n'.format(trackResult.quality))
sys.stdout.write(
'Rip quality: {:.2%}\n'.format(trackResult.quality))
# overlay this rip onto the Table
if number == 0:
# HTOA goes on index 0 of track 1
# ignore silence in PREGAP
if trackResult.peak <= SILENT:
logger.debug('HTOA peak %r is below SILENT threshold, disregarding', trackResult.peak)
logger.debug(
'HTOA peak %r is below SILENT '
'threshold, disregarding', trackResult.peak)
self.itable.setFile(1, 0, None,
self.ittoc.getTrackStart(1), number)
self.ittoc.getTrackStart(1), number)
logger.debug('Unlinking %r', trackResult.filename)
os.unlink(trackResult.filename)
trackResult.filename = None
sys.stdout.write('HTOA discarded, contains digital silence\n')
sys.stdout.write(
'HTOA discarded, contains digital silence\n')
else:
self.itable.setFile(1, 0, trackResult.filename,
self.ittoc.getTrackStart(1), number)
self.ittoc.getTrackStart(1), number)
else:
self.itable.setFile(number, 1, trackResult.filename,
self.ittoc.getTrackLength(number), number)
self.ittoc.getTrackLength(number), number)
self.program.saveRipResult()
# check for hidden track one audio
htoapath = None
htoa = self.program.getHTOA()
@@ -473,7 +497,7 @@ Log files will log the path to tracks relative to this directory.
start, stop = htoa
sys.stdout.write(
'Found Hidden Track One Audio from frame %d to %d\n' % (
start, stop))
start, stop))
# rip it
ripIfNotRipped(0)
@@ -484,17 +508,18 @@ Log files will log the path to tracks relative to this directory.
if not track.audio:
sys.stdout.write(
'WARNING: skipping data track %d, not implemented\n' % (
i + 1, ))
i + 1, ))
# FIXME: make it work for now
track.indexes[1].relative = 0
continue
ripIfNotRipped(i + 1)
### write disc files
# write disc files
discName = self.program.getPath(self.program.outdir,
self.options.disc_template, self.mbdiscid, 0,
disambiguate=disambiguate)
self.options.disc_template,
self.mbdiscid, 0,
disambiguate=disambiguate)
dirname = os.path.dirname(discName)
if not os.path.exists(dirname):
os.makedirs(dirname)
@@ -516,20 +541,22 @@ Log files will log the path to tracks relative to this directory.
u = '%s\n' % targetPath
handle.write(u.encode('utf-8'))
if htoapath:
writeFile(handle, htoapath,
self.itable.getTrackStart(1) / common.FRAMES_PER_SECOND)
self.itable.getTrackStart(1) / common.FRAMES_PER_SECOND)
for i, track in enumerate(self.itable.tracks):
if not track.audio:
continue
path = self.program.getPath(self.program.outdir,
self.options.track_template, self.mbdiscid, i + 1,
disambiguate=disambiguate) + '.' + 'flac'
self.options.track_template,
self.mbdiscid, i + 1,
disambiguate=disambiguate
) + '.' + 'flac'
writeFile(handle, path,
self.itable.getTrackLength(i + 1) / common.FRAMES_PER_SECOND)
(self.itable.getTrackLength(i + 1) /
common.FRAMES_PER_SECOND))
handle.close()
@@ -556,14 +583,13 @@ Log files will log the path to tracks relative to this directory.
if responses:
sys.stdout.write('%d AccurateRip reponses found\n' %
len(responses))
len(responses))
if responses[0].cddbDiscId != self.itable.getCDDBDiscId():
sys.stdout.write(
"AccurateRip response discid different: %s\n" %
responses[0].cddbDiscId)
self.program.verifyImage(self.runner, responses)
sys.stdout.write("\n".join(

View File

@@ -28,6 +28,7 @@ from whipper.result import result
import logging
logger = logging.getLogger(__name__)
class RCCue(BaseCommand):
summary = "write a cue file for the cached result"
description = summary
@@ -148,9 +149,6 @@ class Encode(BaseCommand):
description = summary
def add_arguments(self):
# here to avoid import gst eating our options
from whipper.common import encode
self.parser.add_argument('input', action='store',
help="audio file to encode")
self.parser.add_argument('output', nargs='?', action='store',
@@ -174,8 +172,8 @@ class Encode(BaseCommand):
runner = task.SyncRunner()
logger.debug('Encoding %s to %s',
fromPath.encode('utf-8'),
toPath.encode('utf-8'))
fromPath.encode('utf-8'),
toPath.encode('utf-8'))
encodetask = encode.FlacEncodeTask(fromPath, toPath)
runner.run(encodetask)
@@ -244,7 +242,7 @@ Example disc id: KnpGsLhvH.lPrNc1PBL21lb9Bg4-"""
sys.stdout.write('- Release %d:\n' % (i + 1, ))
sys.stdout.write(' Artist: %s\n' % md.artist.encode('utf-8'))
sys.stdout.write(' Title: %s\n' % md.title.encode('utf-8'))
sys.stdout.write(' Type: %s\n' % md.releaseType.encode('utf-8'))
sys.stdout.write(' Type: %s\n' % md.releaseType.encode('utf-8')) # noqa: E501
sys.stdout.write(' URL: %s\n' % md.url)
sys.stdout.write(' Tracks: %d\n' % len(md.tracks))
if md.catalogNumber:

View File

@@ -28,9 +28,10 @@ from whipper.program import cdparanoia
import logging
logger = logging.getLogger(__name__)
class Analyze(BaseCommand):
summary = "analyze caching behaviour of drive"
description = """Determine whether cdparanoia can defeat the audio cache of the drive."""
description = """Determine whether cdparanoia can defeat the audio cache of the drive.""" # noqa: E501
device_option = True
def do(self):
@@ -51,14 +52,15 @@ class Analyze(BaseCommand):
info = drive.getDeviceInfo(self.options.device)
if not info:
sys.stdout.write('Drive caching behaviour not saved: could not get device info (requires pycdio).\n')
sys.stdout.write('Drive caching behaviour not saved:'
'could not get device info (requires pycdio).\n')
return
sys.stdout.write(
'Adding drive cache behaviour to configuration file.\n')
config.Config().setDefeatsCache(info[0], info[1], info[2],
t.defeatsCache)
config.Config().setDefeatsCache(
info[0], info[1], info[2], t.defeatsCache)
class List(BaseCommand):
@@ -77,7 +79,7 @@ class List(BaseCommand):
return
try:
import cdio as _
import cdio as _ # noqa: F401 (TODO: fix it in a separate PR?)
except ImportError:
sys.stdout.write(
'Install pycdio for vendor/model/release detection.\n')
@@ -87,7 +89,7 @@ class List(BaseCommand):
vendor, model, release = drive.getDeviceInfo(path)
sys.stdout.write(
"drive: %s, vendor: %s, model: %s, release: %s\n" % (
path, vendor, model, release))
path, vendor, model, release))
try:
offset = self.config.getReadOffset(
@@ -95,8 +97,10 @@ class List(BaseCommand):
sys.stdout.write(
" Configured read offset: %d\n" % offset)
except KeyError:
sys.stdout.write(
" No read offset found. Run 'whipper offset find'\n")
# Note spaces at the beginning for pretty terminal output
sys.stdout.write(" "
"No read offset found. "
"Run 'whipper offset find'\n")
try:
defeats = self.config.getDefeatsCache(
@@ -108,7 +112,6 @@ class List(BaseCommand):
" Unknown whether audio cache can be defeated. "
"Run 'whipper drive analyze'\n")
if not paths:
sys.stdout.write('No drives found.\n')

View File

@@ -72,11 +72,11 @@ Retags the image from the given .cue files with tags obtained from MusicBrainz.
sys.stdout.write('MusicBrainz disc id is %s\n' % mbdiscid)
sys.stdout.write("MusicBrainz lookup URL %s\n" %
cueImage.table.getMusicBrainzSubmitURL())
cueImage.table.getMusicBrainzSubmitURL())
prog.metadata = prog.getMusicBrainz(cueImage.table, mbdiscid,
release=self.options.release_id,
country=self.options.country,
prompt=self.options.prompt)
release=self.options.release_id, # noqa: E501
country=self.options.country,
prompt=self.options.prompt)
if not prog.metadata:
print 'Not in MusicBrainz database, skipping'

View File

@@ -17,6 +17,7 @@ from whipper.program.utils import eject_device
import logging
logger = logging.getLogger(__name__)
def main():
# set user agent
musicbrainzngs.set_useragent("whipper", whipper.__version__,
@@ -47,7 +48,7 @@ def main():
if isinstance(e.exception, common.EmptyError):
logger.debug("EmptyError: %r", str(e.exception))
sys.stderr.write('whipper: error: Could not create encoded file.\n')
sys.stderr.write('whipper: error: Could not create encoded file.\n') # noqa: E501
return 255
# in python3 we can instead do `raise e.exception` as that would show
@@ -56,6 +57,7 @@ def main():
return 255
return ret if ret else 0
class Whipper(BaseCommand):
description = """whipper is a CD ripping utility focusing on accuracy over speed.
@@ -74,18 +76,20 @@ You can get help on subcommands by using the -h option to the subcommand.
def add_arguments(self):
self.parser.add_argument('-R', '--record',
action='store_true', dest='record',
help="record API requests for playback")
action='store_true', dest='record',
help="record API requests for playback")
self.parser.add_argument('-v', '--version',
action="store_true", dest="version",
help="show version information")
action="store_true", dest="version",
help="show version information")
self.parser.add_argument('-h', '--help',
action="store_true", dest="help",
help="show this help message and exit")
action="store_true", dest="help",
help="show this help message and exit")
self.parser.add_argument('-e', '--eject',
action="store", dest="eject", default="always",
choices=('never', 'failure', 'success', 'always'),
help="when to eject disc (default: always)")
action="store", dest="eject",
default="always",
choices=('never', 'failure',
'success', 'always'),
help="when to eject disc (default: always)")
def handle_arguments(self):
if self.options.help:

View File

@@ -22,19 +22,17 @@ import argparse
import os
import sys
import tempfile
import logging
import gobject
gobject.threads_init()
from whipper.command.basecommand import BaseCommand
from whipper.common import accurip, common, config, drive, program
from whipper.common import accurip, common, config, drive
from whipper.common import task as ctask
from whipper.program import cdrdao, cdparanoia, utils
from whipper.common import checksum
from whipper.extern.task import task
import logging
gobject.threads_init()
logger = logging.getLogger(__name__)
# see http://www.accuraterip.com/driveoffsets.htm
@@ -117,7 +115,7 @@ CD in the AccurateRip database."""
if responses[0].cddbDiscId != table.getCDDBDiscId():
logger.warning("AccurateRip response discid different: %s",
responses[0].cddbDiscId)
responses[0].cddbDiscId)
# now rip the first track at various offsets, calculating AccurateRip
# CRC, and matching it against the retrieved ones
@@ -137,7 +135,7 @@ CD in the AccurateRip database."""
# let MissingDependency fall through
if isinstance(e.exception,
common.MissingDependencyException):
common.MissingDependencyException):
raise e
if isinstance(e.exception, cdparanoia.FileSizeError):
@@ -159,7 +157,7 @@ CD in the AccurateRip database."""
logger.debug('MATCHED against response %d' % i)
sys.stdout.write(
'Offset of device is likely %d, confirming ...\n' %
offset)
offset)
# now try and rip all other tracks as well, except for the
# last one (to avoid readers that can't do overread
@@ -185,7 +183,7 @@ CD in the AccurateRip database."""
else:
sys.stdout.write(
'Only %d of %d tracks matched, continuing ...\n' % (
count, len(table.tracks)))
count, len(table.tracks)))
sys.stdout.write('No matching offset found.\n')
sys.stdout.write('Consider trying again with a different disc.\n')
@@ -201,16 +199,19 @@ CD in the AccurateRip database."""
os.close(fd)
t = cdparanoia.ReadTrackTask(path, table,
table.getTrackStart(track), table.getTrackEnd(track),
overread=False, offset=offset, device=self.options.device)
table.getTrackStart(
track), table.getTrackEnd(track),
overread=False, offset=offset,
device=self.options.device)
t.description = 'Ripping track %d with read offset %d' % (
track, offset)
runner.run(t)
# TODO MW: Update this to also use the v2 checksum(s)
t = checksum.FastAccurateRipChecksumTask(path, trackNumber=track,
trackCount=len(table.tracks), wave=True, v2=False)
t = checksum.FastAccurateRipChecksumTask(path,
trackNumber=track,
trackCount=len(table.tracks),
wave=True, v2=False)
runner.run(t)
os.unlink(path)
@@ -218,17 +219,19 @@ CD in the AccurateRip database."""
def _foundOffset(self, device, offset):
sys.stdout.write('\nRead offset of device is: %d.\n' %
offset)
offset)
info = drive.getDeviceInfo(device)
if not info:
sys.stdout.write('Offset not saved: could not get device info (requires pycdio).\n')
sys.stdout.write(
'Offset not saved: could not get '
'device info (requires pycdio).\n')
return
sys.stdout.write('Adding read offset to configuration file.\n')
config.Config().setReadOffset(info[0], info[1], info[2],
offset)
offset)
class Offset(BaseCommand):