Convert docstrings to reStructuredText
This commit also includes: - whitespace / code formatting fixes - slight syntax related changes: except <exception_name>, e -> except <exception_name> as e - 3 pointless instructions instances have been rewritten [sorted] (spotted by semi-automatic check) The unrelated changes shouldn't have any real impact on whipper's behaviour.
This commit is contained in:
@@ -37,13 +37,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FileSizeError(Exception):
|
||||
"""The given path does not have the expected size."""
|
||||
|
||||
message = None
|
||||
|
||||
"""
|
||||
The given path does not have the expected size.
|
||||
"""
|
||||
|
||||
def __init__(self, path, message):
|
||||
self.args = (path, message)
|
||||
self.path = path
|
||||
@@ -51,9 +48,7 @@ class FileSizeError(Exception):
|
||||
|
||||
|
||||
class ReturnCodeError(Exception):
|
||||
"""
|
||||
The program had a non-zero return code.
|
||||
"""
|
||||
"""The program had a non-zero return code."""
|
||||
|
||||
def __init__(self, returncode):
|
||||
self.args = (returncode, )
|
||||
@@ -79,6 +74,22 @@ _ERROR_RE = re.compile("^scsi_read error:")
|
||||
|
||||
|
||||
class ProgressParser:
|
||||
"""Parse cdparanoia's output information.
|
||||
|
||||
:cvar read:
|
||||
:vartype read:
|
||||
:cvar wrote:
|
||||
:vartype wrote:
|
||||
:cvar errors:
|
||||
:vartype errors:
|
||||
:ivar reads:
|
||||
:vartype reads:
|
||||
:ivar start: first frame to rip.
|
||||
:vartype start: int
|
||||
:ivar stop: last frame to rip (inclusive).
|
||||
:vartype stop: int
|
||||
"""
|
||||
|
||||
read = 0 # last [read] frame
|
||||
wrote = 0 # last [wrote] frame
|
||||
errors = 0 # count of number of scsi errors
|
||||
@@ -87,12 +98,6 @@ class ProgressParser:
|
||||
reads = 0 # total number of reads
|
||||
|
||||
def __init__(self, start, stop):
|
||||
"""
|
||||
@param start: first frame to rip
|
||||
@type start: int
|
||||
@param stop: last frame to rip (inclusive)
|
||||
@type stop: int
|
||||
"""
|
||||
self.start = start
|
||||
self.stop = stop
|
||||
|
||||
@@ -102,8 +107,10 @@ class ProgressParser:
|
||||
self._reads = {} # read count for each sector
|
||||
|
||||
def parse(self, line):
|
||||
"""
|
||||
Parse a line.
|
||||
"""Parse a line.
|
||||
|
||||
:param line:
|
||||
:type line:
|
||||
"""
|
||||
m = _PROGRESS_RE.search(line)
|
||||
if m:
|
||||
@@ -184,9 +191,12 @@ class ProgressParser:
|
||||
self.wrote = frameOffset
|
||||
|
||||
def getTrackQuality(self):
|
||||
"""
|
||||
Each frame gets read twice.
|
||||
"""Each frame gets read twice.
|
||||
|
||||
More than two reads for a frame reduce track quality.
|
||||
|
||||
:returns:
|
||||
:rtype: float or int
|
||||
"""
|
||||
frames = self.stop - self.start + 1 # + 1 since stop is inclusive
|
||||
reads = self.reads
|
||||
@@ -203,10 +213,35 @@ class ProgressParser:
|
||||
# FIXME: handle errors
|
||||
|
||||
class ReadTrackTask(task.Task):
|
||||
"""
|
||||
I am a task that reads a track using cdparanoia.
|
||||
"""I am a task that reads a track using cdparanoia.
|
||||
|
||||
@ivar reads: how many reads were done to rip the track
|
||||
:cvar description:
|
||||
:vartype description:
|
||||
:cvar quality:
|
||||
:cvar speed:
|
||||
:cvar duration:
|
||||
:ivar path: where to store the ripped track.
|
||||
:vartype path: unicode
|
||||
:ivar table: table of contents of CD.
|
||||
:vartype table: L{table.Table}
|
||||
:ivar start: first frame to rip.
|
||||
:vartype start: int
|
||||
:ivar stop: last frame to rip (inclusive); >= start.
|
||||
:vartype stop: int
|
||||
:ivar offset: read offset, in samples.
|
||||
:vartype offset: int
|
||||
:ivar parser:
|
||||
:vartype parser:
|
||||
:ivar device: the device to rip from.
|
||||
:vartype device: str
|
||||
:ivar start_time:
|
||||
:vartype start_time:
|
||||
:ivar overread:
|
||||
:vartype overread:
|
||||
:ivar buffer:
|
||||
:vartype buffer:
|
||||
:ivar errors:
|
||||
:vartype errors:
|
||||
"""
|
||||
|
||||
description = "Reading track"
|
||||
@@ -218,26 +253,6 @@ class ReadTrackTask(task.Task):
|
||||
|
||||
def __init__(self, path, table, start, stop, overread, offset=0,
|
||||
device=None, action="Reading", what="track"):
|
||||
"""
|
||||
Read the given track.
|
||||
|
||||
@param path: where to store the ripped track
|
||||
@type path: unicode
|
||||
@param table: table of contents of CD
|
||||
@type table: L{table.Table}
|
||||
@param start: first frame to rip
|
||||
@type start: int
|
||||
@param stop: last frame to rip (inclusive); >= start
|
||||
@type stop: int
|
||||
@param offset: read offset, in samples
|
||||
@type offset: int
|
||||
@param device: the device to rip from
|
||||
@type device: str
|
||||
@param action: a string representing the action; e.g. Read/Verify
|
||||
@type action: str
|
||||
@param what: a string representing what's being read; e.g. Track
|
||||
@type what: str
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self.path = path
|
||||
@@ -299,7 +314,7 @@ class ReadTrackTask(task.Task):
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
close_fds=True)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
import errno
|
||||
if e.errno == errno.ENOENT:
|
||||
raise common.MissingDependencyException('cdparanoia')
|
||||
@@ -398,24 +413,45 @@ class ReadTrackTask(task.Task):
|
||||
|
||||
|
||||
class ReadVerifyTrackTask(task.MultiSeparateTask):
|
||||
"""
|
||||
I am a task that reads and verifies a track using cdparanoia.
|
||||
"""I am a task that reads and verifies a track using cdparanoia.
|
||||
|
||||
I also encode the track.
|
||||
|
||||
The path where the file is stored can be changed if necessary, for
|
||||
example if the file name is too long.
|
||||
|
||||
@ivar path: the path where the file is to be stored.
|
||||
@ivar checksum: the checksum of the track; set if they match.
|
||||
@ivar testchecksum: the test checksum of the track.
|
||||
@ivar copychecksum: the copy checksum of the track.
|
||||
@ivar testspeed: the test speed of the track, as a multiple of
|
||||
track duration.
|
||||
@ivar copyspeed: the copy speed of the track, as a multiple of
|
||||
track duration.
|
||||
@ivar testduration: the test duration of the track, in seconds.
|
||||
@ivar copyduration: the copy duration of the track, in seconds.
|
||||
@ivar peak: the peak level of the track
|
||||
:cvar checksum: the checksum of the track; set if they match.
|
||||
:vartype checksum:
|
||||
:cvar testchecksum: the test checksum of the track.
|
||||
:vartype testchecksum:
|
||||
:cvar copychecksum: the copy checksum of the track.
|
||||
:vartype copychecksum:
|
||||
:cvar peak: the peak level of the track
|
||||
:vartype peak:
|
||||
:cvar quality:
|
||||
:vartype quality:
|
||||
:cvar testspeed: the test speed of the track, as a multiple of
|
||||
track duration.
|
||||
:vartype testspeed:
|
||||
:cvar copyspeed: the copy speed of the track, as a multiple of
|
||||
track duration.
|
||||
:vartype copyspeed:
|
||||
:cvar testduration: the test duration of the track, in seconds.
|
||||
:vartype testduration:
|
||||
:cvar copyduration: the copy duration of the track, in seconds.
|
||||
:vartype copyduration:
|
||||
:ivar path: the path where the file is to be stored.
|
||||
:vartype path: str
|
||||
:ivar table: table of contents of CD.
|
||||
:vartype table: L{table.Table}
|
||||
:ivar stop: last frame to rip (inclusive).
|
||||
:vartype stop: int
|
||||
:ivar offset: read offset, in samples.
|
||||
:vartype offset: int
|
||||
:ivar device: the device to rip from.
|
||||
:vartype device: str
|
||||
:ivar taglist: a dict of tags.
|
||||
:vartype taglist: dict
|
||||
"""
|
||||
|
||||
checksum = None
|
||||
@@ -433,22 +469,6 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
|
||||
|
||||
def __init__(self, path, table, start, stop, overread, offset=0,
|
||||
device=None, taglist=None, what="track"):
|
||||
"""
|
||||
@param path: where to store the ripped track
|
||||
@type path: str
|
||||
@param table: table of contents of CD
|
||||
@type table: L{table.Table}
|
||||
@param start: first frame to rip
|
||||
@type start: int
|
||||
@param stop: last frame to rip (inclusive)
|
||||
@type stop: int
|
||||
@param offset: read offset, in samples
|
||||
@type offset: int
|
||||
@param device: the device to rip from
|
||||
@type device: str
|
||||
@param taglist: a dict of tags
|
||||
@type taglist: dict
|
||||
"""
|
||||
task.MultiSeparateTask.__init__(self)
|
||||
|
||||
logger.debug('Creating read and verify task on %r', path)
|
||||
@@ -478,7 +498,7 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
|
||||
try:
|
||||
tmpoutpath = path + u'.part'
|
||||
open(tmpoutpath, 'wb').close()
|
||||
except IOError, e:
|
||||
except IOError as e:
|
||||
if errno.ENAMETOOLONG != e.errno:
|
||||
raise
|
||||
path = common.shrinkPath(path)
|
||||
@@ -540,7 +560,7 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
|
||||
try:
|
||||
logger.debug('Moving to final path %r', self.path)
|
||||
os.rename(self._tmppath, self.path)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
logger.debug('Exception while moving to final '
|
||||
'path %r: %r', self.path, str(e))
|
||||
self.exception = e
|
||||
@@ -548,7 +568,7 @@ class ReadVerifyTrackTask(task.MultiSeparateTask):
|
||||
os.unlink(self._tmppath)
|
||||
else:
|
||||
logger.debug('stop: exception %r', self.exception)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
print 'WARNING: unhandled exception %r' % (e, )
|
||||
|
||||
task.MultiSeparateTask.stop(self)
|
||||
|
||||
@@ -13,8 +13,14 @@ CDRDAO = 'cdrdao'
|
||||
|
||||
|
||||
def read_toc(device, fast_toc=False):
|
||||
"""
|
||||
Return cdrdao-generated table of contents for 'device'.
|
||||
"""Get the cd's toc using cdrdao and parse it.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
:param fast_toc: enable cdrdao's fast-toc option? (Default value = False)
|
||||
:type fast_toc: bool
|
||||
:returns:
|
||||
:rtype: TocFile
|
||||
"""
|
||||
# cdrdao MUST be passed a non-existing filename as its last argument
|
||||
# to write the TOC to; it does not support writing to stdout or
|
||||
@@ -48,8 +54,12 @@ def read_toc(device, fast_toc=False):
|
||||
|
||||
|
||||
def DetectCdr(device):
|
||||
"""
|
||||
Return whether cdrdao detects a CD-R for 'device'.
|
||||
"""Check if inserted disk is a CD-R.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
:returns: False if inserted disk is not a CD-R, True otherwise.
|
||||
:rtype: bool
|
||||
"""
|
||||
cmd = [CDRDAO, 'disk-info', '-v1', '--device', device]
|
||||
logger.debug("executing %r", cmd)
|
||||
@@ -61,8 +71,10 @@ def DetectCdr(device):
|
||||
|
||||
|
||||
def version():
|
||||
"""
|
||||
Return cdrdao version as a string.
|
||||
"""Detect cdrdao's version.
|
||||
|
||||
:returns:
|
||||
:rtype:
|
||||
"""
|
||||
cdrdao = Popen(CDRDAO, stderr=PIPE)
|
||||
out, err = cdrdao.communicate()
|
||||
@@ -80,21 +92,31 @@ def version():
|
||||
|
||||
|
||||
def ReadTOCTask(device):
|
||||
"""
|
||||
stopgap morituri-insanity compatibility layer
|
||||
"""Stopgap morituri-insanity compatibility layer.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
:returns:
|
||||
:rtype: TocFile
|
||||
"""
|
||||
return read_toc(device, fast_toc=True)
|
||||
|
||||
|
||||
def ReadTableTask(device):
|
||||
"""
|
||||
stopgap morituri-insanity compatibility layer
|
||||
"""Stopgap morituri-insanity compatibility layer.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
:returns:
|
||||
:rtype: TocFile
|
||||
"""
|
||||
return read_toc(device)
|
||||
|
||||
|
||||
def getCDRDAOVersion():
|
||||
"""
|
||||
stopgap morituri-insanity compatibility layer
|
||||
"""Stopgap morituri-insanity compatibility layer.
|
||||
|
||||
:returns:
|
||||
:rtype:
|
||||
"""
|
||||
return version()
|
||||
|
||||
@@ -5,9 +5,15 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def encode(infile, outfile):
|
||||
"""
|
||||
Encodes infile to outfile, with flac.
|
||||
Uses '-f' because whipper already creates the file.
|
||||
"""Encode infile to outfile, with flac.
|
||||
|
||||
Uses ``-f`` because whipper already creates the file.
|
||||
|
||||
:param infile: full path to input audio track.
|
||||
:type infile: str
|
||||
:param outfile: full path to output audio track.
|
||||
:type outfile: str
|
||||
:raises CalledProcessError: if the flac encoder returns non-zero.
|
||||
"""
|
||||
try:
|
||||
# TODO: Replace with Popen so that we can catch stderr and write it to
|
||||
|
||||
@@ -8,11 +8,12 @@ SOX = 'sox'
|
||||
|
||||
|
||||
def peak_level(track_path):
|
||||
"""
|
||||
Accepts a path to a sox-decodable audio file.
|
||||
"""Accept a path to a sox-decodable audio file.
|
||||
|
||||
Returns track peak level from sox ('maximum amplitude') as a float.
|
||||
Returns None on error.
|
||||
:param track_path: full path to audio track.
|
||||
:type track_path: str
|
||||
:returns: track peak level from sox ('maximum amplitude') or None on error.
|
||||
:rtype: float or None
|
||||
"""
|
||||
if not os.path.exists(track_path):
|
||||
logger.warning("SoX peak detection failed: file not found")
|
||||
|
||||
@@ -10,19 +10,29 @@ SOXI = 'soxi'
|
||||
|
||||
|
||||
class AudioLengthTask(ctask.PopenTask):
|
||||
"""
|
||||
I calculate the length of a track in audio samples.
|
||||
"""Calculate the length of a track in audio samples.
|
||||
|
||||
@ivar length: length of the decoded audio file, in audio samples.
|
||||
:cvar logCategory:
|
||||
:vartype logCategory:
|
||||
:cvar description:
|
||||
:vartype description:
|
||||
:cvar length: length of the decoded audio file, in audio samples.
|
||||
:vartype length: int or None
|
||||
:ivar logName:
|
||||
:vartype logName:
|
||||
:ivar command:
|
||||
:vartype command:
|
||||
:ivar error:
|
||||
:vartype error:
|
||||
:ivar output:
|
||||
:vartype output:
|
||||
"""
|
||||
|
||||
logCategory = 'AudioLengthTask'
|
||||
description = 'Getting length of audio track'
|
||||
length = None
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
@type path: unicode
|
||||
"""
|
||||
assert type(path) is unicode, "%r is not unicode" % path
|
||||
|
||||
self.logName = os.path.basename(path).encode('utf-8')
|
||||
|
||||
@@ -5,27 +5,34 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def eject_device(device):
|
||||
"""
|
||||
Eject the given device.
|
||||
"""Eject the given device.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
"""
|
||||
logger.debug("ejecting device %s", device)
|
||||
os.system('eject %s' % device)
|
||||
|
||||
|
||||
def load_device(device):
|
||||
"""
|
||||
Load the given device.
|
||||
"""Load the given device.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
"""
|
||||
logger.debug("loading (eject -t) device %s", device)
|
||||
os.system('eject -t %s' % device)
|
||||
|
||||
|
||||
def unmount_device(device):
|
||||
"""
|
||||
Unmount the given device if it is mounted, as happens with automounted
|
||||
data tracks.
|
||||
"""Unmount the given device if it is mounted.
|
||||
|
||||
Data tracks are usually automounted.
|
||||
|
||||
If the given device is a symlink, the target will be checked.
|
||||
|
||||
:param device: optical disk drive.
|
||||
:type device:
|
||||
"""
|
||||
device = os.path.realpath(device)
|
||||
logger.debug('possibly unmount real path %r' % device)
|
||||
|
||||
Reference in New Issue
Block a user