mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-02 22:48:40 +00:00
[Console] Fix to console argument parsing
When starting console with './deluge-console', providing loggin level '-L info' would fail to parse as it identified 'info' as a subcommand.
This commit is contained in:
parent
98eb810f89
commit
4751b33d0c
5 changed files with 235 additions and 62 deletions
|
@ -1,4 +1,12 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
@ -20,6 +28,7 @@ from . import common
|
||||||
from .basetest import BaseTestCase
|
from .basetest import BaseTestCase
|
||||||
|
|
||||||
sys_stdout = sys.stdout
|
sys_stdout = sys.stdout
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
|
||||||
class TestStdout(object):
|
class TestStdout(object):
|
||||||
|
@ -31,12 +40,30 @@ class TestStdout(object):
|
||||||
setattr(self, a, getattr(sys_stdout, a))
|
setattr(self, a, getattr(sys_stdout, a))
|
||||||
|
|
||||||
def write(self, *data, **kwargs):
|
def write(self, *data, **kwargs):
|
||||||
print(data, file=self.out)
|
print(*data, file=self.out, end="")
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
self.out.flush()
|
self.out.flush()
|
||||||
|
|
||||||
|
|
||||||
|
class UIBaseTestCase(object):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.var = dict()
|
||||||
|
|
||||||
|
def set_up(self):
|
||||||
|
common.set_tmp_config_dir()
|
||||||
|
return component.start()
|
||||||
|
|
||||||
|
def tear_down(self):
|
||||||
|
return component.shutdown()
|
||||||
|
|
||||||
|
def exec_command(self):
|
||||||
|
if DEBUG:
|
||||||
|
print("Executing: '%s'\n" % sys.argv, file=sys_stdout)
|
||||||
|
self.var["start_cmd"]()
|
||||||
|
|
||||||
|
|
||||||
class DelugeEntryTestCase(BaseTestCase):
|
class DelugeEntryTestCase(BaseTestCase):
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
|
@ -91,61 +118,142 @@ class DelugeEntryTestCase(BaseTestCase):
|
||||||
self.assertEqual(_level[0], "info")
|
self.assertEqual(_level[0], "info")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.gtkui
|
class GtkUIBaseTestCase(UIBaseTestCase):
|
||||||
class GtkUIEntryTestCase(BaseTestCase):
|
"""Implement all GtkUI tests here"""
|
||||||
|
|
||||||
def set_up(self):
|
|
||||||
common.set_tmp_config_dir()
|
|
||||||
return component.start()
|
|
||||||
|
|
||||||
def tear_down(self):
|
|
||||||
return component.shutdown()
|
|
||||||
|
|
||||||
def test_start_gtkui(self):
|
def test_start_gtkui(self):
|
||||||
self.patch(sys, "argv", ["./deluge", "gtk"])
|
self.patch(sys, "argv", self.var["sys_arg_cmd"])
|
||||||
|
|
||||||
from deluge.ui.gtkui import gtkui
|
from deluge.ui.gtkui import gtkui
|
||||||
with mock.patch.object(gtkui.GtkUI, "start", autospec=True):
|
with mock.patch.object(gtkui.GtkUI, "start", autospec=True):
|
||||||
ui_entry.start_ui()
|
self.exec_command()
|
||||||
|
|
||||||
|
|
||||||
class WebUIEntryTestCase(BaseTestCase):
|
@pytest.mark.gtkui
|
||||||
|
class GtkUIDelugeScriptEntryTestCase(BaseTestCase, GtkUIBaseTestCase):
|
||||||
|
|
||||||
|
def __init__(self, testname):
|
||||||
|
BaseTestCase.__init__(self, testname)
|
||||||
|
GtkUIBaseTestCase.__init__(self)
|
||||||
|
self.var["cmd_name"] = "deluge gtk"
|
||||||
|
self.var["start_cmd"] = ui_entry.start_ui
|
||||||
|
self.var["sys_arg_cmd"] = ["./deluge", "gtk"]
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
common.set_tmp_config_dir()
|
GtkUIBaseTestCase.set_up(self)
|
||||||
return component.start()
|
|
||||||
|
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
return component.shutdown()
|
GtkUIBaseTestCase.tear_down(self)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.gtkui
|
||||||
|
class GtkUIScriptEntryTestCase(BaseTestCase, GtkUIBaseTestCase):
|
||||||
|
|
||||||
|
def __init__(self, testname):
|
||||||
|
BaseTestCase.__init__(self, testname)
|
||||||
|
GtkUIBaseTestCase.__init__(self)
|
||||||
|
from deluge.ui import gtkui
|
||||||
|
self.var["cmd_name"] = "deluge-gtk"
|
||||||
|
self.var["start_cmd"] = gtkui.start
|
||||||
|
self.var["sys_arg_cmd"] = ["./deluge-gtk"]
|
||||||
|
|
||||||
|
def set_up(self):
|
||||||
|
GtkUIBaseTestCase.set_up(self)
|
||||||
|
|
||||||
|
def tear_down(self):
|
||||||
|
GtkUIBaseTestCase.tear_down(self)
|
||||||
|
|
||||||
|
|
||||||
|
class DelugeWebMock(DelugeWeb):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
kwargs["daemon"] = False
|
||||||
|
DelugeWeb.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class WebUIBaseTestCase(UIBaseTestCase):
|
||||||
|
"""Implement all WebUI tests here"""
|
||||||
|
|
||||||
def test_start_webserver(self):
|
def test_start_webserver(self):
|
||||||
self.patch(sys, "argv", ["./deluge", "web", "--do-not-daemonize"])
|
self.patch(sys, "argv", self.var["sys_arg_cmd"])
|
||||||
|
self.patch(deluge.ui.web.server, "DelugeWeb", DelugeWebMock)
|
||||||
|
self.exec_command()
|
||||||
|
|
||||||
class DelugeWebMock(DelugeWeb):
|
def test_start_web_with_log_level(self):
|
||||||
def __init__(self, *args, **kwargs):
|
_level = []
|
||||||
kwargs["daemon"] = False
|
|
||||||
DelugeWeb.__init__(self, *args, **kwargs)
|
def setup_logger(level="error", filename=None, filemode="w", logrotate=None):
|
||||||
|
_level.append(level)
|
||||||
|
|
||||||
|
self.patch(deluge.log, "setup_logger", setup_logger)
|
||||||
|
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["-L", "info"])
|
||||||
|
|
||||||
|
config = deluge.configmanager.ConfigManager("ui.conf", ui_entry.DEFAULT_PREFS)
|
||||||
|
config.config["default_ui"] = "web"
|
||||||
|
config.save()
|
||||||
|
|
||||||
self.patch(deluge.ui.web.server, "DelugeWeb", DelugeWebMock)
|
self.patch(deluge.ui.web.server, "DelugeWeb", DelugeWebMock)
|
||||||
ui_entry.start_ui()
|
self.exec_command()
|
||||||
|
self.assertEqual(_level[0], "info")
|
||||||
|
|
||||||
|
|
||||||
class ConsoleUIBaseTestCase(object):
|
class WebUIScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, testname):
|
||||||
self.var = dict()
|
BaseTestCase.__init__(self, testname)
|
||||||
|
WebUIBaseTestCase.__init__(self)
|
||||||
|
self.var["cmd_name"] = "deluge-web"
|
||||||
|
self.var["start_cmd"] = deluge.ui.web.start
|
||||||
|
self.var["sys_arg_cmd"] = ["./deluge-web", "--do-not-daemonize"]
|
||||||
|
|
||||||
def set_up(self):
|
def set_up(self):
|
||||||
common.set_tmp_config_dir()
|
WebUIBaseTestCase.set_up(self)
|
||||||
return component.start()
|
|
||||||
|
|
||||||
def tear_down(self):
|
def tear_down(self):
|
||||||
return component.shutdown()
|
WebUIBaseTestCase.tear_down(self)
|
||||||
|
|
||||||
|
|
||||||
|
class WebUIDelugeScriptEntryTestCase(BaseTestCase, WebUIBaseTestCase):
|
||||||
|
|
||||||
|
def __init__(self, testname):
|
||||||
|
BaseTestCase.__init__(self, testname)
|
||||||
|
WebUIBaseTestCase.__init__(self)
|
||||||
|
self.var["cmd_name"] = "deluge web"
|
||||||
|
self.var["start_cmd"] = ui_entry.start_ui
|
||||||
|
self.var["sys_arg_cmd"] = ["./deluge", "web", "--do-not-daemonize"]
|
||||||
|
|
||||||
|
def set_up(self):
|
||||||
|
WebUIBaseTestCase.set_up(self)
|
||||||
|
|
||||||
|
def tear_down(self):
|
||||||
|
WebUIBaseTestCase.tear_down(self)
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleUIBaseTestCase(UIBaseTestCase):
|
||||||
|
"""Implement all Console tests here"""
|
||||||
|
|
||||||
def test_start_console(self):
|
def test_start_console(self):
|
||||||
self.patch(sys, "argv", self.var["sys_arg_cmd"])
|
self.patch(sys, "argv", self.var["sys_arg_cmd"])
|
||||||
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
self.var["start_cmd"]()
|
self.exec_command()
|
||||||
|
|
||||||
|
def test_start_console_with_log_level(self):
|
||||||
|
_level = []
|
||||||
|
|
||||||
|
def setup_logger(level="error", filename=None, filemode="w", logrotate=None):
|
||||||
|
_level.append(level)
|
||||||
|
|
||||||
|
self.patch(deluge.log, "setup_logger", setup_logger)
|
||||||
|
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["-L", "info"])
|
||||||
|
|
||||||
|
config = deluge.configmanager.ConfigManager("ui.conf", ui_entry.DEFAULT_PREFS)
|
||||||
|
config.config["default_ui"] = "console"
|
||||||
|
config.save()
|
||||||
|
|
||||||
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
|
# Just test that no exception is raised
|
||||||
|
self.exec_command()
|
||||||
|
|
||||||
|
self.assertEqual(_level[0], "info")
|
||||||
|
|
||||||
def test_console_help(self):
|
def test_console_help(self):
|
||||||
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["-h"])
|
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["-h"])
|
||||||
|
@ -153,12 +261,12 @@ class ConsoleUIBaseTestCase(object):
|
||||||
self.patch(argparse._sys, "stdout", fd)
|
self.patch(argparse._sys, "stdout", fd)
|
||||||
|
|
||||||
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
self.assertRaises(exceptions.SystemExit, self.var["start_cmd"])
|
self.assertRaises(exceptions.SystemExit, self.exec_command)
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue(("usage: %s" % self.var["cmd_name"]) in std_output) # Check command name
|
self.assertTrue(("usage: %s" % self.var["cmd_name"]) in std_output) # Check command name
|
||||||
self.assertTrue("Common Options:" in std_output)
|
self.assertTrue("Common Options:" in std_output)
|
||||||
self.assertTrue("Console Options:" in std_output)
|
self.assertTrue("Console Options:" in std_output)
|
||||||
self.assertTrue(r"Console commands:\n The following console commands are available:" in std_output)
|
self.assertTrue("Console commands:\n The following console commands are available:" in std_output)
|
||||||
self.assertTrue("The following console commands are available:" in std_output)
|
self.assertTrue("The following console commands are available:" in std_output)
|
||||||
|
|
||||||
def test_console_command_info(self):
|
def test_console_command_info(self):
|
||||||
|
@ -167,7 +275,7 @@ class ConsoleUIBaseTestCase(object):
|
||||||
self.patch(argparse._sys, "stdout", fd)
|
self.patch(argparse._sys, "stdout", fd)
|
||||||
|
|
||||||
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
self.var["start_cmd"]()
|
self.exec_command()
|
||||||
|
|
||||||
def test_console_command_info_help(self):
|
def test_console_command_info_help(self):
|
||||||
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["info", "-h"])
|
self.patch(sys, "argv", self.var["sys_arg_cmd"] + ["info", "-h"])
|
||||||
|
@ -175,7 +283,7 @@ class ConsoleUIBaseTestCase(object):
|
||||||
self.patch(argparse._sys, "stdout", fd)
|
self.patch(argparse._sys, "stdout", fd)
|
||||||
|
|
||||||
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
self.assertRaises(exceptions.SystemExit, self.var["start_cmd"])
|
self.assertRaises(exceptions.SystemExit, self.exec_command)
|
||||||
std_output = fd.out.getvalue()
|
std_output = fd.out.getvalue()
|
||||||
self.assertTrue("usage: info" in std_output)
|
self.assertTrue("usage: info" in std_output)
|
||||||
self.assertTrue("Show information about the torrents" in std_output)
|
self.assertTrue("Show information about the torrents" in std_output)
|
||||||
|
@ -185,11 +293,27 @@ class ConsoleUIBaseTestCase(object):
|
||||||
fd = TestStdout(sys.stdout)
|
fd = TestStdout(sys.stdout)
|
||||||
self.patch(argparse._sys, "stderr", fd)
|
self.patch(argparse._sys, "stderr", fd)
|
||||||
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
with mock.patch("deluge.ui.console.main.ConsoleUI"):
|
||||||
self.assertRaises(exceptions.SystemExit, self.var["start_cmd"])
|
self.assertRaises(exceptions.SystemExit, self.exec_command)
|
||||||
self.assertTrue("unrecognized arguments: --ui" in fd.out.getvalue())
|
self.assertTrue("unrecognized arguments: --ui" in fd.out.getvalue())
|
||||||
|
|
||||||
|
|
||||||
class ConsoleUIEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
class ConsoleScriptEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
||||||
|
|
||||||
|
def __init__(self, testname):
|
||||||
|
BaseTestCase.__init__(self, testname)
|
||||||
|
ConsoleUIBaseTestCase.__init__(self)
|
||||||
|
self.var["cmd_name"] = "deluge-console"
|
||||||
|
self.var["start_cmd"] = deluge.ui.console.start
|
||||||
|
self.var["sys_arg_cmd"] = ["./deluge-console"]
|
||||||
|
|
||||||
|
def set_up(self):
|
||||||
|
ConsoleUIBaseTestCase.set_up(self)
|
||||||
|
|
||||||
|
def tear_down(self):
|
||||||
|
ConsoleUIBaseTestCase.tear_down(self)
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleDelugeScriptEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
||||||
|
|
||||||
def __init__(self, testname):
|
def __init__(self, testname):
|
||||||
BaseTestCase.__init__(self, testname)
|
BaseTestCase.__init__(self, testname)
|
||||||
|
@ -198,12 +322,8 @@ class ConsoleUIEntryTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
||||||
self.var["start_cmd"] = ui_entry.start_ui
|
self.var["start_cmd"] = ui_entry.start_ui
|
||||||
self.var["sys_arg_cmd"] = ["./deluge", "console"]
|
self.var["sys_arg_cmd"] = ["./deluge", "console"]
|
||||||
|
|
||||||
|
def set_up(self):
|
||||||
|
ConsoleUIBaseTestCase.set_up(self)
|
||||||
|
|
||||||
class ConsoleUIScriptTestCase(BaseTestCase, ConsoleUIBaseTestCase):
|
def tear_down(self):
|
||||||
|
ConsoleUIBaseTestCase.tear_down(self)
|
||||||
def __init__(self, testname):
|
|
||||||
BaseTestCase.__init__(self, testname)
|
|
||||||
ConsoleUIBaseTestCase.__init__(self)
|
|
||||||
self.var["cmd_name"] = "deluge-console"
|
|
||||||
self.var["start_cmd"] = deluge.ui.console.start
|
|
||||||
self.var["sys_arg_cmd"] = ["./deluge-console"]
|
|
||||||
|
|
|
@ -19,25 +19,27 @@ from deluge import common
|
||||||
from deluge.configmanager import get_config_dir, set_config_dir
|
from deluge.configmanager import get_config_dir, set_config_dir
|
||||||
|
|
||||||
|
|
||||||
def find_subcommand(self, args=None):
|
def find_subcommand(self, args=None, sys_argv=True):
|
||||||
"""Find if a subcommand has been supplied.
|
"""Find if a subcommand has been supplied.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
args (list, optional): The argument list handed to parse_args().
|
args (list, optional): The argument list to search through.
|
||||||
|
sys_argv (bool): Use sys.argv[1:] if args is None.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
int: Index of the subcommand or '-1' if none found.
|
int: Index of the subcommand or '-1' if none found.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
subcommand_found = -1
|
subcommand_found = -1
|
||||||
test_args = args if args is not None else sys.argv[1:]
|
if args is None:
|
||||||
|
args = sys.argv[1:] if sys_argv is None else []
|
||||||
|
|
||||||
for x in self._subparsers._actions:
|
for x in self._subparsers._actions:
|
||||||
if not isinstance(x, argparse._SubParsersAction):
|
if not isinstance(x, argparse._SubParsersAction):
|
||||||
continue
|
continue
|
||||||
for sp_name in x._name_parser_map.keys():
|
for sp_name in x._name_parser_map.keys():
|
||||||
if sp_name in test_args:
|
if sp_name in args:
|
||||||
subcommand_found = test_args.index(sp_name) + 1
|
subcommand_found = args.index(sp_name)
|
||||||
|
|
||||||
return subcommand_found
|
return subcommand_found
|
||||||
|
|
||||||
|
@ -184,20 +186,47 @@ class BaseArgParser(argparse.ArgumentParser):
|
||||||
def parse_args(self, args=None):
|
def parse_args(self, args=None):
|
||||||
"""Parse UI arguments and handle common and process group options.
|
"""Parse UI arguments and handle common and process group options.
|
||||||
|
|
||||||
Unknown arguments return an error and resulting usage text.
|
Notes:
|
||||||
|
Unknown arguments results in usage text printed and system exit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args (list, optional): The arguments to parse.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.Namespace: The parsed arguments.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
options = super(BaseArgParser, self).parse_args(args=args)
|
options = super(BaseArgParser, self).parse_args(args=args)
|
||||||
return self._parse_args(options)
|
return self._handle_ui_options(options)
|
||||||
|
|
||||||
def parse_known_ui_args(self, args=None):
|
def parse_known_ui_args(self, args, withhold=None):
|
||||||
"""Parse UI arguments and handle common and process group options without error.
|
"""Parse UI arguments and handle common and process group options without error.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
args (list): The arguments to parse.
|
||||||
|
withhold (list): Values to ignore in the args list.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.Namespace: The parsed arguments.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
if withhold:
|
||||||
|
args = [a for a in args if a not in withhold]
|
||||||
options, remaining = super(BaseArgParser, self).parse_known_args(args=args)
|
options, remaining = super(BaseArgParser, self).parse_known_args(args=args)
|
||||||
options.remaining = remaining
|
options.remaining = remaining
|
||||||
return self._parse_args(options)
|
# Hanlde common and process group options
|
||||||
|
return self._handle_ui_options(options)
|
||||||
|
|
||||||
def _parse_args(self, options):
|
def _handle_ui_options(self, options):
|
||||||
|
"""Handle UI common and process group options.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
options (argparse.Namespace): The parsed options.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
argparse.Namespace: The parsed options.
|
||||||
|
|
||||||
|
"""
|
||||||
if not self.common_setup:
|
if not self.common_setup:
|
||||||
self.common_setup = True
|
self.common_setup = True
|
||||||
# Setup the logger
|
# Setup the logger
|
||||||
|
@ -226,6 +255,7 @@ class BaseArgParser(argparse.ArgumentParser):
|
||||||
os.makedirs(common.get_default_config_dir())
|
os.makedirs(common.get_default_config_dir())
|
||||||
|
|
||||||
if self.process_arg_group:
|
if self.process_arg_group:
|
||||||
|
self.process_arg_group = False
|
||||||
# If donotdaemonize is set, skip process forking.
|
# If donotdaemonize is set, skip process forking.
|
||||||
if not (common.windows_check() or options.donotdaemonize):
|
if not (common.windows_check() or options.donotdaemonize):
|
||||||
if os.fork():
|
if os.fork():
|
||||||
|
|
|
@ -7,12 +7,13 @@
|
||||||
# the additional special exception to link portions of this program with the OpenSSL library.
|
# the additional special exception to link portions of this program with the OpenSSL library.
|
||||||
# See LICENSE for more details.
|
# See LICENSE for more details.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import deluge.common
|
import deluge.common
|
||||||
from deluge.ui.baseargparser import DelugeTextHelpFormatter
|
from deluge.ui.baseargparser import BaseArgParser, DelugeTextHelpFormatter
|
||||||
from deluge.ui.console import UI_PATH
|
from deluge.ui.console import UI_PATH
|
||||||
from deluge.ui.ui import UI
|
from deluge.ui.ui import UI
|
||||||
|
|
||||||
|
@ -79,6 +80,11 @@ class Console(UI):
|
||||||
self.console_cmds[c].add_subparser(subparsers)
|
self.console_cmds[c].add_subparser(subparsers)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
|
if self.ui_args is None:
|
||||||
|
# Started directly by deluge-console script so must find the UI args manually
|
||||||
|
options, remaining = BaseArgParser(common_help=False).parse_known_args()
|
||||||
|
self.ui_args = remaining
|
||||||
|
|
||||||
i = self.console_parser.find_subcommand(args=self.ui_args)
|
i = self.console_parser.find_subcommand(args=self.ui_args)
|
||||||
self.console_parser.subcommand = False
|
self.console_parser.subcommand = False
|
||||||
self.parser.subcommand = False if i == -1 else True
|
self.parser.subcommand = False if i == -1 else True
|
||||||
|
|
|
@ -33,7 +33,7 @@ from deluge.ui.sessionproxy import SessionProxy
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ConsoleCommandParser(argparse.ArgumentParser):
|
class ConsoleBaseParser(argparse.ArgumentParser):
|
||||||
|
|
||||||
def format_help(self):
|
def format_help(self):
|
||||||
"""
|
"""
|
||||||
|
@ -44,12 +44,15 @@ class ConsoleCommandParser(argparse.ArgumentParser):
|
||||||
# Handle epilog manually to keep the text formatting
|
# Handle epilog manually to keep the text formatting
|
||||||
epilog = self.epilog
|
epilog = self.epilog
|
||||||
self.epilog = ""
|
self.epilog = ""
|
||||||
help_str = super(ConsoleCommandParser, self).format_help()
|
help_str = super(ConsoleBaseParser, self).format_help()
|
||||||
if epilog is not None:
|
if epilog is not None:
|
||||||
help_str += epilog
|
help_str += epilog
|
||||||
self.epilog = epilog
|
self.epilog = epilog
|
||||||
return help_str
|
return help_str
|
||||||
|
|
||||||
|
|
||||||
|
class ConsoleCommandParser(ConsoleBaseParser):
|
||||||
|
|
||||||
def _split_args(self, args):
|
def _split_args(self, args):
|
||||||
command_options = []
|
command_options = []
|
||||||
for a in args:
|
for a in args:
|
||||||
|
@ -71,6 +74,20 @@ class ConsoleCommandParser(argparse.ArgumentParser):
|
||||||
return command_options
|
return command_options
|
||||||
|
|
||||||
def parse_args(self, args=None):
|
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)
|
multi_command = self._split_args(args)
|
||||||
# If multiple commands were passed to console
|
# If multiple commands were passed to console
|
||||||
if multi_command:
|
if multi_command:
|
||||||
|
@ -103,7 +120,7 @@ class ConsoleCommandParser(argparse.ArgumentParser):
|
||||||
return options
|
return options
|
||||||
|
|
||||||
|
|
||||||
class OptionParser(ConsoleCommandParser):
|
class OptionParser(ConsoleBaseParser):
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(OptionParser, self).__init__(**kwargs)
|
super(OptionParser, self).__init__(**kwargs)
|
||||||
|
|
|
@ -29,6 +29,8 @@ DEFAULT_PREFS = {
|
||||||
"default_ui": "gtk"
|
"default_ui": "gtk"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AMBIGUOUS_CMD_ARGS = ("-h", "--help", "-v", "-V", "--version")
|
||||||
|
|
||||||
|
|
||||||
def start_ui():
|
def start_ui():
|
||||||
"""Entry point for ui script"""
|
"""Entry point for ui script"""
|
||||||
|
@ -49,10 +51,8 @@ def start_ui():
|
||||||
# Setup parser with Common Options and add UI Options group.
|
# Setup parser with Common Options and add UI Options group.
|
||||||
parser = add_ui_options_group(BaseArgParser())
|
parser = add_ui_options_group(BaseArgParser())
|
||||||
|
|
||||||
ambiguous_args = ["-h", "--help", "-v", "-V", "--version"]
|
# Parse and handle common/process group options
|
||||||
# Parse arguments without help/version as this is handled later.
|
options = parser.parse_known_ui_args(sys.argv, withhold=AMBIGUOUS_CMD_ARGS)
|
||||||
args = [a for a in sys.argv if a not in ambiguous_args]
|
|
||||||
options = parser.parse_known_ui_args(args)
|
|
||||||
|
|
||||||
config = deluge.configmanager.ConfigManager("ui.conf", DEFAULT_PREFS)
|
config = deluge.configmanager.ConfigManager("ui.conf", DEFAULT_PREFS)
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
@ -86,7 +86,7 @@ def start_ui():
|
||||||
subactions[-1].dest = "%s %s" % (prefix, ui)
|
subactions[-1].dest = "%s %s" % (prefix, ui)
|
||||||
|
|
||||||
# Insert a default UI subcommand unless one of the ambiguous_args are specified
|
# Insert a default UI subcommand unless one of the ambiguous_args are specified
|
||||||
parser.set_default_subparser(default_ui, abort_opts=ambiguous_args)
|
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.
|
# Only parse known arguments to leave the UIs to show a help message if parsing fails.
|
||||||
options, remaining = parser.parse_known_args()
|
options, remaining = parser.parse_known_args()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue