def load_program_config(config_path=None, bs=None): global_singleton.config.readfp(io.StringIO(defaultconfig)) remove_unwanted_default_settings(global_singleton.config) if not config_path: config_path = os.getcwd() global_singleton.config_location = os.path.join( config_path, global_singleton.config_location) loadedFiles = global_singleton.config.read( [global_singleton.config_location]) #Hack required for electrum; must be able to enforce a different #blockchain interface even in default/new load. if bs: global_singleton.config.set("BLOCKCHAIN", "blockchain_source", bs) # Create default config file if not found if len(loadedFiles) != 1: with open(global_singleton.config_location, "w") as configfile: configfile.write(defaultconfig) jmprint( "Created a new `joinmarket.cfg`. Please review and adopt the " "settings and restart joinmarket.", "info") exit(1) #These are left as sanity checks but currently impossible #since any edits are overlays to the default, these sections/options will #always exist. # FIXME: This check is a best-effort attempt. Certain incorrect section # names can pass and so can non-first invalid sections. for s in required_options: #pragma: no cover # check for sections avail = None if not global_singleton.config.has_section(s): for avail in global_singleton.config.sections(): if avail.startswith(s): break else: raise Exception( "Config file does not contain the required section: " + s) # then check for specific options k = avail or s for o in required_options[s]: if not global_singleton.config.has_option(k, o): raise Exception("Config file does not contain the required " "option '{}' in section '{}'.".format(o, k)) loglevel = global_singleton.config.get("LOGGING", "console_log_level") try: set_logging_level(loglevel) except: jmprint( "Failed to set logging level, must be DEBUG, INFO, WARNING, ERROR", "error") # Logs to the console are color-coded if user chooses (file is unaffected) if global_singleton.config.get("LOGGING", "color") == "true": set_logging_color(True) else: set_logging_color(False) try: global_singleton.maker_timeout_sec = global_singleton.config.getint( 'TIMEOUT', 'maker_timeout_sec') except NoOptionError: #pragma: no cover log.debug('TIMEOUT/maker_timeout_sec not found in .cfg file, ' 'using default value') # configure the interface to the blockchain on startup global_singleton.bc_interface = get_blockchain_interface_instance( global_singleton.config) #set the location of the commitments file try: global_singleton.commit_file_location = global_singleton.config.get( "POLICY", "commit_file_location") except NoOptionError: #pragma: no cover log.debug("No commitment file location in config, using default " "location cmtdata/commitments.json") set_commitment_file( os.path.join(config_path, global_singleton.commit_file_location))
def load_program_config(config_path="", bs=None, plugin_services=[]): global_singleton.config.readfp(io.StringIO(defaultconfig)) if not config_path: config_path = lookup_appdata_folder(global_singleton.APPNAME) # we set the global home directory, but keep the config_path variable # for callers of this function: global_singleton.datadir = config_path jmprint("User data location: " + global_singleton.datadir, "info") if not os.path.exists(global_singleton.datadir): os.makedirs(global_singleton.datadir) # prepare folders for wallets and logs if not os.path.exists(os.path.join(global_singleton.datadir, "wallets")): os.makedirs(os.path.join(global_singleton.datadir, "wallets")) if not os.path.exists(os.path.join(global_singleton.datadir, "logs")): os.makedirs(os.path.join(global_singleton.datadir, "logs")) if not os.path.exists(os.path.join(global_singleton.datadir, "cmtdata")): os.makedirs(os.path.join(global_singleton.datadir, "cmtdata")) global_singleton.config_location = os.path.join( global_singleton.datadir, global_singleton.config_location) remove_unwanted_default_settings(global_singleton.config) loadedFiles = global_singleton.config.read([global_singleton.config_location ]) #Hack required for electrum; must be able to enforce a different #blockchain interface even in default/new load. if bs: global_singleton.config.set("BLOCKCHAIN", "blockchain_source", bs) # Create default config file if not found if len(loadedFiles) != 1: with open(global_singleton.config_location, "w") as configfile: configfile.write(defaultconfig) jmprint("Created a new `joinmarket.cfg`. Please review and adopt the " "settings and restart joinmarket.", "info") sys.exit(EXIT_FAILURE) #These are left as sanity checks but currently impossible #since any edits are overlays to the default, these sections/options will #always exist. # FIXME: This check is a best-effort attempt. Certain incorrect section # names can pass and so can non-first invalid sections. for s in required_options: #pragma: no cover # check for sections avail = None if not global_singleton.config.has_section(s): for avail in global_singleton.config.sections(): if avail.startswith(s): break else: raise Exception( "Config file does not contain the required section: " + s) # then check for specific options k = avail or s for o in required_options[s]: if not global_singleton.config.has_option(k, o): raise Exception("Config file does not contain the required " "option '{}' in section '{}'.".format(o, k)) loglevel = global_singleton.config.get("LOGGING", "console_log_level") try: set_logging_level(loglevel) except: jmprint("Failed to set logging level, must be DEBUG, INFO, WARNING, ERROR", "error") # Logs to the console are color-coded if user chooses (file is unaffected) if global_singleton.config.get("LOGGING", "color") == "true": set_logging_color(True) else: set_logging_color(False) try: global_singleton.maker_timeout_sec = global_singleton.config.getint( 'TIMEOUT', 'maker_timeout_sec') except NoOptionError: #pragma: no cover log.debug('TIMEOUT/maker_timeout_sec not found in .cfg file, ' 'using default value') # configure the interface to the blockchain on startup global_singleton.bc_interface = get_blockchain_interface_instance( global_singleton.config) # set the location of the commitments file; for non-mainnet a different # file is used to avoid conflict try: global_singleton.commit_file_location = global_singleton.config.get( "POLICY", "commit_file_location") except NoOptionError: #pragma: no cover if get_network() == "mainnet": log.debug("No commitment file location in config, using default " "location cmtdata/commitments.json") if get_network() != "mainnet": # no need to be flexible for tests; note this is used # for regtest, signet and testnet3 global_singleton.commit_file_location = "cmtdata/" + get_network() + \ "_commitments.json" set_commitment_file(os.path.join(config_path, global_singleton.commit_file_location)) for p in plugin_services: # for now, at this config level, the only significance # of a "plugin" is that it keeps its own separate log. # We require that a section exists in the config file, # and that it has enabled=true: assert isinstance(p, JMPluginService) if not (global_singleton.config.has_section(p.name) and \ global_singleton.config.has_option(p.name, "enabled") and \ global_singleton.config.get(p.name, "enabled") == "true"): break if p.requires_logging: # make sure the environment can accept a logfile by # creating the directory in the correct place, # and setting that in the plugin object; the plugin # itself will switch on its own logging when ready, # attaching a filehandler to the global log. plogsdir = os.path.join(os.path.dirname( global_singleton.config_location), "logs", p.name) if not os.path.exists(plogsdir): os.makedirs(plogsdir) p.set_log_dir(plogsdir)