From 9d1ffe0c374d7ac286d31ec5471044c65df9ed64 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Sun, 16 Mar 2025 15:00:24 +0100 Subject: [PATCH] support for arguments to plugin commands: - add a simple parser that only figures out where the config is, and does not complain if args are unknown --- electrum/commands.py | 28 +++++++++++++++++++++++++- electrum/plugins/labels/commands.py | 4 ++-- run_electrum | 31 ++++++++++++++++++----------- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/electrum/commands.py b/electrum/commands.py index 3ca2701c3..bd8848d90 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -1803,6 +1803,28 @@ def add_wallet_option(parser): parser.add_argument("--forgetconfig", action="store_true", dest=SimpleConfig.CONFIG_FORGET_CHANGES.key(), default=False, help="Forget config on exit") +def get_simple_parser(): + """ simple parser that figures out the path of the config file and ignore unknown args """ + from optparse import OptionParser, BadOptionError, AmbiguousOptionError + class PassThroughOptionParser(OptionParser): + # see https://stackoverflow.com/questions/1885161/how-can-i-get-optparses-optionparser-to-ignore-invalid-options + def _process_args(self, largs, rargs, values): + while rargs: + try: + OptionParser._process_args(self,largs,rargs,values) + except (BadOptionError,AmbiguousOptionError) as e: + largs.append(e.opt_str) + parser = PassThroughOptionParser() + parser.add_option("-D", "--dir", dest="electrum_path", help="electrum directory") + parser.add_option("-P", "--portable", action="store_true", dest="portable", default=False, help="Use local 'electrum_data' directory") + parser.add_option("--testnet", action="store_true", dest="testnet", default=False, help="Use Testnet") + parser.add_option("--testnet4", action="store_true", dest="testnet4", default=False, help="Use Testnet4") + parser.add_option("--regtest", action="store_true", dest="regtest", default=False, help="Use Regtest") + parser.add_option("--simnet", action="store_true", dest="simnet", default=False, help="Use Simnet") + parser.add_option("--signet", action="store_true", dest="signet", default=False, help="Use Signet") + return parser + + def get_parser(): # create main parser parser = argparse.ArgumentParser( @@ -1843,7 +1865,11 @@ def get_parser(): continue if optname in ['plugin']: continue - a, help = command_options[optname] + if optname in command_options: + a, help = command_options[optname] + else: + a = None + help = None b = '--' + optname action = "store_true" if default is False else 'store' args = (a, b) if a else (b,) diff --git a/electrum/plugins/labels/commands.py b/electrum/plugins/labels/commands.py index 7b4e1100e..2c540833e 100644 --- a/electrum/plugins/labels/commands.py +++ b/electrum/plugins/labels/commands.py @@ -15,6 +15,6 @@ async def push(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None) -> @plugin_command('w', plugin_name) -async def pull(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None) -> int: +async def pull(self: 'Commands', plugin: 'LabelsPlugin' = None, wallet=None, force=False) -> int: """ pull labels from server """ - return await plugin.pull_thread(wallet, force=False) + return await plugin.pull_thread(wallet, force=force) diff --git a/run_electrum b/run_electrum index 0b71a496f..970be1a95 100755 --- a/run_electrum +++ b/run_electrum @@ -103,7 +103,7 @@ from electrum.storage import WalletStorage from electrum.util import print_msg, print_stderr, json_encode, json_decode, UserCancelled from electrum.util import InvalidPassword from electrum.plugin import Plugins -from electrum.commands import get_parser, known_commands, Commands, config_variables +from electrum.commands import get_parser, get_simple_parser, known_commands, Commands, config_variables from electrum import daemon from electrum import keystore from electrum.util import create_and_start_event_loop, UserFacingException, JsonRPCError @@ -271,15 +271,21 @@ def sys_exit(i): loop_thread.join(timeout=1) sys.exit(i) -def parse_command_line() -> Dict: +def parse_command_line(simple_parser=False) -> Dict: # parse command line from sys.argv - parser = get_parser() - args = parser.parse_args() - config_options = args.__dict__ - f = lambda key: config_options[key] is not None and key not in config_variables.get(args.cmd, {}).keys() - config_options = {key: config_options[key] for key in filter(f, config_options.keys())} - if config_options.get(SimpleConfig.NETWORK_SERVER.key()): - config_options[SimpleConfig.NETWORK_AUTO_CONNECT.key()] = False + if simple_parser: + parser = get_simple_parser() + options, args = parser.parse_args() + config_options = options.__dict__ + config_options['cmd'] = 'gui' + else: + parser = get_parser() + args = parser.parse_args() + config_options = args.__dict__ + f = lambda key: config_options[key] is not None and key not in config_variables.get(args.cmd, {}).keys() + config_options = {key: config_options[key] for key in filter(f, config_options.keys())} + if config_options.get(SimpleConfig.NETWORK_SERVER.key()): + config_options[SimpleConfig.NETWORK_AUTO_CONNECT.key()] = False config_options['cwd'] = cwd = os.getcwd() @@ -361,10 +367,11 @@ def main(): # save sys args for next parser saved_sys_argv = sys.argv[:] # disable help, the next parser will display it - if '-h' in sys.argv: - sys.argv.remove('-h') + for x in sys.argv: + if x in ['-h', '--help']: + sys.argv.remove(x) # parse first without plugins - config_options = parse_command_line() + config_options = parse_command_line(simple_parser=True) tmp_config = SimpleConfig(config_options) # load (only) the commands modules of plugins so their commands are registered plugin_commands = Plugins(tmp_config, cmd_only=True)