diff --git a/bin/mopidy b/bin/mopidy index aabf21d3..0472518e 100755 --- a/bin/mopidy +++ b/bin/mopidy @@ -1,5 +1,5 @@ #! /usr/bin/env python if __name__ == '__main__': - from mopidy.core import main + from mopidy.__main__ import main main() diff --git a/mopidy/__main__.py b/mopidy/__main__.py index 169c2754..c55a9940 100644 --- a/mopidy/__main__.py +++ b/mopidy/__main__.py @@ -1,10 +1,163 @@ +import logging +import optparse +import os +import signal +import sys + +import gobject +gobject.threads_init() + + +# Extract any non-GStreamer arguments, and leave the GStreamer arguments for +# processing by GStreamer. This needs to be done before GStreamer is imported, +# so that GStreamer doesn't hijack e.g. ``--help``. +# NOTE This naive fix does not support values like ``bar`` in +# ``--gst-foo bar``. Use equals to pass values, like ``--gst-foo=bar``. + +def is_gst_arg(argument): + return argument.startswith('--gst') or argument == '--help-gst' + +gstreamer_args = [arg for arg in sys.argv[1:] if is_gst_arg(arg)] +mopidy_args = [arg for arg in sys.argv[1:] if not is_gst_arg(arg)] +sys.argv[1:] = gstreamer_args + + # Add ../ to the path so we can run Mopidy from a Git checkout without # installing it on the system. -import os -import sys sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../'))) + +from mopidy import (get_version, settings, OptionalDependencyError, + SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE) +from mopidy.gstreamer import GStreamer +from mopidy.utils import get_class +from mopidy.utils.deps import list_deps_optparse_callback +from mopidy.utils.log import setup_logging +from mopidy.utils.path import get_or_create_folder, get_or_create_file +from mopidy.utils.process import (exit_handler, stop_remaining_actors, + stop_actors_by_class) +from mopidy.utils.settings import list_settings_optparse_callback + + +logger = logging.getLogger('mopidy.main') + + +def main(): + signal.signal(signal.SIGTERM, exit_handler) + loop = gobject.MainLoop() + try: + options = parse_options() + setup_logging(options.verbosity_level, options.save_debug_log) + check_old_folders() + setup_settings(options.interactive) + setup_gstreamer() + setup_mixer() + setup_backend() + setup_frontends() + loop.run() + except SettingsError as e: + logger.error(e.message) + except KeyboardInterrupt: + logger.info(u'Interrupted. Exiting...') + except Exception as e: + logger.exception(e) + finally: + loop.quit() + stop_frontends() + stop_backend() + stop_mixer() + stop_gstreamer() + stop_remaining_actors() + + +def parse_options(): + parser = optparse.OptionParser(version=u'Mopidy %s' % get_version()) + parser.add_option('--help-gst', + action='store_true', dest='help_gst', + help='show GStreamer help options') + parser.add_option('-i', '--interactive', + action='store_true', dest='interactive', + help='ask interactively for required settings which are missing') + parser.add_option('-q', '--quiet', + action='store_const', const=0, dest='verbosity_level', + help='less output (warning level)') + parser.add_option('-v', '--verbose', + action='count', default=1, dest='verbosity_level', + help='more output (debug level)') + parser.add_option('--save-debug-log', + action='store_true', dest='save_debug_log', + help='save debug log to "./mopidy.log"') + parser.add_option('--list-settings', + action='callback', callback=list_settings_optparse_callback, + help='list current settings') + parser.add_option('--list-deps', + action='callback', callback=list_deps_optparse_callback, + help='list dependencies and their versions') + return parser.parse_args(args=mopidy_args)[0] + + +def check_old_folders(): + old_settings_folder = os.path.expanduser(u'~/.mopidy') + + if not os.path.isdir(old_settings_folder): + return + + logger.warning(u'Old settings folder found at %s, settings.py should be ' + 'moved to %s, any cache data should be deleted. See release notes ' + 'for further instructions.', old_settings_folder, SETTINGS_PATH) + + +def setup_settings(interactive): + get_or_create_folder(SETTINGS_PATH) + get_or_create_folder(DATA_PATH) + get_or_create_file(SETTINGS_FILE) + try: + settings.validate(interactive) + except SettingsError, e: + logger.error(e.message) + sys.exit(1) + + +def setup_gstreamer(): + GStreamer.start() + + +def stop_gstreamer(): + stop_actors_by_class(GStreamer) + + +def setup_mixer(): + get_class(settings.MIXER).start() + + +def stop_mixer(): + stop_actors_by_class(get_class(settings.MIXER)) + + +def setup_backend(): + get_class(settings.BACKENDS[0]).start() + + +def stop_backend(): + stop_actors_by_class(get_class(settings.BACKENDS[0])) + + +def setup_frontends(): + for frontend_class_name in settings.FRONTENDS: + try: + get_class(frontend_class_name).start() + except OptionalDependencyError as e: + logger.info(u'Disabled: %s (%s)', frontend_class_name, e) + + +def stop_frontends(): + for frontend_class_name in settings.FRONTENDS: + try: + stop_actors_by_class(get_class(frontend_class_name)) + except OptionalDependencyError: + pass + + if __name__ == '__main__': - from mopidy.core import main main() diff --git a/mopidy/core.py b/mopidy/core.py deleted file mode 100644 index 9ae461d8..00000000 --- a/mopidy/core.py +++ /dev/null @@ -1,136 +0,0 @@ -import logging -import optparse -import os -import signal -import sys - -import gobject -gobject.threads_init() - -# Extract any non-GStreamer arguments, and leave the GStreamer arguments for -# processing by GStreamer. This needs to be done before GStreamer is imported, -# so that GStreamer doesn't hijack e.g. ``--help``. -# NOTE This naive fix does not support values like ``bar`` in -# ``--gst-foo bar``. Use equals to pass values, like ``--gst-foo=bar``. -def is_gst_arg(argument): - return argument.startswith('--gst') or argument == '--help-gst' -gstreamer_args = [arg for arg in sys.argv[1:] if is_gst_arg(arg)] -mopidy_args = [arg for arg in sys.argv[1:] if not is_gst_arg(arg)] -sys.argv[1:] = gstreamer_args - -from mopidy import (get_version, settings, OptionalDependencyError, - SettingsError, DATA_PATH, SETTINGS_PATH, SETTINGS_FILE) -from mopidy.gstreamer import GStreamer -from mopidy.utils import get_class -from mopidy.utils.deps import list_deps_optparse_callback -from mopidy.utils.log import setup_logging -from mopidy.utils.path import get_or_create_folder, get_or_create_file -from mopidy.utils.process import (exit_handler, stop_remaining_actors, - stop_actors_by_class) -from mopidy.utils.settings import list_settings_optparse_callback - -logger = logging.getLogger('mopidy.core') - -def main(): - signal.signal(signal.SIGTERM, exit_handler) - loop = gobject.MainLoop() - try: - options = parse_options() - setup_logging(options.verbosity_level, options.save_debug_log) - check_old_folders() - setup_settings(options.interactive) - setup_gstreamer() - setup_mixer() - setup_backend() - setup_frontends() - loop.run() - except SettingsError as e: - logger.error(e.message) - except KeyboardInterrupt: - logger.info(u'Interrupted. Exiting...') - except Exception as e: - logger.exception(e) - finally: - loop.quit() - stop_frontends() - stop_backend() - stop_mixer() - stop_gstreamer() - stop_remaining_actors() - -def parse_options(): - parser = optparse.OptionParser(version=u'Mopidy %s' % get_version()) - parser.add_option('--help-gst', - action='store_true', dest='help_gst', - help='show GStreamer help options') - parser.add_option('-i', '--interactive', - action='store_true', dest='interactive', - help='ask interactively for required settings which are missing') - parser.add_option('-q', '--quiet', - action='store_const', const=0, dest='verbosity_level', - help='less output (warning level)') - parser.add_option('-v', '--verbose', - action='count', default=1, dest='verbosity_level', - help='more output (debug level)') - parser.add_option('--save-debug-log', - action='store_true', dest='save_debug_log', - help='save debug log to "./mopidy.log"') - parser.add_option('--list-settings', - action='callback', callback=list_settings_optparse_callback, - help='list current settings') - parser.add_option('--list-deps', - action='callback', callback=list_deps_optparse_callback, - help='list dependencies and their versions') - return parser.parse_args(args=mopidy_args)[0] - -def check_old_folders(): - old_settings_folder = os.path.expanduser(u'~/.mopidy') - - if not os.path.isdir(old_settings_folder): - return - - logger.warning(u'Old settings folder found at %s, settings.py should be ' - 'moved to %s, any cache data should be deleted. See release notes ' - 'for further instructions.', old_settings_folder, SETTINGS_PATH) - -def setup_settings(interactive): - get_or_create_folder(SETTINGS_PATH) - get_or_create_folder(DATA_PATH) - get_or_create_file(SETTINGS_FILE) - try: - settings.validate(interactive) - except SettingsError, e: - logger.error(e.message) - sys.exit(1) - -def setup_gstreamer(): - GStreamer.start() - -def stop_gstreamer(): - stop_actors_by_class(GStreamer) - -def setup_mixer(): - get_class(settings.MIXER).start() - -def stop_mixer(): - stop_actors_by_class(get_class(settings.MIXER)) - -def setup_backend(): - get_class(settings.BACKENDS[0]).start() - -def stop_backend(): - stop_actors_by_class(get_class(settings.BACKENDS[0])) - -def setup_frontends(): - for frontend_class_name in settings.FRONTENDS: - try: - get_class(frontend_class_name).start() - except OptionalDependencyError as e: - logger.info(u'Disabled: %s (%s)', frontend_class_name, e) - -def stop_frontends(): - for frontend_class_name in settings.FRONTENDS: - try: - stop_actors_by_class(get_class(frontend_class_name)) - except OptionalDependencyError: - pass