def run_app_with_daemon(fd, is_gui, config_options): with app_state.async_ as async_: d = daemon.Daemon(fd, is_gui) d.start() try: app_state.app.run_app() finally: # Shut down the daemon before exiting the async loop d.stop() d.join() sys.exit(0)
def run_app_with_daemon(fd, is_gui, config_options): with app_state.async_ as async_: d = daemon.Daemon(fd, is_gui) app_state.app.setup_app() d.start() try: app_state.app.run_app() except KeyboardInterrupt: pass finally: # Shut down the daemon before exiting the async loop d.stop() d.join() sys.exit(0)
def main(): # The hook will only be used in the Qt GUI right now setup_thread_excepthook() # on osx, delete Process Serial Number arg generated for apps launched in Finder sys.argv = [x for x in sys.argv if not x.startswith('-psn')] # old 'help' syntax if len(sys.argv) > 1 and sys.argv[1] == 'help': sys.argv.remove('help') sys.argv.append('-h') # read arguments from stdin pipe and prompt for i, arg in enumerate(sys.argv): if arg == '-': if not sys.stdin.isatty(): sys.argv[i] = sys.stdin.read() break else: raise Exception('Cannot get argument from stdin') elif arg == '?': sys.argv[i] = input("Enter argument:") elif arg == ':': sys.argv[i] = prompt_password('Enter argument (will not echo):', False) # parse command line parser = get_parser() args = parser.parse_args() # config is an object passed to the various constructors (wallet, interface, gui) config_options = args.__dict__ config_options = { key: value for key, value in config_options.items() if value is not None and key not in config_variables.get(args.cmd, {}) } logs.set_level(config_options['verbose']) if config_options.get('server'): config_options['auto_connect'] = False config_options['cwd'] = os.getcwd() # fixme: this can probably be achieved with a runtime hook (pyinstaller) try: if is_bundle and os.path.exists( os.path.join(sys._MEIPASS, 'is_portable')): config_options['portable'] = True except AttributeError: config_options['portable'] = False if config_options.get('portable'): config_options['electrum_sv_path'] = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'electrum_sv_data') if config_options.get('file_logging'): log_path = os.path.join(platform.user_dir(prefer_local=True), "logs") os.makedirs(log_path, exist_ok=True) log_path = os.path.join(log_path, time.strftime("%Y%m%d-%H%M%S") + ".log") logs.add_file_output(log_path) if config_options.get('testnet'): Net.set_to(SVTestnet) # check uri uri = config_options.get('url') if uri: if not web.is_URI(uri): print('unknown command:', uri, file=sys.stderr) sys.exit(1) config_options['url'] = uri # todo: defer this to gui config = SimpleConfig(config_options) cmdname = config.get('cmd') # Set the app state proxy if cmdname == 'gui': try: from electrumsv.gui.qt.app_state import QtAppStateProxy except ImportError as e: platform.missing_import(e) QtAppStateProxy(config, 'qt') else: AppStateProxy(config, 'cmdline') # run non-RPC commands separately if cmdname in ['create', 'restore']: run_non_RPC(config) sys.exit(0) if cmdname == 'gui': fd, server = daemon.get_fd_or_server(config) if fd is not None: d = daemon.Daemon(fd, True) d.start() app_state.app.run_gui() sys.exit(0) else: result = server.gui(config_options) elif cmdname == 'daemon': subcommand = config.get('subcommand') if subcommand in ['load_wallet']: init_daemon(config_options) if subcommand in [None, 'start']: fd, server = daemon.get_fd_or_server(config) if fd is not None: if subcommand == 'start': pid = os.fork() if pid: print("starting daemon (PID %d)" % pid, file=sys.stderr) sys.exit(0) d = daemon.Daemon(fd, False) d.start() if config.get('websocket_server'): try: from electrumsv import websockets except ImportError as e: platform.missing_import(e) websockets.WebSocketServer(config, d.network).start() if config.get('requests_dir'): path = os.path.join(config.get('requests_dir'), 'index.html') if not os.path.exists(path): print("Requests directory not configured.") print("You can configure it using " "https://github.com/spesmilo/electrum-merchant") sys.exit(1) d.join() sys.exit(0) else: result = server.daemon(config_options) else: server = daemon.get_server(config) if server is not None: result = server.daemon(config_options) else: print("Daemon not running") sys.exit(1) else: # command line server = daemon.get_server(config) init_cmdline(config_options, server) if server is not None: result = server.run_cmdline(config_options) else: cmd = known_commands[cmdname] if cmd.requires_network: print("Daemon not running; try 'electrum-sv daemon start'") sys.exit(1) else: result = run_offline_command(config, config_options) # print result if isinstance(result, str): print(result) elif type(result) is dict and result.get('error'): print(result.get('error'), file=sys.stderr) elif result is not None: print(json_encode(result)) sys.exit(0)