summaryrefslogtreecommitdiffstats
path: root/deluge/ui/console/parser.py
diff options
context:
space:
mode:
Diffstat (limited to 'deluge/ui/console/parser.py')
-rw-r--r--deluge/ui/console/parser.py140
1 files changed, 140 insertions, 0 deletions
diff --git a/deluge/ui/console/parser.py b/deluge/ui/console/parser.py
new file mode 100644
index 0000000..c0686b1
--- /dev/null
+++ b/deluge/ui/console/parser.py
@@ -0,0 +1,140 @@
+#
+# Copyright (C) 2016 bendikro <bro.devel+deluge@gmail.com>
+#
+# 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.
+#
+
+import argparse
+import shlex
+
+import deluge.component as component
+from deluge.ui.console.utils.colors import ConsoleColorFormatter
+
+
+class OptionParserError(Exception):
+ pass
+
+
+class ConsoleBaseParser(argparse.ArgumentParser):
+ def format_help(self):
+ """Differs from ArgumentParser.format_help by adding the raw epilog
+ as formatted in the string. Default behavior mangles the formatting.
+
+ """
+ # Handle epilog manually to keep the text formatting
+ epilog = self.epilog
+ self.epilog = ''
+ help_str = super().format_help()
+ if epilog is not None:
+ help_str += epilog
+ self.epilog = epilog
+ return help_str
+
+
+class ConsoleCommandParser(ConsoleBaseParser):
+ def _split_args(self, args):
+ command_options = []
+ for a in args:
+ if not a:
+ continue
+ if ';' in a:
+ cmd_lines = [arg.strip() for arg in a.split(';')]
+ elif ' ' in a:
+ cmd_lines = [a]
+ else:
+ continue
+
+ for cmd_line in cmd_lines:
+ cmds = shlex.split(cmd_line)
+ cmd_options = super().parse_args(args=cmds)
+ cmd_options.command = cmds[0]
+ command_options.append(cmd_options)
+
+ return command_options
+
+ def parse_args(self, args=None):
+ """Parse known UI args and handle common and process group options.
+
+ Notes:
+ If started by deluge entry script this has already been done.
+
+ Args:
+ args (list, optional): The arguments to parse.
+
+ Returns:
+ argparse.Namespace: The parsed arguments.
+ """
+ from deluge.ui.ui_entry import AMBIGUOUS_CMD_ARGS
+
+ self.base_parser.parse_known_ui_args(args, withhold=AMBIGUOUS_CMD_ARGS)
+
+ multi_command = self._split_args(args)
+ # If multiple commands were passed to console
+ if multi_command:
+ # With multiple commands, normal parsing will fail, so only parse
+ # known arguments using the base parser, and then set
+ # options.parsed_cmds to the already parsed commands
+ options, remaining = self.base_parser.parse_known_args(args=args)
+ options.parsed_cmds = multi_command
+ else:
+ subcommand = False
+ if hasattr(self.base_parser, 'subcommand'):
+ subcommand = getattr(self.base_parser, 'subcommand')
+ if not subcommand:
+ # We must use parse_known_args to handle case when no subcommand
+ # is provided, because argparse does not support parsing without
+ # a subcommand
+ options, remaining = self.base_parser.parse_known_args(args=args)
+ # If any options remain it means they do not exist. Reparse with
+ # parse_args to trigger help message
+ if remaining:
+ options = self.base_parser.parse_args(args=args)
+ options.parsed_cmds = []
+ else:
+ options = super().parse_args(args=args)
+ options.parsed_cmds = [options]
+
+ if not hasattr(options, 'remaining'):
+ options.remaining = []
+
+ return options
+
+
+class OptionParser(ConsoleBaseParser):
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
+ self.formatter = ConsoleColorFormatter()
+
+ def exit(self, status=0, msg=None):
+ self._exit = True
+ if msg:
+ print(msg)
+
+ def error(self, msg):
+ """error(msg : string)
+
+ Print a usage message incorporating 'msg' to stderr and exit.
+ If you override this in a subclass, it should not return -- it
+ should either exit or raise an exception.
+ """
+ raise OptionParserError(msg)
+
+ def print_usage(self, _file=None):
+ console = component.get('ConsoleUI')
+ if self.usage:
+ for line in self.format_usage().splitlines():
+ console.write(line)
+
+ def print_help(self, _file=None):
+ console = component.get('ConsoleUI')
+ console.set_batch_write(True)
+ for line in self.format_help().splitlines():
+ console.write(line)
+ console.set_batch_write(False)
+
+ def format_help(self):
+ """Return help formatted with colors."""
+ help_str = super().format_help()
+ return self.formatter.format_colors(help_str)