Improve docstrings
Signed-off-by: JoeLametta <JoeLametta@users.noreply.github.com>
This commit is contained in:
@@ -43,8 +43,7 @@ class EntryNotFound(Exception):
|
||||
|
||||
class _AccurateRipResponse:
|
||||
"""
|
||||
An AccurateRip response contains a collection of metadata identifying a
|
||||
particular digital audio compact disc.
|
||||
An AR resp. contains a collection of metadata identifying a specific disc.
|
||||
|
||||
For disc level metadata it contains the track count, two internal disc
|
||||
IDs, and the CDDB disc ID.
|
||||
@@ -55,9 +54,12 @@ class _AccurateRipResponse:
|
||||
|
||||
The response is stored as a packed binary structure.
|
||||
"""
|
||||
|
||||
def __init__(self, data):
|
||||
"""
|
||||
The checksums and confidences arrays are indexed by relative track
|
||||
Init _AccurateRipResponse.
|
||||
|
||||
Checksums and confidences arrays are indexed by relative track
|
||||
position, so track 1 will have array index 0, track 2 will have array
|
||||
index 1, and so forth. HTOA and other hidden tracks are not included.
|
||||
"""
|
||||
@@ -98,12 +100,14 @@ def _split_responses(raw_entry):
|
||||
|
||||
def calculate_checksums(track_paths):
|
||||
"""
|
||||
Return ARv1 and ARv2 checksums as two arrays of character strings in a
|
||||
dictionary: {'v1': ['deadbeef', ...], 'v2': [...]}
|
||||
|
||||
Return None instead of checksum string for unchecksummable tracks.
|
||||
Calculate AccurateRip checksums for the given tracks.
|
||||
|
||||
HTOA checksums are not included in the database and are not calculated.
|
||||
|
||||
:returns: ARv1 and ARv2 checksums as two arrays of character strings in a
|
||||
dictionary: ``{'v1': ['deadbeef', ...], 'v2': [...]}``
|
||||
or None instead of checksum string for unchecksummable tracks.
|
||||
:rtype: dict(string, list()) or None
|
||||
"""
|
||||
track_count = len(track_paths)
|
||||
v1_checksums = []
|
||||
@@ -152,9 +156,10 @@ def _save_entry(raw_entry, path):
|
||||
def get_db_entry(path):
|
||||
"""
|
||||
Retrieve cached AccurateRip disc entry as array of _AccurateRipResponses.
|
||||
|
||||
Downloads entry from accuraterip.com on cache fault.
|
||||
|
||||
`path' is in the format of the output of table.accuraterip_path().
|
||||
``path`` is in the format of the output of ``table.accuraterip_path()``.
|
||||
"""
|
||||
cached_path = join(_CACHE_DIR, path)
|
||||
if exists(cached_path):
|
||||
@@ -183,11 +188,11 @@ def _assign_checksums_and_confidences(tracks, checksums, responses):
|
||||
|
||||
def _match_responses(tracks, responses):
|
||||
"""
|
||||
Match and save track accuraterip response checksums against
|
||||
all non-hidden tracks.
|
||||
Match and save track AR response checksums against all non-hidden tracks.
|
||||
|
||||
Returns True if every track has a match for every entry for either
|
||||
AccurateRip version.
|
||||
:returns: True if every track has a match for every entry for either
|
||||
AccurateRip version, False otherwise.
|
||||
:rtype: bool
|
||||
"""
|
||||
for r in responses:
|
||||
for i, track in enumerate(tracks):
|
||||
@@ -211,7 +216,8 @@ def _match_responses(tracks, responses):
|
||||
def verify_result(result, responses, checksums):
|
||||
"""
|
||||
Verify track AccurateRip checksums against database responses.
|
||||
Stores track checksums and database values on result.
|
||||
|
||||
Store track checksums and database values on result.
|
||||
"""
|
||||
if not (result and responses and checksums):
|
||||
return False
|
||||
@@ -226,9 +232,7 @@ def verify_result(result, responses, checksums):
|
||||
|
||||
|
||||
def print_report(result):
|
||||
"""
|
||||
Print AccurateRip verification results.
|
||||
"""
|
||||
"""Print AccurateRip verification results."""
|
||||
for _, track in enumerate(result.tracks):
|
||||
status = 'rip NOT accurate'
|
||||
conf = '(not found)'
|
||||
|
||||
@@ -45,6 +45,7 @@ class Persister:
|
||||
def __init__(self, path=None, default=None):
|
||||
"""
|
||||
If path is not given, the object will not be persisted.
|
||||
|
||||
This allows code to transparently deal with both persisted and
|
||||
non-persisted objects, since the persist method will just end up
|
||||
doing nothing.
|
||||
@@ -56,8 +57,7 @@ class Persister:
|
||||
|
||||
def persist(self, obj=None):
|
||||
"""
|
||||
Persist the given object, if we have a persistence path and the
|
||||
object changed.
|
||||
Persist the given obj if we have a persist. path and the obj changed.
|
||||
|
||||
If object is not given, re-persist our object, always.
|
||||
If object is given, only persist if it was changed.
|
||||
@@ -115,9 +115,7 @@ class Persister:
|
||||
|
||||
|
||||
class PersistedCache:
|
||||
"""
|
||||
I wrap a directory of persisted objects.
|
||||
"""
|
||||
"""Wrap a directory of persisted objects."""
|
||||
|
||||
path = None
|
||||
|
||||
@@ -129,9 +127,7 @@ class PersistedCache:
|
||||
return os.path.join(self.path, '%s.pickle' % key)
|
||||
|
||||
def get(self, key):
|
||||
"""
|
||||
Returns the persister for the given key.
|
||||
"""
|
||||
"""Return the persister for the given key."""
|
||||
persister = Persister(self._getPath(key))
|
||||
if persister.object:
|
||||
if hasattr(persister.object, 'instanceVersion'):
|
||||
@@ -154,8 +150,9 @@ class ResultCache:
|
||||
|
||||
def getRipResult(self, cddbdiscid, create=True):
|
||||
"""
|
||||
Retrieve the persistable RipResult either from our cache (from a
|
||||
previous, possibly aborted rip), or return a new one.
|
||||
Get the persistable RipResult either from our cache or ret. a new one.
|
||||
|
||||
The cached RipResult may come from an aborted rip.
|
||||
|
||||
:rtype: :any:`Persistable` for :any:`result.RipResult`
|
||||
"""
|
||||
@@ -183,9 +180,8 @@ class ResultCache:
|
||||
|
||||
|
||||
class TableCache:
|
||||
|
||||
"""
|
||||
I read and write entries to and from the cache of tables.
|
||||
Read and write entries to and from the cache of tables.
|
||||
|
||||
If no path is specified, the cache will write to the current cache
|
||||
directory and read from all possible cache directories (to allow for
|
||||
|
||||
@@ -39,14 +39,14 @@ BYTES_PER_FRAME = SAMPLES_PER_FRAME * 4
|
||||
|
||||
|
||||
class EjectError(SystemError):
|
||||
"""
|
||||
Possibly ejects the drive in command.main.
|
||||
"""
|
||||
"""Possibly eject the drive in command.main."""
|
||||
|
||||
def __init__(self, device, *args):
|
||||
"""
|
||||
args is a tuple used by BaseException.__str__
|
||||
device is the device path to eject
|
||||
Init EjectError.
|
||||
|
||||
:param args: a tuple used by ``BaseException.__str__``
|
||||
:param device: device path to eject
|
||||
"""
|
||||
self.args = args
|
||||
self.device = device
|
||||
@@ -54,13 +54,12 @@ class EjectError(SystemError):
|
||||
|
||||
def msfToFrames(msf):
|
||||
"""
|
||||
Converts a string value in MM:SS:FF to frames.
|
||||
Convert a string value in MM:SS:FF to frames.
|
||||
|
||||
:param msf: the MM:SS:FF value to convert
|
||||
:type msf: str
|
||||
|
||||
:rtype: int
|
||||
:type msf: str
|
||||
:returns: number of frames
|
||||
:rtype: int
|
||||
"""
|
||||
if ':' not in msf:
|
||||
return int(msf)
|
||||
@@ -97,21 +96,19 @@ def framesToHMSF(frames):
|
||||
|
||||
def formatTime(seconds, fractional=3):
|
||||
"""
|
||||
Nicely format time in a human-readable format, like
|
||||
HH:MM:SS.mmm
|
||||
Nicely format time in a human-readable format, like HH:MM:SS.mmm.
|
||||
|
||||
If fractional is zero, no seconds will be shown.
|
||||
If it is greater than 0, we will show seconds and fractions of seconds.
|
||||
As a side consequence, there is no way to show seconds without fractions.
|
||||
|
||||
:param seconds: the time in seconds to format.
|
||||
:type seconds: int or float
|
||||
:param seconds: the time in seconds to format
|
||||
:type seconds: int or float
|
||||
:param fractional: how many digits to show for the fractional part of
|
||||
seconds.
|
||||
:type fractional: int
|
||||
|
||||
seconds
|
||||
:type fractional: int
|
||||
:returns: a nicely formatted time string
|
||||
:rtype: string
|
||||
:returns: a nicely formatted time string.
|
||||
"""
|
||||
chunks = []
|
||||
|
||||
@@ -149,16 +146,13 @@ class EmptyError(Exception):
|
||||
|
||||
|
||||
class MissingFrames(Exception):
|
||||
"""
|
||||
Less frames decoded than expected.
|
||||
"""
|
||||
"""Less frames decoded than expected."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def truncate_filename(path):
|
||||
"""
|
||||
Truncate filename to the max. len. allowed by the path's filesystem
|
||||
"""
|
||||
"""Truncate filename to the max. len. allowed by the path's filesystem."""
|
||||
p, f = os.path.split(os.path.normpath(path))
|
||||
f, e = os.path.splitext(f)
|
||||
# Get the filename length limit in bytes
|
||||
@@ -172,7 +166,8 @@ def truncate_filename(path):
|
||||
def shrinkPath(path):
|
||||
"""
|
||||
Shrink a full path to a shorter version.
|
||||
Used to handle ENAMETOOLONG
|
||||
|
||||
Used to handle ``ENAMETOOLONG``.
|
||||
"""
|
||||
parts = list(os.path.split(path))
|
||||
length = len(parts[-1])
|
||||
@@ -204,14 +199,15 @@ def shrinkPath(path):
|
||||
def getRealPath(refPath, filePath):
|
||||
"""
|
||||
Translate a .cue or .toc's FILE argument to an existing path.
|
||||
|
||||
Does Windows path translation.
|
||||
|
||||
Will look for the given file name, but with .flac and .wav as extensions.
|
||||
|
||||
:param refPath: path to the file from which the track is referenced;
|
||||
for example, path to the .cue file in the same directory
|
||||
:type refPath: str
|
||||
|
||||
:type filePath: str
|
||||
:param refPath: path to the file from which the track is referenced;
|
||||
for example, path to the .cue file in the same directory
|
||||
:type refPath: str
|
||||
:type filePath: str
|
||||
"""
|
||||
assert isinstance(filePath, str), "%r is not str" % filePath
|
||||
|
||||
@@ -258,10 +254,9 @@ def getRealPath(refPath, filePath):
|
||||
|
||||
def getRelativePath(targetPath, collectionPath):
|
||||
"""
|
||||
Get a relative path from the directory of collectionPath to
|
||||
targetPath.
|
||||
Get a relative path from the directory of collectionPath to targetPath.
|
||||
|
||||
Used to determine the path to use in .cue/.m3u files
|
||||
Used to determine the path to use in .cue/.m3u files.
|
||||
"""
|
||||
logger.debug('getRelativePath: target %r, collection %r',
|
||||
targetPath, collectionPath)
|
||||
@@ -280,9 +275,7 @@ def getRelativePath(targetPath, collectionPath):
|
||||
|
||||
|
||||
def validate_template(template, kind):
|
||||
"""
|
||||
Raise exception if disc/track template includes invalid variables
|
||||
"""
|
||||
"""Raise exception if disc/track template includes invalid variables."""
|
||||
if kind == 'disc':
|
||||
matches = re.findall(r'%[^ARSXdrxy]', template)
|
||||
elif kind == 'track':
|
||||
@@ -294,20 +287,22 @@ def validate_template(template, kind):
|
||||
|
||||
class VersionGetter:
|
||||
"""
|
||||
I get the version of a program by looking for it in command output
|
||||
according to a regexp.
|
||||
Get the version of a program.
|
||||
|
||||
It is extracted by looking for it in command output according to a RegEX.
|
||||
"""
|
||||
|
||||
def __init__(self, dependency, args, regexp, expander):
|
||||
"""
|
||||
:param dependency: name of the dependency providing the program
|
||||
:param args: the arguments to invoke to show the version
|
||||
:type args: list of str
|
||||
:param regexp: the regular expression to get the version
|
||||
:param expander: the expansion string for the version using the
|
||||
regexp group dict
|
||||
"""
|
||||
Init VersionGetter.
|
||||
|
||||
:param dependency: name of the dependency providing the program
|
||||
:param args: the arguments to invoke to show the version
|
||||
:type args: list(str)
|
||||
:param regexp: the regular expression to get the version
|
||||
:param expander: the expansion string for the version using the
|
||||
regexp group dict
|
||||
"""
|
||||
self._dep = dependency
|
||||
self._args = args
|
||||
self._regexp = regexp
|
||||
|
||||
@@ -96,9 +96,7 @@ class Config:
|
||||
self.write()
|
||||
|
||||
def getReadOffset(self, vendor, model, release):
|
||||
"""
|
||||
Get a read offset for the given drive.
|
||||
"""
|
||||
"""Get a read offset for the given drive."""
|
||||
section = self._findDriveSection(vendor, model, release)
|
||||
|
||||
try:
|
||||
|
||||
@@ -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/>.
|
||||
|
||||
"""
|
||||
Handles communication with the MusicBrainz server using NGS.
|
||||
"""
|
||||
"""Handle communication with the MusicBrainz server using NGS."""
|
||||
from urllib.error import HTTPError
|
||||
|
||||
import whipper
|
||||
@@ -62,16 +60,19 @@ class TrackMetadata:
|
||||
|
||||
class DiscMetadata:
|
||||
"""
|
||||
:param artist: artist(s) name
|
||||
:param sortName: release artist sort name
|
||||
:param release: earliest release date, in YYYY-MM-DD
|
||||
:type release: str
|
||||
:param title: title of the disc (with disambiguation)
|
||||
:param releaseTitle: title of the release (without disambiguation)
|
||||
:type tracks: list of :any:`TrackMetadata`
|
||||
:param countries: MusicBrainz release countries
|
||||
:type countries: list or None
|
||||
Represent the disc metadata.
|
||||
|
||||
:cvar artist: artist(s) name
|
||||
:cvar sortName: release artist sort name
|
||||
:cvar release: earliest release date, in YYYY-MM-DD
|
||||
:vartype release: str
|
||||
:cvar title: title of the disc (with disambiguation)
|
||||
:cvar releaseTitle: title of the release (without disambiguation)
|
||||
:vartype tracks: list of :any:`TrackMetadata`
|
||||
:cvar countries: MusicBrainz release countries
|
||||
:vartype countries: list or None
|
||||
"""
|
||||
|
||||
artist = None
|
||||
sortName = None
|
||||
title = None
|
||||
@@ -123,10 +124,7 @@ def _record(record, which, name, what):
|
||||
|
||||
|
||||
class _Credit(list):
|
||||
"""
|
||||
I am a representation of an artist-credit in MusicBrainz for a disc
|
||||
or track.
|
||||
"""
|
||||
"""Represent an artist-credit in MusicBrainz for a disc or track."""
|
||||
|
||||
def joiner(self, attributeGetter, joinString=None):
|
||||
res = []
|
||||
@@ -217,10 +215,11 @@ def _getPerformers(recording):
|
||||
|
||||
def _getMetadata(release, discid=None, country=None):
|
||||
"""
|
||||
:type release: dict
|
||||
Get disc metadata based upon the provided release id.
|
||||
|
||||
:param release: a release dict as returned in the value for key release
|
||||
from get_release_by_id
|
||||
|
||||
:type release: dict
|
||||
:rtype: DiscMetadata or None
|
||||
"""
|
||||
logger.debug('getMetadata for release id %r', release['id'])
|
||||
@@ -378,14 +377,16 @@ def getReleaseMetadata(release_id, discid=None, country=None, record=False):
|
||||
|
||||
def musicbrainz(discid, country=None, record=False):
|
||||
"""
|
||||
Based on a MusicBrainz disc id, get a list of DiscMetadata objects
|
||||
for the given disc id.
|
||||
Get a list of DiscMetadata objects for the given MusicBrainz disc id.
|
||||
|
||||
Example disc id: Mj48G109whzEmAbPBoGvd4KyCS4-
|
||||
|
||||
:type discid: str
|
||||
Example disc id: ``Mj48G109whzEmAbPBoGvd4KyCS4-``
|
||||
|
||||
:type discid: str
|
||||
:rtype: list of :any:`DiscMetadata`
|
||||
:param country: country name used to filter releases by provenance
|
||||
:type country: str
|
||||
:param record: whether to record to disc as a JSON serialization
|
||||
:type record: bool
|
||||
"""
|
||||
logger.debug('looking up results for discid %r', discid)
|
||||
|
||||
|
||||
@@ -22,16 +22,20 @@ import re
|
||||
|
||||
|
||||
class PathFilter:
|
||||
"""
|
||||
I filter path components for safe storage on file systems.
|
||||
"""
|
||||
"""Filter path components for safe storage on file systems."""
|
||||
|
||||
def __init__(self, slashes=True, quotes=True, fat=True, special=False):
|
||||
"""
|
||||
Init PathFilter.
|
||||
|
||||
:param slashes: whether to convert slashes to dashes
|
||||
:param quotes: whether to normalize quotes
|
||||
:param fat: whether to strip characters illegal on FAT filesystems
|
||||
:type slashes: bool
|
||||
:param quotes: whether to normalize quotes
|
||||
:type quotes: bool
|
||||
:param fat: whether to strip characters illegal on FAT filesystems
|
||||
:type fat: bool
|
||||
:param special: whether to strip special characters
|
||||
:type special: bool
|
||||
"""
|
||||
self._slashes = slashes
|
||||
self._quotes = quotes
|
||||
|
||||
@@ -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/>.
|
||||
|
||||
"""
|
||||
Common functionality and class for all programs using whipper.
|
||||
"""
|
||||
"""Common functionality and class for all programs using whipper."""
|
||||
|
||||
import musicbrainzngs
|
||||
import re
|
||||
@@ -47,10 +45,10 @@ class Program:
|
||||
I maintain program state and functionality.
|
||||
|
||||
:vartype metadata: mbngs.DiscMetadata
|
||||
:cvar result: the rip's result
|
||||
:vartype result: result.RipResult
|
||||
:vartype outdir: str
|
||||
:vartype config: whipper.common.config.Config
|
||||
:cvar result: the rip's result
|
||||
:vartype result: result.RipResult
|
||||
:vartype outdir: str
|
||||
:vartype config: whipper.common.config.Config
|
||||
"""
|
||||
|
||||
cuePath = None
|
||||
@@ -61,7 +59,9 @@ class Program:
|
||||
|
||||
def __init__(self, config, record=False):
|
||||
"""
|
||||
:param record: whether to record results of API calls for playback.
|
||||
Init Program.
|
||||
|
||||
:param record: whether to record results of API calls for playback
|
||||
"""
|
||||
self._record = record
|
||||
self._cache = cache.ResultCache()
|
||||
@@ -89,7 +89,9 @@ class Program:
|
||||
os.chdir(workingDirectory)
|
||||
|
||||
def getFastToc(self, runner, device):
|
||||
"""Retrieve the normal TOC table from the drive.
|
||||
"""
|
||||
Retrieve the normal TOC table from the drive.
|
||||
|
||||
Also warn about buggy cdrdao versions.
|
||||
"""
|
||||
from pkg_resources import parse_version as V
|
||||
@@ -150,8 +152,9 @@ class Program:
|
||||
|
||||
def getRipResult(self, cddbdiscid):
|
||||
"""
|
||||
Retrieve the persistable RipResult either from our cache (from a
|
||||
previous, possibly aborted rip), or return a new one.
|
||||
Get the persistable RipResult either from our cache or ret. a new one.
|
||||
|
||||
The cached RipResult may come from an aborted rip.
|
||||
|
||||
:rtype: result.RipResult
|
||||
"""
|
||||
@@ -176,28 +179,31 @@ class Program:
|
||||
|
||||
def getPath(self, outdir, template, mbdiscid, metadata, track_number=None):
|
||||
"""
|
||||
Return disc or track path relative to outdir according to
|
||||
template. Track paths do not include extension.
|
||||
Return disc or track path relative to outdir according to template.
|
||||
|
||||
Track paths do not include extension.
|
||||
|
||||
Tracks are named according to the track template, filling in
|
||||
the variables and adding the file extension. Variables
|
||||
exclusive to the track template are:
|
||||
- %t: track number
|
||||
- %a: track artist
|
||||
- %n: track title
|
||||
- %s: track sort name
|
||||
|
||||
* ``%t``: track number
|
||||
* ``%a``: track artist
|
||||
* ``%n``: track title
|
||||
* ``%s``: track sort name
|
||||
|
||||
Disc files (.cue, .log, .m3u) are named according to the disc
|
||||
template, filling in the variables and adding the file
|
||||
extension. Variables for both disc and track template are:
|
||||
- %A: release artist
|
||||
- %S: release artist sort name
|
||||
- %d: disc title
|
||||
- %y: release year
|
||||
- %r: release type, lowercase
|
||||
- %R: release type, normal case
|
||||
- %x: audio extension, lowercase
|
||||
- %X: audio extension, uppercase
|
||||
|
||||
* ``%A``: release artist
|
||||
* ``%S``: release artist sort name
|
||||
* ``%d``: disc title
|
||||
* ``%y``: release year
|
||||
* ``%r``: release type, lowercase
|
||||
* ``%R``: release type, normal case
|
||||
* ``%x``: audio extension, lowercase
|
||||
* ``%X``: audio extension, uppercase
|
||||
"""
|
||||
assert isinstance(outdir, str), "%r is not str" % outdir
|
||||
assert isinstance(template, str), "%r is not str" % template
|
||||
@@ -247,8 +253,9 @@ class Program:
|
||||
@staticmethod
|
||||
def getCDDB(cddbdiscid):
|
||||
"""
|
||||
:param cddbdiscid: list of id, tracks, offsets, seconds
|
||||
Fetch basic metadata from freedb's CDDB.
|
||||
|
||||
:param cddbdiscid: list of id, tracks, offsets, seconds
|
||||
:rtype: str
|
||||
"""
|
||||
# FIXME: convert to nonblocking?
|
||||
@@ -272,7 +279,20 @@ class Program:
|
||||
def getMusicBrainz(self, ittoc, mbdiscid, release=None, country=None,
|
||||
prompt=False):
|
||||
"""
|
||||
:type ittoc: whipper.image.table.Table
|
||||
Fetch MusicBrainz's metadata for the given MusicBrainz disc id.
|
||||
|
||||
:param ittoc: disc TOC
|
||||
:type ittoc: whipper.image.table.Table
|
||||
:param mbdiscid: MusicBrainz DiscID
|
||||
:type mbdiscid: str
|
||||
:param release: MusicBrainz release id to match to
|
||||
(if there are multiple)
|
||||
:type release: str or None
|
||||
:param country: country name used to filter releases by provenance
|
||||
:type country: str or None
|
||||
:param prompt: whether to prompt if there are multiple
|
||||
matching releases
|
||||
:type prompt: bool
|
||||
"""
|
||||
# look up disc on MusicBrainz
|
||||
print('Disc duration: %s, %d audio tracks' % (
|
||||
@@ -393,9 +413,10 @@ class Program:
|
||||
"""
|
||||
Based on the metadata, get a dict of tags for the given track.
|
||||
|
||||
:param number: track number (0 for HTOA)
|
||||
:type number: int
|
||||
|
||||
:param number: track number (0 for HTOA)
|
||||
:type number: int
|
||||
:param mbdiscid: MusicBrainz DiscID
|
||||
:type mbdiscid: str
|
||||
:rtype: dict
|
||||
"""
|
||||
trackArtist = 'Unknown Artist'
|
||||
@@ -469,6 +490,7 @@ class Program:
|
||||
Check if we have hidden track one audio.
|
||||
|
||||
:returns: tuple of (start, stop), or None
|
||||
:rtype: tuple(int, int) or None
|
||||
"""
|
||||
track = self.result.table.tracks[0]
|
||||
try:
|
||||
@@ -531,11 +553,26 @@ class Program:
|
||||
def ripTrack(self, runner, trackResult, offset, device, taglist,
|
||||
overread, what=None, coverArtPath=None):
|
||||
"""
|
||||
Rip and store a track of the disc.
|
||||
|
||||
Ripping the track may change the track's filename as stored in
|
||||
trackResult.
|
||||
|
||||
:param trackResult: the object to store information in.
|
||||
:type trackResult: result.TrackResult
|
||||
:param runner: synchronous track rip task
|
||||
:type runner: task.SyncRunner
|
||||
:param trackResult: the object to store information in
|
||||
:type trackResult: result.TrackResult
|
||||
:param offset: ripping offset, in CD frames
|
||||
:type offset: int
|
||||
:param device: path to the hardware disc drive
|
||||
:type device: str
|
||||
:param taglist: dictionary of tags for the given track
|
||||
:type taglist: dict
|
||||
:param overread: whether to force overreading into the
|
||||
lead-out portion of the disc
|
||||
:type overread: bool
|
||||
:param what: a string representing what's being read; e.g. Track
|
||||
:type what: str or None
|
||||
"""
|
||||
if trackResult.number == 0:
|
||||
start, stop = self.getHTOA()
|
||||
@@ -581,7 +618,8 @@ class Program:
|
||||
|
||||
def verifyImage(self, runner, table):
|
||||
"""
|
||||
verify table against accuraterip and cue_path track lengths
|
||||
Verify table against AccurateRip and cue_path track lengths.
|
||||
|
||||
Verify our image against the given AccurateRip responses.
|
||||
|
||||
Needs an initialized self.result.
|
||||
|
||||
@@ -35,14 +35,13 @@ class Operator:
|
||||
self._resuming = False
|
||||
|
||||
def addOperation(self, operation):
|
||||
"""
|
||||
Add an operation.
|
||||
"""
|
||||
"""Add an operation."""
|
||||
self._todo.append(operation)
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load state from the given state path using the given key.
|
||||
|
||||
Verifies the state.
|
||||
"""
|
||||
todo = os.path.join(self._statePath, self._key + '.todo')
|
||||
@@ -67,9 +66,7 @@ class Operator:
|
||||
self._resuming = True
|
||||
|
||||
def save(self):
|
||||
"""
|
||||
Saves the state to the given state path using the given key.
|
||||
"""
|
||||
"""Save the state to the given state path using the given key."""
|
||||
# only save todo first time
|
||||
todo = os.path.join(self._statePath, self._key + '.todo')
|
||||
if not os.path.exists(todo):
|
||||
@@ -88,9 +85,7 @@ class Operator:
|
||||
handle.write('%s %s\n' % (name, data))
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Execute the operations
|
||||
"""
|
||||
"""Execute the operations."""
|
||||
|
||||
def __next__(self):
|
||||
operation = self._todo[len(self._done)]
|
||||
@@ -110,10 +105,10 @@ class FileRenamer(Operator):
|
||||
"""
|
||||
Add a rename operation.
|
||||
|
||||
:param source: source filename
|
||||
:type source: str
|
||||
:param source: source filename
|
||||
:type source: str
|
||||
:param destination: destination filename
|
||||
:type destination: str
|
||||
:type destination: str
|
||||
"""
|
||||
|
||||
|
||||
@@ -122,27 +117,27 @@ class Operation:
|
||||
def verify(self):
|
||||
"""
|
||||
Check if the operation will succeed in the current conditions.
|
||||
Consider this a pre-flight check.
|
||||
|
||||
Consider this a pre-flight check.
|
||||
Does not eliminate the need to handle errors as they happen.
|
||||
"""
|
||||
|
||||
def do(self):
|
||||
"""
|
||||
Perform the operation.
|
||||
"""
|
||||
"""Perform the operation."""
|
||||
pass
|
||||
|
||||
def redo(self):
|
||||
"""
|
||||
Perform the operation, without knowing if it already has been
|
||||
(partly) performed.
|
||||
Perform the operation.
|
||||
|
||||
Perform it without knowing if it already has been (partly) performed.
|
||||
"""
|
||||
self.do()
|
||||
|
||||
def serialize(self):
|
||||
"""
|
||||
Serialize the operation.
|
||||
|
||||
The return value should bu usable with :any:`deserialize`
|
||||
|
||||
:rtype: str
|
||||
@@ -152,7 +147,7 @@ class Operation:
|
||||
"""
|
||||
Deserialize the operation with the given operation data.
|
||||
|
||||
:type data: str
|
||||
:type data: str
|
||||
"""
|
||||
raise NotImplementedError
|
||||
deserialize = classmethod(deserialize)
|
||||
|
||||
@@ -25,9 +25,7 @@ class LoggableMultiSeparateTask(task.MultiSeparateTask):
|
||||
|
||||
|
||||
class PopenTask(task.Task):
|
||||
"""
|
||||
I am a task that runs a command using Popen.
|
||||
"""
|
||||
"""Task that runs a command using Popen."""
|
||||
|
||||
logCategory = 'PopenTask'
|
||||
bufsize = 1024
|
||||
@@ -117,31 +115,21 @@ class PopenTask(task.Task):
|
||||
# self.stop()
|
||||
|
||||
def readbytesout(self, bytes_stdout):
|
||||
"""
|
||||
Called when bytes have been read from stdout.
|
||||
"""
|
||||
"""Call when bytes have been read from stdout."""
|
||||
pass
|
||||
|
||||
def readbyteserr(self, bytes_stderr):
|
||||
"""
|
||||
Called when bytes have been read from stderr.
|
||||
"""
|
||||
"""Call when bytes have been read from stderr."""
|
||||
pass
|
||||
|
||||
def done(self):
|
||||
"""
|
||||
Called when the command completed successfully.
|
||||
"""
|
||||
"""Call when the command completed successfully."""
|
||||
pass
|
||||
|
||||
def failed(self):
|
||||
"""
|
||||
Called when the command failed.
|
||||
"""
|
||||
"""Call when the command failed."""
|
||||
pass
|
||||
|
||||
def commandMissing(self):
|
||||
"""
|
||||
Called when the command is missing.
|
||||
"""
|
||||
"""Call when the command is missing."""
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user