summaryrefslogtreecommitdiffstats
path: root/deluge/ui/ui_entry.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/ui_entry.py')
-rw-r--r--deluge/ui/ui_entry.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/deluge/ui/ui_entry.py b/deluge/ui/ui_entry.py
new file mode 100644
index 0000000..e185fda
--- /dev/null
+++ b/deluge/ui/ui_entry.py
@@ -0,0 +1,140 @@
+#
+# Copyright (C) 2007 Andrew Resch <andrewresch@gmail.com>
+# Copyright (C) 2010 Pedro Algarvio <pedro@algarvio.me>
+#
+# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with
+# the additional special exception to link portions of this program with the OpenSSL library.
+# See LICENSE for more details.
+#
+
+# The main starting point for the program. This function is called when the
+# user runs the command 'deluge'.
+
+"""Main starting point for Deluge"""
+import argparse
+import logging
+import os
+import sys
+
+import pkg_resources
+
+import deluge.common
+import deluge.configmanager
+from deluge.argparserbase import ArgParserBase
+from deluge.i18n import setup_translation
+
+DEFAULT_PREFS = {'default_ui': 'gtk'}
+
+AMBIGUOUS_CMD_ARGS = ('-h', '--help', '-v', '-V', '--version')
+
+
+def start_ui():
+ """Entry point for ui script"""
+ setup_translation()
+
+ # Get the registered UI entry points
+ ui_entrypoints = {}
+ for entrypoint in pkg_resources.iter_entry_points('deluge.ui'):
+ try:
+ ui_entrypoints[entrypoint.name] = entrypoint.load()
+ except ImportError:
+ # Unable to load entrypoint so skip adding it.
+ pass
+
+ ui_titles = sorted(ui_entrypoints)
+
+ def add_ui_options_group(_parser):
+ """Function to enable reuse of UI Options group"""
+ group = _parser.add_argument_group(_('UI Options'))
+ group.add_argument(
+ '-s',
+ '--set-default-ui',
+ dest='default_ui',
+ choices=ui_titles,
+ help=_('Set the default UI to be run, when no UI is specified'),
+ )
+ return _parser
+
+ # Setup parser with Common Options and add UI Options group.
+ parser = add_ui_options_group(ArgParserBase())
+
+ # Parse and handle common/process group options
+ options = parser.parse_known_ui_args(sys.argv, withhold=AMBIGUOUS_CMD_ARGS)
+
+ config = deluge.configmanager.ConfigManager('ui.conf', DEFAULT_PREFS)
+ log = logging.getLogger(__name__)
+ log.info('Deluge ui %s', deluge.common.get_version())
+
+ if options.default_ui:
+ config['default_ui'] = options.default_ui
+ config.save()
+ log.info('The default UI has been changed to %s', options.default_ui)
+ sys.exit(0)
+
+ default_ui = config['default_ui']
+ config.save() # Save in case config didn't already exist.
+ del config
+
+ # We have parsed and got the config dir needed to get the default UI
+ # Now create a parser for choosing the UI. We reuse the ui option group for
+ # parsing to succeed and the text displayed to user, but result is not used.
+ parser = add_ui_options_group(ArgParserBase(common_help=True))
+
+ # Create subparser for each registered UI. Empty title is used to remove unwanted positional text.
+ subparsers = parser.add_subparsers(
+ dest='selected_ui',
+ metavar='{%s} [UI args]' % ','.join(ui_titles),
+ title=None,
+ help=_('Alternative UI to launch, with optional ui args \n (default UI: *)'),
+ )
+ for ui in ui_titles:
+ parser_ui = subparsers.add_parser(
+ ui,
+ common_help=False,
+ help=getattr(ui_entrypoints[ui], 'cmd_description', ''),
+ )
+ parser_ui.add_argument('ui_args', nargs=argparse.REMAINDER)
+ # If the UI is set as default, indicate this in help by prefixing with a star.
+ subactions = subparsers._get_subactions()
+ prefix = '*' if ui == default_ui else ' '
+ subactions[-1].metavar = f'{prefix} {ui}'
+
+ # Insert a default UI subcommand unless one of the ambiguous_args are specified
+ parser.set_default_subparser(default_ui, abort_opts=AMBIGUOUS_CMD_ARGS)
+
+ # Only parse known arguments to leave the UIs to show a help message if parsing fails.
+ options, remaining = parser.parse_known_args()
+ selected_ui = options.selected_ui
+ ui_args = remaining + options.ui_args
+
+ # Remove the UI argument before launching the UI.
+ sys.argv.remove(selected_ui)
+
+ try:
+ ui = ui_entrypoints[selected_ui](
+ prog=f'{os.path.basename(sys.argv[0])} {selected_ui}', ui_args=ui_args
+ )
+ except KeyError:
+ log.error(
+ 'Unable to find chosen UI: "%s". Please choose a different UI '
+ 'or use "--set-default-ui" to change default UI.',
+ selected_ui,
+ )
+ except ImportError as ex:
+ import traceback
+
+ error_type, error_value, tb = sys.exc_info()
+ stack = traceback.extract_tb(tb)
+ last_frame = stack[-1]
+ if last_frame[0] == __file__:
+ log.error(
+ 'Unable to find chosen UI: "%s". Please choose a different UI '
+ 'or use "--set-default-ui" to change default UI.',
+ selected_ui,
+ )
+ else:
+ log.exception(ex)
+ log.error('Encountered an error launching the request UI: %s', selected_ui)
+ sys.exit(1)
+ else:
+ ui.start()