Merge branch 'master' into python3
This commit is contained in:
@@ -10,7 +10,7 @@ install:
|
||||
# Dependencies
|
||||
- sudo apt-get -qq update
|
||||
- sudo pip install --upgrade -qq pip
|
||||
- sudo apt-get -qq install cdparanoia cdrdao flac libcdio-dev libiso9660-dev libsndfile1-dev python-cddb python-gobject python-musicbrainzngs python-mutagen python-setuptools sox swig libcdio-utils
|
||||
- sudo apt-get -qq install cdparanoia cdrdao flac gir1.2-glib-2.0 libcdio-dev libiso9660-dev libsndfile1-dev python-cddb python-gi python-musicbrainzngs python-mutagen python-setuptools sox swig libcdio-utils
|
||||
- sudo pip install pycdio==0.21 requests
|
||||
|
||||
# Testing dependencies
|
||||
|
||||
@@ -48,7 +48,7 @@ https://web.archive.org/web/20160528213242/https://thomas.apestaart.org/thomas/t
|
||||
- Performs Test & Copy rips
|
||||
- Verifies rip accuracy using the [AccurateRip database](http://www.accuraterip.com/)
|
||||
- Uses [MusicBrainz](https://musicbrainz.org/doc/About) for metadata lookup
|
||||
- Supports reading the [pre-emphasis](http://wiki.hydrogenaud.io/index.php?title=Pre-emphasis) flag embedded into some CDs (and correctly tags the resulting rip)
|
||||
- Supports reading the [pre-emphasis](http://wiki.hydrogenaud.io/index.php?title=Pre-emphasis) flag embedded into some CDs (and correctly tags the resulting rip). _Currently whipper only reports the pre-emphasis flag value stored in the TOC._
|
||||
- Detects and rips _non digitally silent_ [Hidden Track One Audio](http://wiki.hydrogenaud.io/index.php?title=HTOA) (HTOA)
|
||||
- Provides batch ripping capabilities
|
||||
- Provides templates for file and directory naming
|
||||
@@ -78,7 +78,8 @@ Whipper relies on the following packages in order to run correctly and provide a
|
||||
- [cd-paranoia](https://www.gnu.org/software/libcdio/), for the actual ripping
|
||||
- To avoid bugs it's advised to use `cd-paranoia` **10.2+0.94+2-2**
|
||||
- [cdrdao](http://cdrdao.sourceforge.net/), for session, TOC, pre-gap, and ISRC extraction
|
||||
- [python-gobject-2](https://packages.debian.org/en/jessie/python-gobject-2), required by `task.py`
|
||||
- [GObject Introspection](https://wiki.gnome.org/Projects/GObjectIntrospection), to provide GLib-2.0 methods used by `task.py`
|
||||
- [PyGObject](https://pypi.org/project/PyGObject/), required by `task.py`
|
||||
- [python-musicbrainzngs](https://github.com/alastair/python-musicbrainzngs), for metadata lookup
|
||||
- [python-mutagen](https://pypi.python.org/pypi/mutagen), for tagging support
|
||||
- [python-setuptools](https://pypi.python.org/pypi/setuptools), for installation, plugins support
|
||||
|
||||
@@ -24,7 +24,6 @@ import os
|
||||
import glob
|
||||
import sys
|
||||
import logging
|
||||
import gobject
|
||||
from whipper.command.basecommand import BaseCommand
|
||||
from whipper.common import (
|
||||
accurip, config, drive, program, task
|
||||
@@ -32,8 +31,6 @@ from whipper.common import (
|
||||
from whipper.program import cdrdao, cdparanoia, utils
|
||||
from whipper.result import result
|
||||
|
||||
gobject.threads_init()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
@@ -18,12 +18,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from whipper.command.basecommand import BaseCommand
|
||||
from whipper.common import accurip, config, program
|
||||
from whipper.common import encode
|
||||
from whipper.extern.task import task
|
||||
from whipper.image import image
|
||||
from whipper.result import result
|
||||
@@ -32,78 +30,6 @@ import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Retag(BaseCommand):
|
||||
summary = "retag image files"
|
||||
description = """
|
||||
Retags the image from the given .cue files with tags obtained from MusicBrainz.
|
||||
"""
|
||||
|
||||
def add_arguments(self):
|
||||
self.parser.add_argument('cuefile', nargs='+', action='store',
|
||||
help="cue file to load rip image from")
|
||||
self.parser.add_argument(
|
||||
'-R', '--release-id',
|
||||
action="store", dest="release_id",
|
||||
help="MusicBrainz release id to match to (if there are multiple)"
|
||||
)
|
||||
self.parser.add_argument(
|
||||
'-p', '--prompt',
|
||||
action="store_true", dest="prompt",
|
||||
help="Prompt if there are multiple matching releases"
|
||||
)
|
||||
self.parser.add_argument(
|
||||
'-c', '--country',
|
||||
action="store", dest="country",
|
||||
help="Filter releases by country"
|
||||
)
|
||||
|
||||
def do(self):
|
||||
|
||||
prog = program.Program(config.Config(), stdout=sys.stdout)
|
||||
runner = task.SyncRunner()
|
||||
|
||||
for arg in self.options.cuefile:
|
||||
sys.stdout.write('Retagging image %r\n' % arg)
|
||||
arg = arg.decode('utf-8')
|
||||
cueImage = image.Image(arg)
|
||||
cueImage.setup(runner)
|
||||
|
||||
mbdiscid = cueImage.table.getMusicBrainzDiscId()
|
||||
sys.stdout.write('MusicBrainz disc id is %s\n' % mbdiscid)
|
||||
|
||||
sys.stdout.write("MusicBrainz lookup URL %s\n" %
|
||||
cueImage.table.getMusicBrainzSubmitURL())
|
||||
prog.metadata = prog.getMusicBrainz(cueImage.table, mbdiscid,
|
||||
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')
|
||||
continue
|
||||
|
||||
prog.metadata.discid = mbdiscid
|
||||
|
||||
# FIXME: this feels like we're poking at internals.
|
||||
prog.cuePath = arg
|
||||
prog.result = result.RipResult()
|
||||
for track in cueImage.table.tracks:
|
||||
path = cueImage.getRealPath(track.indexes[1].path)
|
||||
|
||||
taglist = prog.getTagList(track.number)
|
||||
logger.debug(
|
||||
'possibly retagging %r from cue path %r with taglist %r',
|
||||
path, arg, taglist)
|
||||
t = encode.SafeRetagTask(path, taglist)
|
||||
runner.run(t)
|
||||
path = os.path.basename(path)
|
||||
if t.changed:
|
||||
print('Retagged %s' % path)
|
||||
else:
|
||||
print('%s already tagged correctly' % path)
|
||||
print()
|
||||
|
||||
|
||||
class Verify(BaseCommand):
|
||||
summary = "verify image"
|
||||
description = """
|
||||
@@ -145,10 +71,8 @@ class Image(BaseCommand):
|
||||
summary = "handle images"
|
||||
description = """
|
||||
Handle disc images. Disc images are described by a .cue file.
|
||||
Disc images can be encoded to another format (for example, to make a
|
||||
compressed encoding), retagged and verified.
|
||||
Disc images can be verified.
|
||||
"""
|
||||
subcommands = {
|
||||
'verify': Verify,
|
||||
'retag': Retag
|
||||
}
|
||||
|
||||
@@ -23,15 +23,12 @@ import os
|
||||
import sys
|
||||
import tempfile
|
||||
import logging
|
||||
import gobject
|
||||
from whipper.command.basecommand import BaseCommand
|
||||
from whipper.common import accurip, common, config, drive
|
||||
from whipper.common import task as ctask
|
||||
from whipper.program import arc, cdrdao, cdparanoia, utils
|
||||
from whipper.extern.task import task
|
||||
|
||||
gobject.threads_init()
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# see http://www.accuraterip.com/driveoffsets.htm
|
||||
|
||||
@@ -542,11 +542,6 @@ class Program:
|
||||
trackResult.filename = t.path
|
||||
logger.info('Filename changed to %r', trackResult.filename)
|
||||
|
||||
def retagImage(self, runner, taglists):
|
||||
cueImage = image.Image(self.cuePath)
|
||||
t = image.ImageRetagTask(cueImage, taglists)
|
||||
runner.run(t)
|
||||
|
||||
def verifyImage(self, runner, table):
|
||||
"""
|
||||
verify table against accuraterip and cue_path track lengths
|
||||
|
||||
21
whipper/extern/task/task.py
vendored
21
whipper/extern/task/task.py
vendored
@@ -18,9 +18,15 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with whipper. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import gobject
|
||||
try:
|
||||
from gi.repository import GLib as gobject
|
||||
except ImportError:
|
||||
import gobject
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TaskException(Exception):
|
||||
@@ -70,21 +76,14 @@ class LogStub(object):
|
||||
I am a stub for a log interface.
|
||||
"""
|
||||
|
||||
# log stubs
|
||||
def log(self, message, *args):
|
||||
pass
|
||||
logger.info(message, *args)
|
||||
|
||||
def debug(self, message, *args):
|
||||
pass
|
||||
|
||||
def info(self, message, *args):
|
||||
pass
|
||||
logger.debug(message, *args)
|
||||
|
||||
def warning(self, message, *args):
|
||||
pass
|
||||
|
||||
def error(self, message, *args):
|
||||
pass
|
||||
logger.warning(message, *args)
|
||||
|
||||
|
||||
class Task(LogStub):
|
||||
|
||||
Reference in New Issue
Block a user