* 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
Failed and done can stay unimplemented.
If we read stdout or stderr, reschedule immediately to process
all output before considering the possibility the program stopped.
Log which task we are notifying progress on.
* morituri/common/program.py:
Solve a problem where a release does not have an .id,
which means it's only half in musicbrainz (artist
and title, but no URL to the disc)
add task argument to TaskRunner.schedule so we can get exceptions.
Add .schedule method to Task to pass self.
* morituri/common/checksum.py:
* morituri/common/encode.py:
* morituri/common/gstreamer.py:
* morituri/program/cdparanoia.py:
* morituri/program/cdrdao.py:
Adapt.
Actually raise the exception.
* morituri/common/task.py:
Document interface more clearly.
* morituri/test/test_common_checksum.py:
Use tcommon for test.common
Style fixes.
* morituri/common/common.py:
Add functions to convert a gst.TagList to a dict and compare them.
* morituri/common/task.py:
Add setAndRaiseException which gives us an appropriate
exceptionMessage as if we raised where we called this new function.
Fix AudioLengthTask for the case where we don't have the decoder,
by instead of doing get_state, waiting for an ASYNC_DONE or ERROR
message. Properly raise a gst.GError in that case.
* morituri/common/task.py:
Add some debug.
* morituri/test/test_image_image.py:
After this fix, we now catch the TYPE_NOT_FOUND because of an
empty stream instead of the later gst.QueryError.
* morituri/test/test_common_encode.py:
Let us know what it is if not a gst.QueryError.
Add documentation.
Use a _task counter instead of duplicating tasks to
__tasks; this allows us to add tasks after starting.
Catch Exceptions during next() so that we don't get
stuck in a main loop that doesn't exit.
Raise it later when we're done.
Add an exception ivar for tasks to set an exception on while
running. Make SyncRunner raise it during done()
* morituri/program/cdparanoia.py:
Set an exception if the ripped file doesn't match the expected size
(for example when disc is full)
* morituri/common/taskgtk.py:
Split off GtkProgressRunner in separate module to not import gtk
everywhere.
* examples/ARcalibrate.py:
* examples/ARcue.py:
* examples/gtkchecksum.py:
* examples/trm.py:
Adapt.
Allow a SyncRunner to be constructed with verbose too.
Separate a 'running' verbose mode from that.
Fixes unwanted test output.
* morituri/test/test_image_image.py:
Run without verbosity.
Add a 'described' method so listeners can get proper notification
of description changes, and update their description in between
progress changes.
Add a MultiCombinedTask that reports on progress over all tasks
combined.
* examples/trm.py:
Add a playlist option to the example. Still needs to store results
to pickles, preferably after each completed task.
* morituri/common/checksum.py:
Add audioconvert to make sure we can trm ogg files.
* morituri/common/crc.py:
* morituri/common/task.py:
* morituri/image/image.py:
Add a 'schedule' call to the TaskRunner class, so that we can
abstract things like gobject.timeout_add and reactor.callLater
Pass the runner to the task in Task.start() so a task can call
schedule.
* morituri/common/task.py:
* morituri/image/image.py (added):
Add an object for handling an Image based on a .cue file.
Create a Task for CRC'ing the whole Image.
Make the example use this new task instead.