If MusicBrainz returns data for the CD being ripped but no release date
is returned, we attempt to set the DATE tag to None (which is caught by
mutagen). To resolve this, check if there is a value for release date
before setting.
* Add encoding using Xiph.org 'flac' program.
This adds a FlacEncodeTask that encodes wave files to flac files.
This commit also replaces morituri's EncodeTask with FlacEncodeTask, however, in
morituri, EncodeTask also does the tagging.
FlacEncodeTask will not perform the tagging.
So we will need an extra task for the tagging - this will be added soon.
Meanwhile, do not merge this commit to master yet.
* Add tagging using mutagen.
Replace the gstreamer tagging code with mutagen tagging code.
getTagList is rewritten to return a dictionary of tags, which are then simply
passed to mutagen.
The way it is set up right now is not the best - I don't think it makes sense
for tagging to take place in program/cdparanoia.py ; but this is how the current
code did it.
I suggest that, when we rip out all the gstreamer code, we also move the tagging
to a more sensible place; and then also make the tagging not be an actual
'task.Task'.
* Add gstreamer-less CRC32 version
Only works on wave files at this point. Should not be a problem, I think.
* Use proper musicbrainz tags and ALBUM tag.
* Add mutagen to .travis.yml
There's now a "stable" `whipper` package, which is likely the main one
we want to link to. I kept in the link to the `whipper-git` package at
the end, but also added a link to the non-git `whipper` package.
If cdparanoia can't work around the audio caching of a drive,
defeats_cache = False is written to the config. However, when it is
read back the string 'False' ends up being converted to True (as it is
not an empty string).
This corrects the behaviour when reading the value back and adds tests
to make sure that both True and False can be correctly retrieved from
the config.
If the drive offset or cache status are unknown, 'drive list' suggests
running 'rip offset find' or 'rip drive analyze'. Update these to
refer to whipper instead.
* introduce logcommand.Lager, Whipper(); use argparse for whipper image commands, stub logging
* update Lager docstring to mention config.Config()
* make incorrect subcommand and --version work on toplevel command
* migrate accurip show, expand Lager, do not attempt to return from Lager.__init__.
* migrate offset find, add Lager.error
* correct offset find drive symlink handling
* migrate drive
* change Lager.__init__(prog) to arg from kwarg
* but actually
* remove Whipper.usage
* add and use Lager.device_option() context manager
* help I married an axe murderer
* use unified options namespace for entire command tree
* migrate whipper cd without comprehensive config loading
* switch to logging module
- use logging instead of flog for non-extern modules
- use WHIPPER_DEBUG and WHIPPER_LOGFILE env variables
* convert self.log calls to logger.debug
* convert self.error calls to logger.error
* remove log.Loggable, use logger not logging
* Logging conversion continues
- Convert log.* calls to logger.*
- Remove morituri.common.log imports
* remove morituri.common.log from tests
* remove extern/flog, bare minimum Debug conversion
* update README for logging changes
* update soxi to use logging
* refactor Lager for more declarative subcommands
* Refactor Lager.device_option:
- inline into __init__
- throw IOError instead of Exception for missing drives
- remove CommandError checking in rip/main
* rename rip to whipper in rip.main
* convert rip.debug commands
* Rename logcommand.Lager to command.BaseCommand
- remove command.CommandError occurrences
- remove python-command external module
* remove submodules from README, update rclog formatter
* update minor ambiguity in readme for command invocation
* update version number to match setup.py
* remove gitmodules
* update version number in tests as well (boo)
* convert logger.error to logger.critical
* Change morituri.rip to morituri.command
- mv common.command to command.basecommand
- move TEMPLATES used only by rip.cd out of rip.common
- update entry point for command to command.main
* update basecommand documentation
* go pyflaking: import fixing
* replace self.stdout with sys.stdout
* remove BaseCommand.config, alphabetise imports
* convert self.stdXXX leftovers
* convert last getRootCommand to config.Config
* convert last getExceptionMessage's to str
* change musicbrainz useragent to whipper
Added clearer info on required GStreamer-related packages.
I got a `no module named gst` while testing on Ubuntu 16.04 and figured it would be clearer to name the package to install to avoid that.
a TaskException already wraps another exception; raising it gives a
hard-to-read multi-line message instead of showing the clean wrapped
original backtrace; for comparison, an asserton error in image.py line
253:
exception AssertionError at /home/chrysn/git/whipper/morituri/image/image.py:253: stop(): Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)
Traceback (most recent call last):
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 497, in _startWrap
task.start(self)
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 395, in start
BaseMultiTask.start(self, runner)
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 330, in start
self.next()
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 401, in next
BaseMultiTask.next(self)
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 351, in next
self.stop()
File "/home/chrysn/git/whipper/morituri/image/image.py", line 253, in stop
assert taskk.length is not None, "Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)"
AssertionError: Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)
vs.
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/home/chrysn/git/whipper/morituri/rip/main.py", line 27, in main
ret = c.parse(sys.argv[1:])
File "/home/chrysn/git/whipper/morituri/rip/main.py", line 94, in parse
logcommand.LogCommand.parse(self, argv)
File "/home/chrysn/git/whipper/morituri/common/logcommand.py", line 62, in parse
command.Command.parse(self, argv)
File "/home/chrysn/git/whipper/morituri/extern/command/command.py", line 401, in parse
return self.subCommands[command].parse(args[1:])
File "/home/chrysn/git/whipper/morituri/common/logcommand.py", line 62, in parse
command.Command.parse(self, argv)
File "/home/chrysn/git/whipper/morituri/extern/command/command.py", line 401, in parse
return self.subCommands[command].parse(args[1:])
File "/home/chrysn/git/whipper/morituri/common/logcommand.py", line 62, in parse
command.Command.parse(self, argv)
File "/home/chrysn/git/whipper/morituri/extern/command/command.py", line 363, in parse
ret = self.do(args)
File "/home/chrysn/git/whipper/morituri/rip/image.py", line 184, in do
cueImage.setup(runner)
File "/home/chrysn/git/whipper/morituri/image/image.py", line 75, in setup
runner.run(verify)
File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 490, in run
raise TaskException(task.exception, message=msg)
morituri.extern.task.task.TaskException: (AssertionError('Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)',), 'exception AssertionError at /home/chrysn/git/whipper/morituri/image/image.py:253: stop(): Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)\nTraceback (most recent call last):\n File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 497, in _startWrap\n task.start(self)\n File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 395, in start\n BaseMultiTask.start(self, runner)\n File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 330, in start\n self.next()\n File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 401, in next\n BaseMultiTask.next(self)\n File "/home/chrysn/git/whipper/morituri/extern/task/task.py", line 351, in next\n self.stop()\n File "/home/chrysn/git/whipper/morituri/image/image.py", line 253, in stop\n assert taskk.length is not None, "Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)"\nAssertionError: Track length was not found; look for earlier errors in debug log (set RIP_DEBUG=4)\n')
* Use extensions soxi understands (ie. ".flac")
* Actually test for result correctness on files with odd characters in
their names by copying the test track
* Relax the requirements on the "track absent" task to only raise some
TaskError (the previously tested behavior was backend dependent, and
the application did not actually depend on that behavior)
* update HACKING to mention pep8, data structures, and more test discs
* add notice of TODO deprecation
* remove ChangeLog, NEWS, and RELEASE from new versions
* rename COPYING to LICENSE