Improve docstrings
Signed-off-by: JoeLametta <JoeLametta@users.noreply.github.com>
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Reading .cue files
|
||||
Read .cue files.
|
||||
|
||||
See http://digitalx.org/cuesheetsyntax.php
|
||||
"""
|
||||
@@ -58,17 +58,15 @@ _INDEX_RE = re.compile(r"""
|
||||
|
||||
|
||||
class CueFile:
|
||||
"""
|
||||
I represent a .cue file as an object.
|
||||
|
||||
:vartype table: table.Table
|
||||
:ivar table: the index table.
|
||||
"""
|
||||
"""Represent a .cue file as an object."""
|
||||
logCategory = 'CueFile'
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
:type path: str
|
||||
Init CueFile.
|
||||
|
||||
:param path: path to track
|
||||
:type path: str
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
|
||||
@@ -153,7 +151,10 @@ class CueFile:
|
||||
"""
|
||||
Add a message about a given line in the cue file.
|
||||
|
||||
:param number: line number, counting from 0.
|
||||
:param message: a text line in the cue sheet
|
||||
:type message: str
|
||||
:param number: line number, counting from 0
|
||||
:type number: int
|
||||
"""
|
||||
self._messages.append((number + 1, message))
|
||||
|
||||
@@ -181,19 +182,21 @@ class CueFile:
|
||||
"""
|
||||
Translate the .cue's FILE to an existing path.
|
||||
|
||||
:type path: str
|
||||
:param path: path to track
|
||||
:type path: str
|
||||
"""
|
||||
return common.getRealPath(self._path, path)
|
||||
|
||||
|
||||
class File:
|
||||
"""
|
||||
I represent a FILE line in a cue file.
|
||||
"""
|
||||
"""Represent a FILE line in a cue file."""
|
||||
|
||||
def __init__(self, path, file_format):
|
||||
"""
|
||||
:type path: str
|
||||
Init File.
|
||||
|
||||
:param path: path to track
|
||||
:type path: str
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Wrap on-disk CD images based on the .cue file.
|
||||
"""
|
||||
"""Wrap on-disk CD images based on the .cue file."""
|
||||
|
||||
import os
|
||||
|
||||
@@ -36,15 +34,19 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
class Image:
|
||||
"""
|
||||
:ivar table: The Table of Contents for this image.
|
||||
Represent a CD image based on the .cue file.
|
||||
|
||||
:ivar table: The Table of Contents for this image
|
||||
:vartype table: table.Table
|
||||
"""
|
||||
logCategory = 'Image'
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
:type path: str
|
||||
Init Image.
|
||||
|
||||
:param path: .cue path
|
||||
:type path: str
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
|
||||
@@ -61,6 +63,7 @@ class Image:
|
||||
Translate the .cue's FILE to an existing path.
|
||||
|
||||
:param path: .cue path
|
||||
:type path: unicode
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
|
||||
@@ -68,8 +71,10 @@ class Image:
|
||||
|
||||
def setup(self, runner):
|
||||
"""
|
||||
Do initial setup, like figuring out track lengths, and
|
||||
constructing the Table of Contents.
|
||||
Perform initial setup.
|
||||
|
||||
Like figuring out track lengths, and constructing
|
||||
the Table of Contents.
|
||||
"""
|
||||
logger.debug('setup image start')
|
||||
verify = ImageVerifyTask(self)
|
||||
@@ -108,9 +113,7 @@ class Image:
|
||||
|
||||
|
||||
class ImageVerifyTask(task.MultiSeparateTask):
|
||||
"""
|
||||
I verify a disk image and get the necessary track lengths.
|
||||
"""
|
||||
"""Verify a disk image and get the necessary track lengths."""
|
||||
|
||||
logCategory = 'ImageVerifyTask'
|
||||
|
||||
@@ -174,9 +177,7 @@ class ImageVerifyTask(task.MultiSeparateTask):
|
||||
|
||||
|
||||
class ImageEncodeTask(task.MultiSeparateTask):
|
||||
"""
|
||||
I encode a disk image to a different format.
|
||||
"""
|
||||
"""Encode a disk image to a different format."""
|
||||
|
||||
description = "Encoding tracks"
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Wrap Table of Contents.
|
||||
"""
|
||||
"""Wrap Table of Contents."""
|
||||
|
||||
import copy
|
||||
from urllib.parse import urlunparse, urlencode
|
||||
@@ -54,19 +52,20 @@ CDTEXT_FIELDS = [
|
||||
|
||||
class Track:
|
||||
"""
|
||||
I represent a track entry in an Table.
|
||||
Represent a track entry in a Table.
|
||||
|
||||
:cvar number: track number (1-based)
|
||||
:vartype number: int
|
||||
:cvar audio: whether the track is audio
|
||||
:vartype audio: bool
|
||||
:vartype indexes: dict of number -> :any:`Index`
|
||||
:cvar isrc: ISRC code (12 alphanumeric characters)
|
||||
:vartype isrc: str
|
||||
:cvar cdtext: dictionary of CD Text information;
|
||||
:any:`see CDTEXT_KEYS`
|
||||
:vartype cdtext: str
|
||||
:cvar pre_emphasis: whether track is pre-emphasised
|
||||
:cvar number: track number (1-based)
|
||||
:vartype number: int
|
||||
:cvar audio: whether the track is audio
|
||||
:vartype audio: bool
|
||||
:cvar indexes: dict of number
|
||||
:vartype indexes: dict of number -> :any:`Index`
|
||||
:cvar isrc: ISRC code (12 alphanumeric characters)
|
||||
:vartype isrc: str
|
||||
:cvar cdtext: dictionary of CD Text information;
|
||||
:any:`see CDTEXT_KEYS`
|
||||
:vartype cdtext: str
|
||||
:cvar pre_emphasis: whether track is pre-emphasised
|
||||
:vartype pre_emphasis: bool
|
||||
"""
|
||||
|
||||
@@ -90,7 +89,19 @@ class Track:
|
||||
def index(self, number, absolute=None, path=None, relative=None,
|
||||
counter=None):
|
||||
"""
|
||||
:type path: str or None
|
||||
Instantiate Index object and store it in class variable.
|
||||
|
||||
:param number: index number
|
||||
:type number: int
|
||||
:param absolute: absolute index offset, in CD frames
|
||||
:type absolute: int or None
|
||||
:param path: path to track
|
||||
:type path: str or None
|
||||
:param relative: relative index offset, in CD frames
|
||||
:type relative: int or None
|
||||
:param counter: the source counter; updates for each different
|
||||
data source (silence or different file path)
|
||||
:type counter: int or None
|
||||
"""
|
||||
if path is not None:
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
@@ -117,7 +128,7 @@ class Track:
|
||||
|
||||
def getPregap(self):
|
||||
"""
|
||||
Returns the length of the pregap for this track.
|
||||
Return the length of the pregap for this track.
|
||||
|
||||
The pregap is 0 if there is no index 0, and the difference between
|
||||
index 1 and index 0 if there is.
|
||||
@@ -130,10 +141,15 @@ class Track:
|
||||
|
||||
class Index:
|
||||
"""
|
||||
Represent an index of a track on a CD.
|
||||
|
||||
:cvar counter: counter for the index source; distinguishes between
|
||||
the matching FILE lines in .cue files for example
|
||||
:vartype path: str or None
|
||||
:vartype counter: int
|
||||
:cvar path: path to track
|
||||
:vartype path: str or None
|
||||
"""
|
||||
|
||||
number = None
|
||||
absolute = None
|
||||
path = None
|
||||
@@ -159,13 +175,12 @@ class Index:
|
||||
|
||||
class Table:
|
||||
"""
|
||||
I represent a table of indexes on a CD.
|
||||
Represent a table of indexes on a CD.
|
||||
|
||||
:cvar tracks: tracks on this CD
|
||||
:vartype tracks: list of :any:`Track`
|
||||
:cvar catalog: catalog number
|
||||
:cvar tracks: tracks on this CD
|
||||
:vartype tracks: list(Track)
|
||||
:cvar catalog: catalog number
|
||||
:vartype catalog: str
|
||||
:vartype cdtext: dict of str -> str
|
||||
"""
|
||||
|
||||
tracks = None # list of Track
|
||||
@@ -193,22 +208,24 @@ class Table:
|
||||
|
||||
def getTrackStart(self, number):
|
||||
"""
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
Return the start of the given track number's index 1, in CD frames.
|
||||
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
:returns: the start of the given track number's index 1, in CD frames
|
||||
:rtype: int
|
||||
:rtype: int
|
||||
"""
|
||||
track = self.tracks[number - 1]
|
||||
return track.getIndex(1).absolute
|
||||
|
||||
def getTrackEnd(self, number):
|
||||
"""
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
Return the end of the given track number, in CD frames.
|
||||
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
:returns: the end of the given track number (ie index 1 of next track)
|
||||
:rtype: int
|
||||
:rtype: int
|
||||
"""
|
||||
# default to end of disc
|
||||
end = self.leadout - 1
|
||||
@@ -231,24 +248,30 @@ class Table:
|
||||
|
||||
def getTrackLength(self, number):
|
||||
"""
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
Return the length, in CD frames, for the given track number.
|
||||
|
||||
:param number: the track number, 1-based
|
||||
:type number: int
|
||||
:returns: the length of the given track number, in CD frames
|
||||
:rtype: int
|
||||
:rtype: int
|
||||
"""
|
||||
return self.getTrackEnd(number) - self.getTrackStart(number) + 1
|
||||
|
||||
def getAudioTracks(self):
|
||||
"""
|
||||
:returns: the number of audio tracks on the CD
|
||||
:rtype: int
|
||||
Return the number of audio tracks on the disc.
|
||||
|
||||
:returns: the number of audio tracks on the disc
|
||||
:rtype: int
|
||||
"""
|
||||
return len([t for t in self.tracks if t.audio])
|
||||
|
||||
def hasDataTracks(self):
|
||||
"""
|
||||
:returns: whether this disc contains data tracks
|
||||
Return whether the disc contains data tracks.
|
||||
|
||||
:returns: whether the disc contains data tracks
|
||||
:rtype: bool
|
||||
"""
|
||||
return len([t for t in self.tracks if not t.audio]) > 0
|
||||
|
||||
@@ -266,12 +289,13 @@ class Table:
|
||||
Get all CDDB values needed to calculate disc id and lookup URL.
|
||||
|
||||
This includes:
|
||||
- CDDB disc id
|
||||
- number of audio tracks
|
||||
- offset of index 1 of each track
|
||||
- length of disc in seconds (including data track)
|
||||
|
||||
:rtype: list of int
|
||||
* CDDB disc id
|
||||
* number of audio tracks
|
||||
* offset of index 1 of each track
|
||||
* length of disc in seconds (including data track)
|
||||
|
||||
:rtype: list(int)
|
||||
"""
|
||||
offsets = []
|
||||
|
||||
@@ -323,8 +347,8 @@ class Table:
|
||||
"""
|
||||
Calculate the CDDB disc ID.
|
||||
|
||||
:rtype: str
|
||||
:returns: the 8-character hexadecimal disc ID
|
||||
:rtype: str
|
||||
"""
|
||||
values = self.getCDDBValues()
|
||||
return "%08x" % int(values)
|
||||
@@ -333,8 +357,8 @@ class Table:
|
||||
"""
|
||||
Calculate the MusicBrainz disc ID.
|
||||
|
||||
:rtype: str
|
||||
:returns: the 28-character base64-encoded disc ID
|
||||
:rtype: str
|
||||
"""
|
||||
if self.mbdiscid:
|
||||
logger.debug('getMusicBrainzDiscId: returning cached %r',
|
||||
@@ -367,9 +391,10 @@ class Table:
|
||||
|
||||
def getFrameLength(self, data=False):
|
||||
"""
|
||||
Get the length in frames (excluding HTOA)
|
||||
Get the length in frames (excluding HTOA).
|
||||
|
||||
:param data: whether to include the data tracks in the length
|
||||
:type data: bool
|
||||
"""
|
||||
# the 'real' leadout, not offset by 150 frames
|
||||
if data:
|
||||
@@ -384,9 +409,7 @@ class Table:
|
||||
return durationFrames
|
||||
|
||||
def duration(self):
|
||||
"""
|
||||
Get the duration in ms for all audio tracks (excluding HTOA).
|
||||
"""
|
||||
"""Get the duration in ms for all audio tracks (excluding HTOA)."""
|
||||
return int(self.getFrameLength() * 1000.0 / common.FRAMES_PER_SECOND)
|
||||
|
||||
def _getMusicBrainzValues(self):
|
||||
@@ -394,12 +417,13 @@ class Table:
|
||||
Get all MusicBrainz values needed to calculate disc id and submit URL.
|
||||
|
||||
This includes:
|
||||
- track number of first track
|
||||
- number of audio tracks
|
||||
- leadout of disc
|
||||
- offset of index 1 of each track
|
||||
|
||||
:rtype: list of int
|
||||
* track number of first track
|
||||
* number of audio tracks
|
||||
* leadout of disc
|
||||
* offset of index 1 of each track
|
||||
|
||||
:rtype: list(int)
|
||||
"""
|
||||
# MusicBrainz disc id does not take into account data tracks
|
||||
|
||||
@@ -447,12 +471,13 @@ class Table:
|
||||
|
||||
def cue(self, cuePath='', program='whipper'):
|
||||
"""
|
||||
:param cuePath: path to the cue file to be written. If empty,
|
||||
will treat paths as if in current directory.
|
||||
|
||||
|
||||
Dump our internal representation to a .cue file content.
|
||||
|
||||
:param cuePath: path to the cue file to be written. If empty,
|
||||
will treat paths as if in current directory
|
||||
:type cuePath: unicode
|
||||
:param program: name of the program (ripping software)
|
||||
:type program: str
|
||||
:rtype: str
|
||||
"""
|
||||
logger.debug('generating .cue for cuePath %r', cuePath)
|
||||
@@ -582,6 +607,7 @@ class Table:
|
||||
def clearFiles(self):
|
||||
"""
|
||||
Clear all file backings.
|
||||
|
||||
Resets indexes paths and relative offsets.
|
||||
"""
|
||||
# FIXME: do a loop over track indexes better, with a pythonic
|
||||
@@ -604,14 +630,24 @@ class Table:
|
||||
|
||||
def setFile(self, track, index, path, length, counter=None):
|
||||
"""
|
||||
Sets the given file as the source from the given index on.
|
||||
Set the given file as the source from the given index on.
|
||||
|
||||
Will loop over all indexes that fall within the given length,
|
||||
to adjust the path.
|
||||
|
||||
Assumes all indexes have an absolute offset and will raise if not.
|
||||
|
||||
:type track: int
|
||||
:type index: int
|
||||
:param track: track number, 1-based
|
||||
:type track: int
|
||||
:param index: index of the track
|
||||
:type index: int
|
||||
:param path: path to track
|
||||
:type path: unicode
|
||||
:param length: length of the given track, in CD frames
|
||||
:type length: int
|
||||
:param counter: counter for the index source; distinguishes between
|
||||
the matching FILE lines in .cue files for example
|
||||
:type counter: int or None
|
||||
"""
|
||||
logger.debug('setFile: track %d, index %d, path %r, length %r, '
|
||||
'counter %r', track, index, path, length, counter)
|
||||
@@ -640,6 +676,7 @@ class Table:
|
||||
def absolutize(self):
|
||||
"""
|
||||
Calculate absolute offsets on indexes as much as possible.
|
||||
|
||||
Only possible for as long as tracks draw from the same file.
|
||||
"""
|
||||
t = self.tracks[0].number
|
||||
@@ -677,11 +714,14 @@ class Table:
|
||||
|
||||
def merge(self, other, session=2):
|
||||
"""
|
||||
Merges the given table at the end.
|
||||
Merge the given table at the end.
|
||||
|
||||
The other table is assumed to be from an additional session,
|
||||
|
||||
|
||||
:type other: Table
|
||||
:param other: session table
|
||||
:type other: Table
|
||||
:param session: session number
|
||||
:type session: int
|
||||
"""
|
||||
gap = self._getSessionGap(session)
|
||||
|
||||
@@ -729,10 +769,11 @@ class Table:
|
||||
Return the next track and index.
|
||||
|
||||
:param track: track number, 1-based
|
||||
|
||||
:type track: int
|
||||
:raises IndexError: on last index
|
||||
|
||||
:rtype: tuple of (int, int)
|
||||
:rtype: tuple(int, int)
|
||||
:param index: index of the next track
|
||||
:type index: int
|
||||
"""
|
||||
t = self.tracks[track - 1]
|
||||
indexes = list(t.indexes)
|
||||
@@ -756,7 +797,8 @@ class Table:
|
||||
def hasTOC(self):
|
||||
"""
|
||||
Check if the Table has a complete TOC.
|
||||
a TOC is a list of all tracks and their Index 01, with absolute
|
||||
|
||||
A TOC is a list of all tracks and their Index 01, with absolute
|
||||
offsets, as well as the leadout.
|
||||
"""
|
||||
if not self.leadout:
|
||||
@@ -775,8 +817,11 @@ class Table:
|
||||
|
||||
def accuraterip_ids(self):
|
||||
"""
|
||||
returns both AccurateRip disc ids as a tuple of 8-char
|
||||
hexadecimal strings (discid1, discid2)
|
||||
Return both AccurateRip disc ids.
|
||||
|
||||
:returns: both AccurateRip disc ids as a tuple of 8-char
|
||||
hexadecimal strings
|
||||
:rtype: tuple(str, str)
|
||||
"""
|
||||
# AccurateRip does not take into account data tracks,
|
||||
# but does count the data track to determine the leadout offset
|
||||
@@ -809,9 +854,7 @@ class Table:
|
||||
)
|
||||
|
||||
def canCue(self):
|
||||
"""
|
||||
Check if this table can be used to generate a .cue file
|
||||
"""
|
||||
"""Check if this table can be used to generate a .cue file."""
|
||||
if not self.hasTOC():
|
||||
logger.debug('no TOC, cannot cue')
|
||||
return False
|
||||
|
||||
@@ -19,9 +19,9 @@
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""
|
||||
Reading .toc files
|
||||
Read .toc files.
|
||||
|
||||
The .toc file format is described in the man page of cdrdao
|
||||
The .toc file format is described in the man page of cdrdao.
|
||||
"""
|
||||
|
||||
import re
|
||||
@@ -93,7 +93,8 @@ _INDEX_RE = re.compile(r"""
|
||||
|
||||
class Sources:
|
||||
"""
|
||||
I represent the list of sources used in the .toc file.
|
||||
Represent the list of sources used in the .toc file.
|
||||
|
||||
Each SILENCE and each FILE is a source.
|
||||
If the filename for FILE doesn't change, the counter is not increased.
|
||||
"""
|
||||
@@ -103,19 +104,22 @@ class Sources:
|
||||
|
||||
def append(self, counter, offset, source):
|
||||
"""
|
||||
Append ``(counter, offset, source)`` tuple to the ``sources`` list.
|
||||
|
||||
:param counter: the source counter; updates for each different
|
||||
data source (silence or different file path)
|
||||
:type counter: int
|
||||
:param offset: the absolute disc offset where this source starts
|
||||
:type counter: int
|
||||
:param offset: the absolute disc offset where this source starts
|
||||
:type offset: int
|
||||
:param source: data source
|
||||
:type source: File or None
|
||||
"""
|
||||
logger.debug('appending source, counter %d, abs offset %d, '
|
||||
'source %r', counter, offset, source)
|
||||
self._sources.append((counter, offset, source))
|
||||
|
||||
def get(self, offset):
|
||||
"""
|
||||
Retrieve the source used at the given offset.
|
||||
"""
|
||||
"""Retrieve the source used at the given offset."""
|
||||
for i, (_, o, _) in enumerate(self._sources):
|
||||
if offset < o:
|
||||
return self._sources[i - 1]
|
||||
@@ -124,7 +128,11 @@ class Sources:
|
||||
|
||||
def getCounterStart(self, counter):
|
||||
"""
|
||||
Retrieve the absolute offset of the first source for this counter
|
||||
Retrieve the absolute offset of the first source for this counter.
|
||||
|
||||
:param counter: the source counter; updates for each different
|
||||
data source (silence or different file path)
|
||||
:type counter: int
|
||||
"""
|
||||
for i, (c, _, _) in enumerate(self._sources):
|
||||
if c == counter:
|
||||
@@ -137,7 +145,10 @@ class TocFile:
|
||||
|
||||
def __init__(self, path):
|
||||
"""
|
||||
:type path: str
|
||||
Init TocFile.
|
||||
|
||||
:param path: path to track
|
||||
:type path: str
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
self._path = path
|
||||
@@ -379,14 +390,19 @@ class TocFile:
|
||||
"""
|
||||
Add a message about a given line in the cue file.
|
||||
|
||||
:param number: line number, counting from 0.
|
||||
:param number: line number, counting from 0
|
||||
:type number: int
|
||||
:param message: a text line in the cue sheet
|
||||
:type message: str
|
||||
"""
|
||||
self._messages.append((number + 1, message))
|
||||
|
||||
def getTrackLength(self, track):
|
||||
"""
|
||||
Returns the length of the given track, from its INDEX 01 to the next
|
||||
track's INDEX 01
|
||||
Return the length of the given track, in CD frames.
|
||||
|
||||
The track length is calculated from its INDEX 01 to the next
|
||||
track's INDEX 01.
|
||||
"""
|
||||
# returns track length in frames, or -1 if can't be determined and
|
||||
# complete file should be assumed
|
||||
@@ -411,22 +427,25 @@ class TocFile:
|
||||
"""
|
||||
Translate the .toc's FILE to an existing path.
|
||||
|
||||
:type path: str
|
||||
:param path: path to track
|
||||
:type path: str
|
||||
"""
|
||||
return common.getRealPath(self._path, path)
|
||||
|
||||
|
||||
class File:
|
||||
"""
|
||||
I represent a FILE line in a .toc file.
|
||||
"""
|
||||
"""Represent a FILE line in a .toc file."""
|
||||
|
||||
def __init__(self, path, start, length):
|
||||
"""
|
||||
:type path: str
|
||||
:type start: int
|
||||
:param start: starting point for the track in this file, in frames
|
||||
Init File.
|
||||
|
||||
:param path: path to track
|
||||
:type path: unicode
|
||||
:param start: starting point for the track in this file, in frames
|
||||
:type start: int
|
||||
:param length: length for the track in this file, in frames
|
||||
:type length: int
|
||||
"""
|
||||
assert isinstance(path, str), "%r is not str" % path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user