class ParamStore(object): def __init__(self, root_dir, file_name): if not os.path.isdir(root_dir): os.makedirs(root_dir) self._path = os.path.join(root_dir, file_name) self._dirty = False # open config file self._config = RawConfigParser() self._config.read(self._path) def __del__(self): self.flush() def flush(self): if not self._dirty: return self._dirty = False of = open(self._path, "w") self._config.write(of) of.close() def get(self, section, option, default=None): """Get a parameter value and return a string. If default is specified and section or option are not defined in the file, they are created and set to default, which is then the return value. """ if not self._config.has_option(section, option): if default is not None: self.set(section, option, default) return default return self._config.get(section, option) def get_datetime(self, section, option, default=None): result = self.get(section, option, default) if result: return safestrptime(result) return result def set(self, section, option, value): """Set option in section to string value.""" if not self._config.has_section(section): self._config.add_section(section) elif self._config.has_option(section, option) and self._config.get(section, option) == value: return self._config.set(section, option, value) self._dirty = True def unset(self, section, option): """Remove option from section.""" if not self._config.has_section(section): return if self._config.has_option(section, option): self._config.remove_option(section, option) self._dirty = True if not self._config.options(section): self._config.remove_section(section) self._dirty = True
class OriginAuthStore(object): def __init__(self, config_file): self.config_file = config_file self.config = RawConfigParser() self.config.read(config_file) def origin(self, name): return OriginAuth(self, name) def __getitem__(self, origin_name): try: return dict(self.config.items(origin_name)) except NoSectionError: return {} def __setitem__(self, origin_name, auth): try: self.config.remove_section(origin_name) except NoSectionError: pass if auth: self.config.add_section(origin_name) for key, val in auth.iteritems(): self.config.set(origin_name, key, val) with open(self.config_file, 'w') as f: self.config.write(f) try: os.chmod(self.config_file, stat.S_IRUSR | stat.S_IWUSR) except OSError: print 'Unable to chmod 600 %s' % self.config_file # TODO: Test
def execute(*args, **kw): if not os.path.isfile('/etc/kolab-freebusy/config.ini') and not os.path.isfile('/etc/kolab-freebusy/config.ini.sample'): log.error(_("Free/Busy is not installed on this system")) return if not os.path.isfile('/etc/kolab-freebusy/config.ini'): os.rename('/etc/kolab-freebusy/config.ini.sample', '/etc/kolab-freebusy/config.ini') freebusy_settings = { 'directory "kolab-ldap"': { 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'fbsource': 'file:/var/lib/kolab-freebusy/%mail.ifb', }, 'httpauth': { } } cfg_parser = RawConfigParser() cfg_parser.read('/etc/kolab-freebusy/config.ini') for section in freebusy_settings.keys(): if len(freebusy_settings[section].keys()) < 1: cfg_parser.remove_section(section) continue for key in freebusy_settings[section].keys(): cfg_parser.set(section, key, freebusy_settings[section][key]) fp = open('/etc/kolab-freebusy/config.ini', "w+") cfg_parser.write(fp) fp.close()
class Config(object): def __init__(self, buildout_dir): self.cfg_path = os.path.join(buildout_dir, '.mr.developer.cfg') self._config = RawConfigParser() self._config.optionxform = lambda s: s self._config.read(self.cfg_path) self.develop = {} self.buildout_args = [] self.rewrites = [] if self._config.has_section('develop'): for package, value in self._config.items('develop'): value = value.lower() if value == 'true': self.develop[package] = True elif value == 'false': self.develop[package] = False elif value == 'auto': self.develop[package] = 'auto' else: raise ValueError("Invalid value in 'develop' section of '%s'" % self.cfg_path) if self._config.has_option('buildout', 'args'): args = self._config.get('buildout', 'args').split("\n") for arg in args: arg = arg.strip() if arg.startswith("'") and arg.endswith("'"): arg = arg[1:-1].replace("\\'", "'") elif arg.startswith('"') and arg.endswith('"'): arg = arg[1:-1].replace('\\"', '"') self.buildout_args.append(arg) (self.buildout_options, self.buildout_settings, _) = \ parse_buildout_args(self.buildout_args[1:]) if self._config.has_option('mr.developer', 'rewrites'): for rewrite in self._config.get('mr.developer', 'rewrites').split('\n'): self.rewrites.append(rewrite.split()) def save(self): self._config.remove_section('develop') self._config.add_section('develop') for package in sorted(self.develop): state = self.develop[package] if state is 'auto': self._config.set('develop', package, 'auto') elif state is True: self._config.set('develop', package, 'true') elif state is False: self._config.set('develop', package, 'false') if not self._config.has_section('buildout'): self._config.add_section('buildout') options, settings, args = parse_buildout_args(self.buildout_args[1:]) # don't store the options when a command was in there if not len(args): self._config.set('buildout', 'args', "\n".join(repr(x) for x in self.buildout_args)) if not self._config.has_section('mr.developer'): self._config.add_section('mr.developer') self._config.set('mr.developer', 'rewrites', "\n".join(" ".join(x) for x in self.rewrites)) self._config.write(open(self.cfg_path, "w"))
class ConfigStore(object): def __init__(self, name): self.config = RawConfigParser() self.file_opts = {} if sys.version_info[0] >= 3: self.file_opts['encoding'] = 'utf-8' if hasattr(appdirs, 'user_config_dir'): data_dir = appdirs.user_config_dir('photini') else: data_dir = appdirs.user_data_dir('photini') if not os.path.isdir(data_dir): os.makedirs(data_dir, mode=0700) self.file_name = os.path.join(data_dir, '%s.ini' % name) if name == 'editor': for old_file_name in (os.path.expanduser('~/photini.ini'), os.path.join(data_dir, 'photini.ini')): if os.path.exists(old_file_name): self.config.read(old_file_name, **self.file_opts) self.save() os.unlink(old_file_name) self.config.read(self.file_name, **self.file_opts) self.timer = QtCore.QTimer() self.timer.setSingleShot(True) self.timer.setInterval(3000) self.timer.timeout.connect(self.save) self.has_section = self.config.has_section def get(self, section, option, default=None): if self.config.has_option(section, option): result = self.config.get(section, option) if sys.version_info[0] < 3: return result.decode('utf-8') return result if default is not None: self.set(section, option, default) return default def set(self, section, option, value): if not self.config.has_section(section): self.config.add_section(section) if (self.config.has_option(section, option) and self.config.get(section, option) == value): return if sys.version_info[0] < 3: value = value.encode('utf-8') self.config.set(section, option, value) self.timer.start() def remove_section(self, section): if not self.config.has_section(section): return for option in self.config.options(section): self.config.remove_option(section, option) self.config.remove_section(section) self.timer.start() def save(self): self.config.write(open(self.file_name, 'w', **self.file_opts)) os.chmod(self.file_name, 0600)
class Reader(object): """ Configuration Reader. """ __metaclass__ = ReaderMetaclass section = None def __init__(self, config_path=None): # by default, read from the global config dir if config_path is None: config_path = join(settings.MINV_CONFIG_DIR, "minv.conf") self._config_path = config_path self._config = None self.read() def check_config(self): errors = [] for option in self._options: try: option.fget(self) except Exception as exc: errors.append(exc) if errors: raise ConfigurationErrors(errors) def write(self, config_path=None): self._config.write(open(config_path or self._config_path, "w")) def read(self, reset=True): if reset or not self._config: self._config = RawConfigParser() with open(self._config_path) as f: self._config.readfp(f) def get_section_dict(self, section, ordered=False): try: items = self._config.items(section) return SortedDict(items) if ordered else dict(items) except NoSectionError: return {} def set_section_dict(self, section, values): self._config.remove_section(section) if values: self._config.add_section(section) for key, value in values.items(): self._config.set(section, key, value) @classmethod def from_fileobject(cls, fobj): reader = cls() reader._config = RawConfigParser() reader._config.readfp(fobj) return reader
def remove_section(self, section): """ Wrapper around the ConfigParser.remove_section() method. This method only calls the ConfigParser.remove_section() method if the section actually exists. """ if self.has_section(section): RawConfigParser.remove_section(self, section)
def remove_section(self, section): """ Wrapper around the ConfigParser.remove_section() method. This method only calls the ConfigParser.remove_section() method if the section actually exists. """ if self.has_section(section): RawConfigParser.remove_section(self, section)
def delete_share( menu ): conf = ConfigParser() conf.read( SMB_CONF_FILE ) view_smb( menu, include_vals=False ) print( "The share directory will not be deleted" ) conf.remove_section( menu.prompt( "Please enter the 'share name' to remove" ) ) conf.write( open( SMB_CONF_FILE, 'w' ) ) restart_smb( menu )
def convert_config_to_tribler71(current_config, state_dir=None): """ Convert the Config files libtribler.conf and tribler.conf to the newer triblerd.conf and cleanup the files when we are done. :param: current_config: the current config in which we merge the old config files. :return: the newly edited TriblerConfig object with the old data inserted. """ state_dir = state_dir or TriblerConfig.get_default_state_dir() libtribler_file_loc = os.path.join(state_dir, "libtribler.conf") if os.path.exists(libtribler_file_loc): libtribler_cfg = RawConfigParser() libtribler_cfg.read(libtribler_file_loc) current_config = add_libtribler_config(current_config, libtribler_cfg) os.remove(libtribler_file_loc) tribler_file_loc = os.path.join(state_dir, "tribler.conf") if os.path.exists(tribler_file_loc): tribler_cfg = RawConfigParser() tribler_cfg.read(tribler_file_loc) current_config = add_tribler_config(current_config, tribler_cfg) os.remove(tribler_file_loc) # We also have to update all existing downloads, in particular, rename the section 'downloadconfig' to # 'download_defaults'. for _, filename in enumerate( iglob(os.path.join(state_dir, STATEDIR_DLPSTATE_DIR, '*.state'))): download_cfg = RawConfigParser() try: with open(filename) as cfg_file: download_cfg.readfp(cfg_file, filename=filename) except MissingSectionHeaderError: logger.error( "Removing download state file %s since it appears to be corrupt", filename) os.remove(filename) try: download_items = download_cfg.items("downloadconfig") download_cfg.add_section("download_defaults") for download_item in download_items: download_cfg.set("download_defaults", download_item[0], download_item[1]) download_cfg.remove_section("downloadconfig") with open(filename, "w") as output_config_file: download_cfg.write(output_config_file) except (NoSectionError, DuplicateSectionError): # This item has already been converted pass return current_config
def merge(master, updates, outfile, **kwargs): if not master: master = _find_master() if not isinstance(updates, (list, tuple)): updates = [updates] print "Merging files: %s and %s" % (master, ', '.join(updates)) parser = RawConfigParser() parser.read(updates) with open(master, 'r') as orig: with open(outfile, 'w') as new: current_section = None for line in orig: sec_m = re.match("^\[([\w\d_\-\s]+)\]\s*", line, re.IGNORECASE) if sec_m: current_section = sec_m.group(1) new.write(line) else: if not parser.has_section(current_section): new.write(line) continue var_m = re.match("^(?:;)?([\w\d\_\-\.]+)\s*=\s*(.*)\n$", line, re.IGNORECASE) if var_m: key, value = var_m.groups() if parser.has_option(current_section, key): new_value = parser.get(current_section, key) # print "REPLACING: %s = %s with value %s" % (key, value, new_value) new.write("%s = %s\n" % (key, new_value % kwargs)) parser.remove_option(current_section, key) if not parser.items(current_section): parser.remove_section(current_section) else: new.write(line) else: new.write(line) if parser.sections(): #print "The following values were not set:" for s in parser.sections(): new.write("") new.write("[%s]\n" % s) for t in parser.items(s): new.write("%s = %s\n" % t)
def merge(master, updates, outfile, **kwargs): if not master: master = _find_master() if not isinstance(updates, (list, tuple)): updates = [updates] print "Merging files: %s and %s" % (master, ', '.join(updates)) parser = RawConfigParser() parser.read(updates) with open(master, 'r') as orig: with open(outfile, 'w') as new: current_section=None for line in orig: sec_m = re.match("^\[([\w\d_\-\s]+)\]\s*", line, re.IGNORECASE) if sec_m: current_section=sec_m.group(1) new.write(line) else: if not parser.has_section(current_section): new.write(line) continue var_m = re.match("^(?:;)?([\w\d\_\-\.]+)\s*=\s*(.*)\n$", line, re.IGNORECASE) if var_m: key, value = var_m.groups() if parser.has_option(current_section, key): new_value = parser.get(current_section, key) # print "REPLACING: %s = %s with value %s" % (key, value, new_value) new.write("%s = %s\n" % (key, new_value % kwargs)) parser.remove_option(current_section, key) if not parser.items(current_section): parser.remove_section(current_section) else: new.write(line) else: new.write(line) if parser.sections(): #print "The following values were not set:" for s in parser.sections(): new.write("") new.write("[%s]\n" % s) for t in parser.items(s): new.write("%s = %s\n" % t)
def remove_options(self, section): """Remove a n entire section """ #print self.data['conf_file'] if 'conf_file' in self.data and self.data['conf_file'] is not None: config = RawConfigParser() config.read([self.data['conf_file']]) config.remove_section(section) with open(self.data['conf_file'], 'wb') as configfile: config.write(configfile) if section in self._cache: del self._cache[section] return True return False
def convert_config_to_tribler71(current_config, state_dir=None): """ Convert the Config files libtribler.conf and tribler.conf to the newer triblerd.conf and cleanup the files when we are done. :param: current_config: the current config in which we merge the old config files. :return: the newly edited TriblerConfig object with the old data inserted. """ state_dir = state_dir or TriblerConfig.get_default_state_dir() libtribler_file_loc = os.path.join(state_dir, "libtribler.conf") if os.path.exists(libtribler_file_loc): libtribler_cfg = RawConfigParser() libtribler_cfg.read(libtribler_file_loc) current_config = add_libtribler_config(current_config, libtribler_cfg) os.remove(libtribler_file_loc) tribler_file_loc = os.path.join(state_dir, "tribler.conf") if os.path.exists(tribler_file_loc): tribler_cfg = RawConfigParser() tribler_cfg.read(tribler_file_loc) current_config = add_tribler_config(current_config, tribler_cfg) os.remove(tribler_file_loc) # We also have to update all existing downloads, in particular, rename the section 'downloadconfig' to # 'download_defaults'. for _, filename in enumerate(iglob( os.path.join(state_dir, STATEDIR_DLPSTATE_DIR, '*.state'))): download_cfg = RawConfigParser() try: with open(filename) as cfg_file: download_cfg.readfp(cfg_file, filename=filename) except MissingSectionHeaderError: logger.error("Removing download state file %s since it appears to be corrupt", filename) os.remove(filename) try: download_items = download_cfg.items("downloadconfig") download_cfg.add_section("download_defaults") for download_item in download_items: download_cfg.set("download_defaults", download_item[0], download_item[1]) download_cfg.remove_section("downloadconfig") with open(filename, "w") as output_config_file: download_cfg.write(output_config_file) except (NoSectionError, DuplicateSectionError): # This item has already been converted pass return current_config
def remove_backend(self, backend_name): config = RawConfigParser() config.read(self.confpath) if not config.remove_section(backend_name): return False with open(self.confpath, 'w') as f: config.write(f) return True
def save_ui_config(defaults, section, save_options, error_callback): p = RawConfigParser() filename = os.path.join(defaults['data_dir'], 'ui_config') p.read(filename) p.remove_section(section) p.add_section(section) for name in save_options: p.set(section, name, defaults[name]) try: f = file(filename, 'w') p.write(f) f.close() except Exception, e: try: f.close() except: pass error_callback(ERROR, 'Could not permanently save options: ' + str(e))
class Config(object): """ Manage configuration - a simple wrapper around RawConfigParser. Upon initialization, the loaded file is updated with the default values. config.save() will save the current state. """ def __init__(self): self.filename = get_config_fn() try: self.parser = RawConfigParser(dict_type=OrderedDict) except TypeError: # Python versions < 2.6 don't support dict_type self.parser = RawConfigParser() f = StringIO(default_config) self.parser.readfp(f) self.parser.read(self.filename) self.save() def get(self, key, section='DreamPie'): return self.parser.get(section, key) def get_bool(self, key, section='DreamPie'): return self.parser.getboolean(section, key) def get_int(self, key, section='DreamPie'): return self.parser.getint(section, key) def set(self, key, value, section='DreamPie'): self.parser.set(section, key, value) def set_bool(self, key, value, section='DreamPie'): value_str = 'True' if value else 'False' self.set(key, value_str, section) def set_int(self, key, value, section='DreamPie'): if value != int(value): raise ValueError("Expected an int, got %r" % value) self.set(key, '%d' % value, section) def sections(self): return self.parser.sections() def has_section(self, section): return self.parser.has_section(section) def add_section(self, section): return self.parser.add_section(section) def remove_section(self, section): return self.parser.remove_section(section) def save(self): f = open(self.filename, 'w') self.parser.write(f) f.close()
def save_ui_config(defaults, section, save_options, error_callback): p = RawConfigParser() filename = os.path.join(defaults['data_dir'], 'ui_config') p.read(filename) p.remove_section(section) p.add_section(section) for name in save_options: p.set(section, name, defaults[name]) try: f = file(filename, 'w') p.write(f) f.close() except Exception, e: try: f.close() except: pass error_callback(ERROR, 'Could not permanently save options: '+ str(e))
def updateVersion(self, version): """ Replace the existing version numbers in files with the specified version. """ # replace release date in changelog logging.info("\tUpdating changelog...") # open change log file change_log = self.directory.child("CHANGES.txt") changelog = open(change_log.path, "r") now = datetime.now().isoformat()[:10] old_date = "(unreleased)" new_date = "(%s)" % now newlines = [] found = 0 for line in changelog: if found > 0: line = "%s\n" % ("-" * found) found = 0 if line.find(old_date) > -1: line = line.replace(old_date, new_date) found = len(line) - 1 newlines.append(line) # create updated change log file outputFile = open(change_log.path, "wb") outputFile.writelines(newlines) # remove the egg_info metadata from setup.cfg logging.info("\tUpdating setup.cfg...") setup_cfg = self.directory.child("setup.cfg") config = RawConfigParser() config.read(setup_cfg.path) if config.has_section('egg_info'): config.remove_section('egg_info') # save updated configuration file with open(setup_cfg.path, 'wb') as configfile: config.write(configfile)
class Config(object): """ Manage configuration - a simple wrapper around RawConfigParser. Upon initialization, the loaded file is updated with the default values. config.save() will save the current state. """ def __init__(self): self.filename = get_config_fn() try: self.parser = RawConfigParser(dict_type=OrderedDict) except TypeError: # Python versions < 2.6 don't support dict_type self.parser = RawConfigParser() f = StringIO(default_config) self.parser.readfp(f) self.parser.read(self.filename) self.save() def get(self, key, section='DreamPie'): return self.parser.get(section, key) def get_bool(self, key, section='DreamPie'): return self.parser.getboolean(section, key) def get_int(self, key, section='DreamPie'): return self.parser.getint(section, key) def set(self, key, value, section='DreamPie'): self.parser.set(section, key, value) def set_bool(self, key, value, section='DreamPie'): value_str = 'True' if value else 'False' self.set(key, value_str, section) def set_int(self, key, value, section='DreamPie'): if value != int(value): raise ValueError("Expected an int, got %r" % value) self.set(key, '%d' % value, section) def sections(self): return self.parser.sections() def has_section(self, section): return self.parser.has_section(section) def add_section(self, section): return self.parser.add_section(section) def remove_section(self, section): return self.parser.remove_section(section) def save(self): f = open(self.filename, 'w') self.parser.write(f) f.close()
def edit_config(filename, settings, dry_run=False): """Edit a configuration file to include `settings` `settings` is a dictionary of dictionaries or ``None`` values, keyed by command/section name. A ``None`` value means to delete the entire section, while a dictionary lists settings to be changed or deleted in that section. A setting of ``None`` means to delete that setting. """ from ConfigParser import RawConfigParser log.debug("Reading configuration from %s", filename) opts = RawConfigParser() opts.read([filename]) for section, options in settings.items(): if options is None: log.info("Deleting section [%s] from %s", section, filename) opts.remove_section(section) else: if not opts.has_section(section): log.debug("Adding new section [%s] to %s", section, filename) opts.add_section(section) for option,value in options.items(): if value is None: log.debug("Deleting %s.%s from %s", section, option, filename ) opts.remove_option(section,option) if not opts.options(section): log.info("Deleting empty [%s] section from %s", section, filename) opts.remove_section(section) else: log.debug( "Setting %s.%s to %r in %s", section, option, value, filename ) opts.set(section,option,value) log.info("Writing %s", filename) if not dry_run: f = open(filename,'w'); opts.write(f); f.close()
def edit_config(filename, settings, dry_run=False): """Edit a configuration file to include `settings` `settings` is a dictionary of dictionaries or ``None`` values, keyed by command/section name. A ``None`` value means to delete the entire section, while a dictionary lists settings to be changed or deleted in that section. A setting of ``None`` means to delete that setting. """ from ConfigParser import RawConfigParser log.debug("Reading configuration from %s", filename) opts = RawConfigParser() opts.read([filename]) for section, options in settings.items(): if options is None: log.info("Deleting section [%s] from %s", section, filename) opts.remove_section(section) else: if not opts.has_section(section): log.debug("Adding new section [%s] to %s", section, filename) opts.add_section(section) for option, value in options.items(): if value is None: log.debug("Deleting %s.%s from %s", section, option, filename) opts.remove_option(section, option) if not opts.options(section): log.info("Deleting empty [%s] section from %s", section, filename) opts.remove_section(section) else: log.debug("Setting %s.%s to %r in %s", section, option, value, filename) opts.set(section, option, value) log.info("Writing %s", filename) if not dry_run: f = open(filename, 'w') opts.write(f) f.close()
def remove_section(self, section): """Removes a section. :param section: the section to be removed :type section: string :rtype: boolean :returns: True if the section existed """ if RCP.remove_section(self, section): self._section_list.remove(section) return True return False
def commandFetchProtect(self, parts, fromloc, overriderank): "/fp on|off - Mod\nToggles Fetch Protection for yourself." if len(parts) != 2: self.client.sendServerMessage("You must specify either 'on' or 'off'.") elif parts[1] == "on": config = ConfigParser() config.read("config/data/fprot.meta") config.add_section(self.client.username) fp = open("config/data/fprot.meta", "w") config.write(fp) fp.close() self.client.sendServerMessage("Fetch protection is now on.") elif parts[1] == "off": config = ConfigParser() config.read("config/data/fprot.meta") config.remove_section(self.client.username) fp = open("config/data/fprot.meta", "w") config.write(fp) fp.close() self.client.sendServerMessage("Fetch protection is now off.") else: self.client.sendServerMessage("You must specify either 'on' or 'off'.")
def reset(self, name): # If custom conf file is not set then it is only read only configs if self.custom_conf_file is None: raise GconfNotConfigurable() # If a config can not be modified if name != "all" and not self._is_configurable(name): raise GconfNotConfigurable() cnf = RawConfigParser() with open(self.custom_conf_file) as f: cnf.readfp(f) # Nothing to Reset, Not configured if name != "all": if not cnf.has_option("vars", name): return True # Remove option from custom conf file cnf.remove_option("vars", name) else: # Remove and add empty section, do not disturb if config file # already has any other section try: cnf.remove_section("vars") except NoSectionError: pass cnf.add_section("vars") with open(self.tmp_conf_file, "w") as fw: cnf.write(fw) os.rename(self.tmp_conf_file, self.custom_conf_file) self.reload() return True
def from_file(self, infile): config = ConfParser(allow_no_value=True) config.read(infile) sections = config.sections() required = list(self.SECTIONS['required']) for section in sections: if section in required: required.remove(section) if required: m = 'Required section(s) not found. {}' raise ValueError(m.format(required)) for required in self.SECTIONS['required']: method_name = 'load_' + required method = getattr(self, method_name, None) if method: method(config.items(required)) config.remove_section(required) else: m = 'Required class method not found. "{}()"' raise AttributeError(m.format(method_name)) for gateway in self.gateways: if gateway not in self.routers: m = 'Gateway not in routers. [{}]'.format(gateway) raise ValueError(m) for optional in self.SECTIONS['optional']: method_name = 'load_' + optional method = getattr(self, method_name, None) if method: method(config.items(optional)) config.remove_section(optional) sections = config.sections() for section in sections: network = {section: []} for i, item in enumerate(config.items(section)): option, value = item values = self.string2list(value) network[section].append({option: values}) self.networks.append(network)
def commandTeleProtect(self, parts, fromloc, overriderank): "/tpp on|off - Mod\nEngages TeleProtection for yourself." if len(parts) != 2: self.client.sendServerMessage( "You must specify either \'on\' or \'off\'.") elif parts[1] == "on": config = ConfigParser() config.read('config/data/tpprot.meta') config.add_section(self.client.username) fp = open('config/data/tpprot.meta', "w") config.write(fp) fp.close() self.client.sendServerMessage("Teleport protection is now on.") elif parts[1] == "off": config = ConfigParser() config.read('config/data/tpprot.meta') config.remove_section(self.client.username) fp = open('config/data/tpprot.meta', "w") config.write(fp) fp.close() self.client.sendServerMessage("Teleport protection is now off.") else: self.client.sendServerMessage( "You must specify either \'on\' or \'off\'.")
def remove_project(project_name): """Remove a project from the global configuration file. :param project_name: Name of the project to remove. :type project_name: str :return: True if the project existed :rtype: bool """ path = locate_config_file() parser = RawConfigParser() parser.read(path) result = parser.remove_section(project_name) if result: with open(path, "w") as f: parser.write(f) return result
def remove_project(project_name): """Remove a project from the global configuration file. :param project_name: Name of the project to remove. :type project_name: str :return: True if the project existed :rtype: bool :Example: >>> view_projects() Project skynet with specfile at /path/to/skynet.yaml Project south park with specfile at /path/to/south_park.yaml >>> remove_project('skynet') >>> view_projects() Project south park with specfile at /path/to/south_park.yaml """ path = locate_config_file() parser = RawConfigParser() parser.read(path) result = parser.remove_section(project_name) if result: with open(path, "w") as f: parser.write(f) return result
def remove_project(project_name): """Remove a project from the global configuration file. :param project_name: Name of the project to remove. :type project_name: str :return: True if the project existed :rtype: bool :Example: >>> view_projects() Project skynet with specfile at /path/to/skynet.yaml Project south park with specfile at /path/to/south_park.yaml >>> remove_project('skynet') >>> view_projects() Project south park with specfile at /path/to/south_park.yaml """ path = locate_config_file() parser = RawConfigParser() parser.read(path) result = parser.remove_section(project_name) if result: with open(path, "w") as f: parser.write(f) return result
class Config(object): """A wrapper around RawConfigParser""" def __init__(self): """Use read() to read in an existing config file""" self._config = ConfigParser(dict_type=_sorted_dict) self._initial = {} def set_inital(self, section, option, value): """Set an initial value for an option. The section must be added with add_section() first. Adds the value to the config and calling reset() will reset the value to it. """ self.set(section, option, value) self._initial.setdefault(section, {}) self._initial[section].setdefault(option, {}) self._initial[section][option] = value def reset(self, section, option): """Reset the value to the initial state""" value = self._initial[section][option] self.set(section, option, value) def options(self, section): """Returns a list of options available in the specified section.""" return self._config.options(section) def get(self, *args): """get(section, option[, default]) -> str If default is not given, raises Error in case of an error """ if len(args) == 3: try: return self._config.get(*args[:2]) except Error: return args[-1] return self._config.get(*args) def getboolean(self, *args): """getboolean(section, option[, default]) -> bool If default is not given, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], bool): raise ValueError try: return self._config.getboolean(*args[:2]) # ValueError if the value found in the config file # does not match any string representation -> so catch it too except (ValueError, Error): return args[-1] return self._config.getboolean(*args) def getint(self, *args): """getint(section, option[, default]) -> int If default is not give, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], int): raise ValueError try: return self._config.getint(*args[:2]) except Error: return args[-1] return self._config.getint(*args) def getfloat(self, *args): """getfloat(section, option[, default]) -> float If default is not give, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], float): raise ValueError try: return self._config.getfloat(*args[:2]) except Error: return args[-1] return self._config.getfloat(*args) def getstringlist(self, *args): """getstringlist(section, option[, default]) -> list If default is not given, raises Error in case of an error. Gets a list of strings, using CSV to parse and delimit. """ if len(args) == 3: if not isinstance(args[-1], list): raise ValueError try: value = self._config.get(*args[:2]) except Error: return args[-1] else: value = self._config.get(*args) parser = csv.reader([value], lineterminator='\n', quoting=csv.QUOTE_MINIMAL) try: vals = [v.decode('utf-8') for v in parser.next()] except (csv.Error, ValueError) as e: raise Error(e) return vals def setstringlist(self, section, option, values): """Saves a list of unicode strings using the csv module""" sw = StringIO() values = [unicode(v).encode('utf-8') for v in values] writer = csv.writer(sw, lineterminator='\n', quoting=csv.QUOTE_MINIMAL) writer.writerow(values) self._config.set(section, option, sw.getvalue()) def set(self, section, option, value): """Saves the string representation for the passed value Don't pass unicode, encode first. """ # RawConfigParser only allows string values but doesn't # scream if they are not (and it only fails before the # first config save..) if not isinstance(value, str): value = str(value) self._config.set(section, option, value) def setdefault(self, section, option, default): """Like set but only sets the new value if the option isn't set before. """ if not self._config.has_option(section, option): self._config.set(section, option, default) def write(self, filename): """Write config to filename. Can raise EnvironmentError """ assert is_fsnative(filename) mkdir(os.path.dirname(filename)) with atomic_save(filename, ".tmp", "wb") as fileobj: self._config.write(fileobj) def clear(self): """Remove all sections and initial values""" for section in self._config.sections(): self._config.remove_section(section) self._initial.clear() def is_empty(self): """Whether the config has any sections""" return not self._config.sections() def read(self, filename): """Reads the config from `filename` if the file exists, otherwise does nothing Can raise EnvironmentError, Error. """ self._config.read(filename) def sections(self): """Return a list of the sections available""" return self._config.sections() def has_option(self, section, option): """If the given section exists, and contains the given option""" return self._config.has_option(section, option) def remove_option(self, section, option): """Remove the specified option from the specified section Can raise Error. """ return self._config.remove_option(section, option) def add_section(self, section): """Add a section named section to the instance if it not already exists.""" if not self._config.has_section(section): self._config.add_section(section)
class Config(object): def __init__(self, buildout_dir): self.cfg_path = os.path.join(buildout_dir, '.mr.developer.cfg') self._config = RawConfigParser() self._config.optionxform = lambda s: s self._config.read(self.cfg_path) self.develop = {} self.buildout_args = [] self.rewrites = [] if self._config.has_section('develop'): for package, value in self._config.items('develop'): value = value.lower() if value == 'true': self.develop[package] = True elif value == 'false': self.develop[package] = False elif value == 'auto': self.develop[package] = 'auto' else: raise ValueError( "Invalid value in 'develop' section of '%s'" % self.cfg_path) if self._config.has_option('buildout', 'args'): args = self._config.get('buildout', 'args').split("\n") for arg in args: arg = arg.strip() if arg.startswith("'") and arg.endswith("'"): arg = arg[1:-1].replace("\\'", "'") elif arg.startswith('"') and arg.endswith('"'): arg = arg[1:-1].replace('\\"', '"') self.buildout_args.append(arg) (self.buildout_options, self.buildout_settings, _) = \ parse_buildout_args(self.buildout_args[1:]) if self._config.has_option('mr.developer', 'rewrites'): for rewrite in self._config.get('mr.developer', 'rewrites').split('\n'): self.rewrites.append(rewrite.split()) def save(self): self._config.remove_section('develop') self._config.add_section('develop') for package in sorted(self.develop): state = self.develop[package] if state is 'auto': self._config.set('develop', package, 'auto') elif state is True: self._config.set('develop', package, 'true') elif state is False: self._config.set('develop', package, 'false') if not self._config.has_section('buildout'): self._config.add_section('buildout') options, settings, args = parse_buildout_args(self.buildout_args[1:]) # don't store the options when a command was in there if not len(args): self._config.set('buildout', 'args', "\n".join(repr(x) for x in self.buildout_args)) if not self._config.has_section('mr.developer'): self._config.add_section('mr.developer') self._config.set('mr.developer', 'rewrites', "\n".join(" ".join(x) for x in self.rewrites)) self._config.write(open(self.cfg_path, "w"))
class Config(object): """A wrapper around RawConfigParser""" def __init__(self, version=None): """Use read() to read in an existing config file. version should be an int starting with 0 that gets incremented if you want to register a new upgrade function. If None, upgrade is disabled. """ self._config = ConfigParser(dict_type=_sorted_dict) self._version = version self._loaded_version = None self._upgrade_funcs = [] self._initial = {} def _do_upgrade(self, func): assert self._loaded_version is not None assert self._version is not None old_version = self._loaded_version new_version = self._version if old_version != new_version: print_d("Config upgrade: %d->%d (%r)" % (old_version, new_version, func)) func(self, old_version, new_version) def get_version(self): """Get the version of the loaded config file (for testing only) Raises Error if no file was loaded or versioning is disabled. """ if self._version is None: raise Error("Versioning disabled") if self._loaded_version is None: raise Error("No file loaded") return self._loaded_version def register_upgrade_function(self, function): """Register an upgrade function that gets called at each read() if the current config version and the loaded version don't match. Can also be registered after read was called. function(config, old_version: int, new_version: int) -> None """ if self._version is None: raise Error("Versioning disabled") self._upgrade_funcs.append(function) # after read(), so upgrade now if self._loaded_version is not None: self._do_upgrade(function) return function def set_inital(self, section, option, value): """Set an initial value for an option. The section must be added with add_section() first. Adds the value to the config and calling reset() will reset the value to it. """ self.set(section, option, value) self._initial.setdefault(section, {}) self._initial[section].setdefault(option, {}) self._initial[section][option] = value def reset(self, section, option): """Reset the value to the initial state""" value = self._initial[section][option] self.set(section, option, value) def options(self, section): """Returns a list of options available in the specified section.""" return self._config.options(section) def get(self, *args): """get(section, option[, default]) -> str If default is not given, raises Error in case of an error """ if len(args) == 3: try: return self._config.get(*args[:2]) except Error: return args[-1] return self._config.get(*args) def getboolean(self, *args): """getboolean(section, option[, default]) -> bool If default is not given, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], bool): raise ValueError try: return self._config.getboolean(*args[:2]) # ValueError if the value found in the config file # does not match any string representation -> so catch it too except (ValueError, Error): return args[-1] return self._config.getboolean(*args) def getint(self, *args): """getint(section, option[, default]) -> int If default is not give, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], int): raise ValueError try: return self._config.getint(*args[:2]) except Error: return args[-1] return self._config.getint(*args) def getfloat(self, *args): """getfloat(section, option[, default]) -> float If default is not give, raises Error in case of an error """ if len(args) == 3: if not isinstance(args[-1], float): raise ValueError try: return self._config.getfloat(*args[:2]) except Error: return args[-1] return self._config.getfloat(*args) def getstringlist(self, *args): """getstringlist(section, option[, default]) -> list If default is not given, raises Error in case of an error. Gets a list of strings, using CSV to parse and delimit. """ if len(args) == 3: if not isinstance(args[-1], list): raise ValueError try: value = self._config.get(*args[:2]) except Error: return args[-1] else: value = self._config.get(*args) parser = csv.reader([value], lineterminator='\n', quoting=csv.QUOTE_MINIMAL) try: vals = [v.decode('utf-8') for v in parser.next()] except (csv.Error, ValueError) as e: raise Error(e) return vals def setstringlist(self, section, option, values): """Saves a list of unicode strings using the csv module""" sw = StringIO() values = [unicode(v).encode('utf-8') for v in values] writer = csv.writer(sw, lineterminator='\n', quoting=csv.QUOTE_MINIMAL) writer.writerow(values) self._config.set(section, option, sw.getvalue()) def set(self, section, option, value): """Saves the string representation for the passed value Don't pass unicode, encode first. """ # RawConfigParser only allows string values but doesn't # scream if they are not (and it only fails before the # first config save..) if not isinstance(value, str): value = str(value) self._config.set(section, option, value) def setdefault(self, section, option, default): """Like set but only sets the new value if the option isn't set before. """ if not self._config.has_option(section, option): self._config.set(section, option, default) def write(self, filename): """Write config to filename. Can raise EnvironmentError """ assert is_fsnative(filename) mkdir(os.path.dirname(filename)) # temporary set the new version for saving if self._version is not None: self.add_section("__config__") self.set("__config__", "version", self._version) try: with atomic_save(filename, ".tmp", "wb") as fileobj: self._config.write(fileobj) finally: if self._loaded_version is not None: self.set("__config__", "version", self._loaded_version) def clear(self): """Remove all sections and initial values""" for section in self._config.sections(): self._config.remove_section(section) self._initial.clear() def is_empty(self): """Whether the config has any sections""" return not self._config.sections() def read(self, filename): """Reads the config from `filename` if the file exists, otherwise does nothing Can raise EnvironmentError, Error. """ parsed_filenames = self._config.read(filename) # don't upgrade if we just created a new config if parsed_filenames and self._version is not None: self._loaded_version = self.getint("__config__", "version", -1) for func in self._upgrade_funcs: self._do_upgrade(func) def sections(self): """Return a list of the sections available""" return self._config.sections() def has_option(self, section, option): """If the given section exists, and contains the given option""" return self._config.has_option(section, option) def remove_option(self, section, option): """Remove the specified option from the specified section Can raise Error. """ return self._config.remove_option(section, option) def add_section(self, section): """Add a section named section to the instance if it not already exists.""" if not self._config.has_section(section): self._config.add_section(section)
class Tracker: "Provides a unique access point to the configuration file" MAX = 5 CONFIG_FILE = '%s/.noch_less.cnf' % expanduser('~') def __init__(self): """ Instance variables: config """ try: self.config = RawConfigParser() self.config.read(self.CONFIG_FILE) self.remove_excess() except: pass def add(self, less_file): if self.count() >= self.MAX: return "You can't add more than %s files." % self.MAX if self.config.has_section(less_file.id): return "The file %s is already being tracked." % less_file.id self.config.add_section(less_file.id) self.config.set(less_file.id, 'source', less_file.source) self.config.set(less_file.id, 'destination', less_file.destination) self.save() return True def modify(self, less_file): self.config.set(less_file.id, 'destination', less_file.destination) self.save() def remove(self, less_file): self.config.remove_section(less_file.id) self.save() def remove_excess(self): if self.count() >= self.MAX: count = 0 for section in self.config.sections(): count += 1 if count > self.MAX: self.config.remove_section(section) self.save() def all(self): all_sections = [] for section in self.config.sections(): lessie = {'id': section} lessie['source'] = self.config.get(section, 'source') lessie['destination'] = self.config.get(section, 'destination') all_sections.append(lessie) return all_sections def save(self): with open(self.CONFIG_FILE, 'wb') as file: self.config.write(file) def count(self): return len(self.config.sections())
class ConfigINIFile(object): def __init__(self, path=None, load=False, caseSensitive=True): self.parser = RawConfigParser() if caseSensitive: self.parser.optionxform = str #options are case sensitive, and not converted to lower case during load self.path = path self._valuehooks = defaultdict(dict) self._valuehooks.update({ 'default': defaultdict(dict), 'formatter': defaultdict(dict) }) self._mandatorySections = [] self._mandatoryOptions = defaultdict(list) if load: self.load() def load(self, path=None): path = path or self.path if not path: raise RuntimeError( 'Failed to load configuration file, No path specified') self.parser.read(path) return self def mandatory(self, sections): self._mandatorySections = [sections] if isinstance(sections, str) else sections def mandatoryOptions(self, section, options): self._mandatoryOptions[section] = [options] if isinstance( options, str) else options def sections(self): return self.parser.sections() def section(self, section, get_defaults=True): actual_options = self.parser.options( section) #actual options set in the config INI file all_defaults = self._valuehooks['default'][section].keys( ) #all options with default values options = list( set(actual_options) | set(all_defaults) ) #options = union of actual options loaded from file + options with defautls set values = [self.get(section, option) for option in options] section = dict(zip(options, values)) return section def addSection(self, section, save=False): self.parser.add_section(section) if save: self.save() def removeSection(self, section, save=False): self.parser.remove_section(section) if save: self.save() def __contains__(self, section): return self.parser.has_section(section) def __getitem__(self, section): return self.section(section) def __setitem__(self, section): return self.addSection(section) def __delitem__(self, section): return self.removeSection(section) def options(self, section): return self.parser.options(section) def get(self, section, option): try: value = self.parser.get(section, option) except NoOptionError: value = self.defaultValue(section, option) if value is None: raise return self.formatValue(section, option, value) def getint(self, section, option): return self.parser.getint(section, option) def getfloat(self, section, option): return self.parser.getfloat(section, option) def hasOption(self, section, option): return self.parser.has_option(section, option) def setOption(self, section, option, value, save=False): self.parser.set(section, option, value) if save: self.save() def removeOption(self, section, option, save=False): self.parser.remove_option(section, option) if save: self.save() def _addValuehook(self, hooklabel, func, section=None, options=None): if not section: section = 'ALL' else: self._valuehooks[hooklabel].pop('ALL', '') if not options: self._valuehooks[hooklabel][section]['ALL'] = func else: options = [options] if isinstance(options, str) else options self._valuehooks[hooklabel][section].pop('ALL', '') for option in options: self._valuehooks[hooklabel][section][option] = func def _applyValuehook(self, hooklabel, section, option, value=None): # logger.debug('%s(%s, %s, %s)', hooklabel, section, option, value) hooks = self._valuehooks[hooklabel] if section not in hooks: if 'ALL' not in hooks: return value else: section = 'ALL' if option not in hooks[section]: if 'ALL' not in hooks[section]: return value else: option = 'ALL' return hooks[section][option](value) def formatter(self, func, section=None, options=None): ''' Install a formatter func for <section|ALL>.[<options1>, <option2>, ...|ALL]. func(value) would be returned instead of value ''' self._addValuehook('formatter', func, section, options) def default(self, value, section=None, options=None): ''' Set a default value for configuration <section|ALL>.[<options1>, <option2>, ...|ALL] Makes use of the generic value hooks feature. Note that a value hook func should accept a single argument <value> We worked around this interface here by defining lambda *args: value, this way the function wouldn not complain about the "dummuy" argument passed to it ''' self._addValuehook('default', lambda *args: value, section, options) def formatValue(self, section, option, value): ''' Format a value prior to returning to client code, e.g. split comma separated values into a list of strings ''' return self._applyValuehook('formatter', section, option, value) def defaultValue(self, section, option): ''' Retreive the default value for section.option ''' return self._applyValuehook('default', section, option, None) def validate(self): self.validateMandatorySections() for section in self.sections(): self.validateSection(section) def validateMandatorySections(self): result = [ section in self.sections() for section in self._mandatorySections ] if not all(result): missingSections = [ self._mandatorySections[idx] for idx, exists in enumerate(result) if not exists ] raise RuntimeError('Invalid Configuration, missing sections %s' % missingSections) def validateSection(self, section): self.validateMandatoryOptions(section) def validateMandatoryOptions(self, section): result = [ option in self.options(section) for option in self._mandatoryOptions[section] ] if not all(result): missingOptions = [ self._mandatoryOptions[section][idx] for idx, exists in enumerate(result) if not exists ] raise RuntimeError( 'Invalid Configuration, missing configuration options %s in section [%s]' % (missingOptions, section)) def save(self, saveas=None): path = saveas or self.path with open(path, 'w') as cfgfile: self.parser.write(cfgfile)
class Config(object): """A wrapper around RawConfigParser. Provides a ``defaults`` attribute of the same type which can be used to set default values. """ def __init__(self, version=None, _defaults=True): """Use read() to read in an existing config file. version should be an int starting with 0 that gets incremented if you want to register a new upgrade function. If None, upgrade is disabled. """ self._config = ConfigParser(dict_type=_sorted_dict) self.defaults = None if _defaults: self.defaults = Config(_defaults=False) self._version = version self._loaded_version = None self._upgrade_funcs = [] def _do_upgrade(self, func): assert self._loaded_version is not None assert self._version is not None old_version = self._loaded_version new_version = self._version if old_version != new_version: print_d("Config upgrade: %d->%d (%r)" % ( old_version, new_version, func)) func(self, old_version, new_version) def get_version(self): """Get the version of the loaded config file (for testing only) Raises Error if no file was loaded or versioning is disabled. """ if self._version is None: raise Error("Versioning disabled") if self._loaded_version is None: raise Error("No file loaded") return self._loaded_version def register_upgrade_function(self, function): """Register an upgrade function that gets called at each read() if the current config version and the loaded version don't match. Can also be registered after read was called. function(config, old_version: int, new_version: int) -> None """ if self._version is None: raise Error("Versioning disabled") self._upgrade_funcs.append(function) # after read(), so upgrade now if self._loaded_version is not None: self._do_upgrade(function) return function def reset(self, section, option): """Reset the value to the default state""" assert self.defaults is not None self.set(section, option, self.defaults.get(section, option)) def options(self, section): """Returns a list of options available in the specified section.""" try: options = self._config.options(section) except NoSectionError: if self.defaults: return self.defaults.options(section) raise else: if self.defaults: try: options.extend(self.defaults.options(section)) options = list_unique(options) except NoSectionError: pass return options def get(self, section, option, default=_DEFAULT): """get(section, option[, default]) -> str If default is not given or set, raises Error in case of an error """ try: return self._config.get(section, option) except Error: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.get(section, option) except Error: pass raise return default def gettext(self, *args, **kwargs): value = self.get(*args, **kwargs) if PY2: value = value.decode("utf-8") else: # make sure there are no surrogates value.encode("utf-8") return value def getbytes(self, section, option, default=_DEFAULT): try: value = self._config.get(section, option) if PY3: value = value.encode("utf-8", "surrogateescape") return value except (Error, ValueError) as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getbytes(section, option) except Error: pass raise Error(e) return default def getboolean(self, section, option, default=_DEFAULT): """getboolean(section, option[, default]) -> bool If default is not given or set, raises Error in case of an error """ try: return self._config.getboolean(section, option) except (Error, ValueError) as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getboolean(section, option) except Error: pass raise Error(e) return default def getint(self, section, option, default=_DEFAULT): """getint(section, option[, default]) -> int If default is not give or set, raises Error in case of an error """ try: return int(self._config.getfloat(section, option)) except (Error, ValueError) as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getint(section, option) except Error: pass raise Error(e) return default def getfloat(self, section, option, default=_DEFAULT): """getfloat(section, option[, default]) -> float If default is not give or set, raises Error in case of an error """ try: return self._config.getfloat(section, option) except (Error, ValueError) as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getfloat(section, option) except Error: pass raise Error(e) return default def getstringlist(self, section, option, default=_DEFAULT): """getstringlist(section, option[, default]) -> list If default is not given or set, raises Error in case of an error. Gets a list of strings, using CSV to parse and delimit. """ try: value = self._config.get(section, option) parser = csv.reader( [value], lineterminator='\n', quoting=csv.QUOTE_MINIMAL) try: if PY2: vals = [v.decode('utf-8') for v in next(parser)] else: vals = next(parser) except (csv.Error, ValueError) as e: raise Error(e) return vals except Error as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getstringlist(section, option) except Error: pass raise Error(e) return default def setstringlist(self, section, option, values): """Saves a list of unicode strings using the csv module""" if PY2: sw = cBytesIO() values = [text_type(v).encode('utf-8') for v in values] else: sw = StringIO() values = [text_type(v) for v in values] writer = csv.writer(sw, lineterminator='\n', quoting=csv.QUOTE_MINIMAL) writer.writerow(values) self.set(section, option, sw.getvalue()) def setlist(self, section, option, values, sep=","): """Saves a list of str using ',' as a separator and \\ for escaping""" values = [str(v) for v in values] joined = join_escape(values, sep) self.set(section, option, joined) def getlist(self, section, option, default=_DEFAULT, sep=","): """Returns a str list saved with setlist()""" try: value = self._config.get(section, option) return split_escape(value, sep) except (Error, ValueError) as e: if default is _DEFAULT: if self.defaults is not None: try: return self.defaults.getlist(section, option, sep=sep) except Error: pass raise Error(e) return default def set(self, section, option, value): """Saves the string representation for the passed value Don't pass unicode, encode first. """ if PY3 and isinstance(value, bytes): raise TypeError("use setbytes") # RawConfigParser only allows string values but doesn't # scream if they are not (and it only fails before the # first config save..) if not isinstance(value, str): value = str(value) try: self._config.set(section, option, value) except NoSectionError: if self.defaults and self.defaults.has_section(section): self._config.add_section(section) self._config.set(section, option, value) else: raise def settext(self, section, option, value): value = text_type(value) if PY2: value = value.encode("utf-8") else: # make sure there are no surrogates value.encode("utf-8") self.set(section, option, value) def setbytes(self, section, option, value): assert isinstance(value, bytes) if PY3: value = value.decode("utf-8", "surrogateescape") self.set(section, option, value) def write(self, filename): """Write config to filename. Can raise EnvironmentError """ assert isinstance(filename, fsnative) mkdir(os.path.dirname(filename)) # temporary set the new version for saving if self._version is not None: self.add_section("__config__") self.set("__config__", "version", self._version) try: with atomic_save(filename, "wb") as fileobj: if PY2: self._config.write(fileobj) else: temp = StringIO() self._config.write(temp) data = temp.getvalue().encode("utf-8", "surrogateescape") fileobj.write(data) finally: if self._loaded_version is not None: self.set("__config__", "version", self._loaded_version) def clear(self): """Remove all sections.""" for section in self._config.sections(): self._config.remove_section(section) def is_empty(self): """Whether the config has any sections""" return not self._config.sections() def read(self, filename): """Reads the config from `filename` if the file exists, otherwise does nothing Can raise EnvironmentError, Error. """ try: with open(filename, "rb") as fileobj: if PY3: fileobj = StringIO( fileobj.read().decode("utf-8", "surrogateescape")) self._config.readfp(fileobj, filename) except (IOError, OSError): return # don't upgrade if we just created a new config if self._version is not None: self._loaded_version = self.getint("__config__", "version", -1) for func in self._upgrade_funcs: self._do_upgrade(func) def has_option(self, section, option): """If the given section exists, and contains the given option""" return self._config.has_option(section, option) or ( self.defaults and self.defaults.has_option(section, option)) def has_section(self, section): """If the given section exists""" return self._config.has_section(section) or ( self.defaults and self.defaults.has_section(section)) def remove_option(self, section, option): """Remove the specified option from the specified section Can raise Error. """ return self._config.remove_option(section, option) def add_section(self, section): """Add a section named section to the instance if it not already exists.""" if not self._config.has_section(section): self._config.add_section(section)
def execute(*args, **kw): if not os.path.isfile('/etc/kolab-freebusy/config.ini') and not os.path.isfile('/etc/kolab-freebusy/config.ini.sample'): log.error(_("Free/Busy is not installed on this system")) return if not os.path.isfile('/etc/kolab-freebusy/config.ini'): os.rename('/etc/kolab-freebusy/config.ini.sample', '/etc/kolab-freebusy/config.ini') imap_backend = conf.get('kolab', 'imap_backend') admin_login = conf.get(imap_backend, 'admin_login') admin_password = conf.get(imap_backend, 'admin_password') imap_uri = conf.get(imap_backend, 'imap_uri') if imap_uri == None: imap_uri = conf.get(imap_backend, 'uri') scheme = None hostname = None port = None result = urlparse(imap_uri) if hasattr(result, 'hostname'): hostname = result.hostname else: scheme = imap_uri.split(':')[0] (hostname, port) = imap_uri.split('/')[2].split(':') if port == None: port = 993 if scheme == None or scheme == "": scheme = 'imaps' if scheme == "imaps" and port == 993: scheme = "imap" port = 143 resources_imap_uri = '%s://%s:%s@%s:%s/%%kolabtargetfolder?acl=lrs' % (scheme, admin_login, admin_password, hostname, port) users_imap_uri = '%s://%%s:%s@%s:%s/?proxy_auth=%s' % (scheme, admin_password, hostname, port, admin_login) freebusy_settings = { 'directory "local"': { 'type': 'static', 'fbsource': 'file:/var/lib/kolab-freebusy/%s.ifb', }, 'directory "local-cache"': { 'type': 'static', 'fbsource': 'file:/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m' }, 'directory "kolab-people"': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'filter': '(&(objectClass=kolabInetOrgPerson)(|(mail=%s)(alias=%s)))', 'attributes': 'mail', 'lc_attributes': 'mail', 'fbsource': users_imap_uri, 'cacheto': '/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m', 'loglevel': 300, }, 'directory "kolab-resources"': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'resource_base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'attributes': 'mail, kolabtargetfolder', 'filter': '(&(objectClass=kolabsharedfolder)(kolabfoldertype=event)(mail=%s))', 'fbsource': resources_imap_uri, 'cacheto': '/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m', 'loglevel': 300, }, } cfg_parser = RawConfigParser() cfg_parser.read('/etc/kolab-freebusy/config.ini') for section in freebusy_settings.keys(): if len(freebusy_settings[section].keys()) < 1: cfg_parser.remove_section(section) continue for key in freebusy_settings[section].keys(): if not cfg_parser.has_section(section): cfg_parser.add_section(section) cfg_parser.set(section, key, freebusy_settings[section][key]) fp = open('/etc/kolab-freebusy/config.ini', "w+") cfg_parser.write(fp) fp.close()
class Config(object): """A wrapper around RawConfigParser""" def __init__(self, version=None): """Use read() to read in an existing config file. version should be an int starting with 0 that gets incremented if you want to register a new upgrade function. If None, upgrade is disabled. """ self._config = ConfigParser(dict_type=_sorted_dict) self._version = version self._loaded_version = None self._upgrade_funcs = [] self._initial = {} def _do_upgrade(self, func): assert self._loaded_version is not None assert self._version is not None old_version = self._loaded_version new_version = self._version if old_version != new_version: print_d("Config upgrade: %d->%d (%r)" % ( old_version, new_version, func)) func(self, old_version, new_version) def get_version(self): """Get the version of the loaded config file (for testing only) Raises Error if no file was loaded or versioning is disabled. """ if self._version is None: raise Error("Versioning disabled") if self._loaded_version is None: raise Error("No file loaded") return self._loaded_version def register_upgrade_function(self, function): """Register an upgrade function that gets called at each read() if the current config version and the loaded version don't match. Can also be registered after read was called. function(config, old_version: int, new_version: int) -> None """ if self._version is None: raise Error("Versioning disabled") self._upgrade_funcs.append(function) # after read(), so upgrade now if self._loaded_version is not None: self._do_upgrade(function) return function def set_inital(self, section, option, value): """Set an initial value for an option. The section must be added with add_section() first. Adds the value to the config and calling reset() will reset the value to it. """ self.set(section, option, value) self._initial.setdefault(section, {}) self._initial[section].setdefault(option, {}) self._initial[section][option] = value def reset(self, section, option): """Reset the value to the initial state""" value = self._initial[section][option] self.set(section, option, value) def options(self, section): """Returns a list of options available in the specified section.""" return self._config.options(section) def get(self, section, option, default=_DEFAULT): """get(section, option[, default]) -> str If default is not given, raises Error in case of an error """ try: return self._config.get(section, option) except Error: if default is _DEFAULT: raise return default def getboolean(self, section, option, default=_DEFAULT): """getboolean(section, option[, default]) -> bool If default is not given, raises Error in case of an error """ try: return self._config.getboolean(section, option) except Error: if default is _DEFAULT: raise if not isinstance(default, bool): raise ValueError return default def getint(self, section, option, default=_DEFAULT): """getint(section, option[, default]) -> int If default is not give, raises Error in case of an error """ try: return self._config.getint(section, option) except Error: if default is _DEFAULT: raise if not isinstance(default, int): raise ValueError return default def getfloat(self, section, option, default=_DEFAULT): """getfloat(section, option[, default]) -> float If default is not give, raises Error in case of an error """ try: return self._config.getfloat(section, option) except Error: if default is _DEFAULT: raise if not isinstance(default, float): raise ValueError return default def getstringlist(self, section, option, default=_DEFAULT): """getstringlist(section, option[, default]) -> list If default is not given, raises Error in case of an error. Gets a list of strings, using CSV to parse and delimit. """ try: value = self._config.get(section, option) except Error: if default is _DEFAULT: raise if not isinstance(default, list): raise ValueError return default parser = csv.reader( [value], lineterminator='\n', quoting=csv.QUOTE_MINIMAL) try: vals = [v.decode('utf-8') for v in parser.next()] except (csv.Error, ValueError) as e: raise Error(e) return vals def setstringlist(self, section, option, values): """Saves a list of unicode strings using the csv module""" sw = StringIO() values = [unicode(v).encode('utf-8') for v in values] writer = csv.writer(sw, lineterminator='\n', quoting=csv.QUOTE_MINIMAL) writer.writerow(values) self._config.set(section, option, sw.getvalue()) def setlist(self, section, option, values, sep=","): """Saves a list of str using ',' as a separator and \\ for escaping""" values = map(str, values) joined = join_escape(values, sep) self._config.set(section, option, joined) def getlist(self, section, option, default=_DEFAULT, sep=","): """Returns a str list saved with setlist()""" try: value = self._config.get(section, option) except Error: if default is _DEFAULT: raise if not isinstance(default, list): raise ValueError return default return split_escape(value, sep) def set(self, section, option, value): """Saves the string representation for the passed value Don't pass unicode, encode first. """ # RawConfigParser only allows string values but doesn't # scream if they are not (and it only fails before the # first config save..) if not isinstance(value, str): value = str(value) self._config.set(section, option, value) def setdefault(self, section, option, default): """Like set but only sets the new value if the option isn't set before. """ if not self._config.has_option(section, option): self._config.set(section, option, default) def write(self, filename): """Write config to filename. Can raise EnvironmentError """ assert is_fsnative(filename) mkdir(os.path.dirname(filename)) # temporary set the new version for saving if self._version is not None: self.add_section("__config__") self.set("__config__", "version", self._version) try: with atomic_save(filename, ".tmp", "wb") as fileobj: self._config.write(fileobj) finally: if self._loaded_version is not None: self.set("__config__", "version", self._loaded_version) def clear(self): """Remove all sections and initial values""" for section in self._config.sections(): self._config.remove_section(section) self._initial.clear() def is_empty(self): """Whether the config has any sections""" return not self._config.sections() def read(self, filename): """Reads the config from `filename` if the file exists, otherwise does nothing Can raise EnvironmentError, Error. """ parsed_filenames = self._config.read(filename) # don't upgrade if we just created a new config if parsed_filenames and self._version is not None: self._loaded_version = self.getint("__config__", "version", -1) for func in self._upgrade_funcs: self._do_upgrade(func) def sections(self): """Return a list of the sections available""" return self._config.sections() def has_option(self, section, option): """If the given section exists, and contains the given option""" return self._config.has_option(section, option) def remove_option(self, section, option): """Remove the specified option from the specified section Can raise Error. """ return self._config.remove_option(section, option) def add_section(self, section): """Add a section named section to the instance if it not already exists.""" if not self._config.has_section(section): self._config.add_section(section)
class Config(object): def __init__(self): self._config = RawConfigParser() # A convenient place for other code to store a file name. self.target_file = None def _path_to_config_value(self, path): ''' Return config value for a path. If the path is below CONFIG_DIR, a relative path to it is returned, otherwise, an absolute path is returned. Note: relative path are automatically assumed to be relative to CONFIG_DIR. ''' path = os.path.realpath(os.path.join(CONFIG_DIR, path)) config_dir = os.path.realpath(CONFIG_DIR) + os.sep if path.startswith(config_dir): return path[len(config_dir):] else: return path def _path_from_config_value(self, value): ''' Return a path from a config value. If value is an absolute path, it is returned as is otherwise, an absolute path relative to CONFIG_DIR is returned. ''' return os.path.realpath(os.path.join(CONFIG_DIR, value)) def load(self, fp): self._config = RawConfigParser() try: self._config.readfp(fp) except ConfigParser.Error as e: raise InvalidConfigurationError(str(e)) def clear(self): self._config = RawConfigParser() def save(self, fp): self._config.write(fp) def clone(self): f = StringIO() self.save(f) c = Config() f.seek(0, 0) c.load(f) return c def set_machine_type(self, machine_type): self._set(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, machine_type) def get_machine_type(self): return self._get(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, DEFAULT_MACHINE_TYPE) def set_machine_specific_options(self, machine_name, options): if self._config.has_section(machine_name): self._config.remove_section(machine_name) self._config.add_section(machine_name) for k, v in options.items(): self._config.set(machine_name, k, str(v)) def get_machine_specific_options(self, machine_name): def convert(p, v): try: return p[1](v) except ValueError: return p[0] machine = machine_registry.get(machine_name) info = machine.get_option_info() defaults = {k: v[0] for k, v in info.items()} if self._config.has_section(machine_name): options = { o: self._config.get(machine_name, o) for o in self._config.options(machine_name) if o in info } options = {k: convert(info[k], v) for k, v in options.items()} defaults.update(options) return defaults def set_dictionary_file_names(self, filenames): if self._config.has_section(DICTIONARY_CONFIG_SECTION): self._config.remove_section(DICTIONARY_CONFIG_SECTION) self._config.add_section(DICTIONARY_CONFIG_SECTION) filenames = [self._path_to_config_value(path) for path in filenames] for ordinal, filename in enumerate(filenames, start=1): option = DICTIONARY_FILE_OPTION + str(ordinal) self._config.set(DICTIONARY_CONFIG_SECTION, option, filename) def get_dictionary_file_names(self): filenames = [] if self._config.has_section(DICTIONARY_CONFIG_SECTION): options = filter(lambda x: x.startswith(DICTIONARY_FILE_OPTION), self._config.options(DICTIONARY_CONFIG_SECTION)) options.sort(key=_dict_entry_key) filenames = [ self._config.get(DICTIONARY_CONFIG_SECTION, o) for o in options ] if not filenames: filenames = DEFAULT_DICTIONARIES filenames = [self._path_from_config_value(path) for path in filenames] return filenames def set_log_file_name(self, filename): filename = self._path_to_config_value(filename) self._set(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, filename) def get_log_file_name(self): filename = self._get(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, DEFAULT_LOG_FILE) return self._path_from_config_value(filename) def set_enable_stroke_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, log) def get_enable_stroke_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, DEFAULT_ENABLE_STROKE_LOGGING) def set_enable_translation_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, log) def get_enable_translation_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, DEFAULT_ENABLE_TRANSLATION_LOGGING) def set_auto_start(self, b): self._set(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, b) def get_auto_start(self): return self._get_bool(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, DEFAULT_MACHINE_AUTO_START) def set_show_stroke_display(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, b) def get_show_stroke_display(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, DEFAULT_STROKE_DISPLAY_SHOW) def set_show_suggestions_display(self, b): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_SHOW_OPTION, b) def get_show_suggestions_display(self): return self._get_bool(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_SHOW_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_SHOW) def get_space_placement(self): return self._get(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, DEFAULT_OUTPUT_CONFIG_SPACE_PLACEMENT) def set_space_placement(self, s): self._set(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, s) def set_stroke_display_on_top(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, b) def get_stroke_display_on_top(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, DEFAULT_STROKE_DISPLAY_ON_TOP) def set_suggestions_display_on_top(self, b): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_ON_TOP_OPTION, b) def get_suggestions_display_on_top(self): return self._get_bool(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_ON_TOP_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_ON_TOP) def set_stroke_display_style(self, s): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, s) def get_stroke_display_style(self): return self._get(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, DEFAULT_STROKE_DISPLAY_STYLE) def set_stroke_display_x(self, x): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, x) def get_stroke_display_x(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, DEFAULT_STROKE_DISPLAY_X) def set_stroke_display_y(self, y): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, y) def get_stroke_display_y(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, DEFAULT_STROKE_DISPLAY_Y) def set_suggestions_display_x(self, x): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_X_OPTION, x) def get_suggestions_display_x(self): return self._get_int(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_X_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_X) def set_suggestions_display_y(self, y): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_Y_OPTION, y) def get_suggestions_display_y(self): return self._get_int(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_Y_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_Y) def set_config_frame_x(self, x): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, x) def get_config_frame_x(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, DEFAULT_CONFIG_FRAME_X) def set_config_frame_y(self, y): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, y) def get_config_frame_y(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, DEFAULT_CONFIG_FRAME_Y) def set_config_frame_width(self, width): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, width) def get_config_frame_width(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, DEFAULT_CONFIG_FRAME_WIDTH) def set_config_frame_height(self, height): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, height) def get_config_frame_height(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, DEFAULT_CONFIG_FRAME_HEIGHT) def set_main_frame_x(self, x): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, x) def get_main_frame_x(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, DEFAULT_MAIN_FRAME_X) def set_main_frame_y(self, y): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, y) def get_main_frame_y(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, DEFAULT_MAIN_FRAME_Y) def set_translation_frame_x(self, x): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, x) def get_translation_frame_x(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, DEFAULT_TRANSLATION_FRAME_X) def set_translation_frame_y(self, y): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, y) def get_translation_frame_y(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, DEFAULT_TRANSLATION_FRAME_Y) def set_lookup_frame_x(self, x): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, x) def get_lookup_frame_x(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, DEFAULT_LOOKUP_FRAME_X) def set_lookup_frame_y(self, y): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, y) def get_lookup_frame_y(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, DEFAULT_LOOKUP_FRAME_Y) def set_dictionary_editor_frame_x(self, x): self._set(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_X_OPTION, x) def get_dictionary_editor_frame_x(self): return self._get_int(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_X_OPTION, DEFAULT_DICTIONARY_EDITOR_FRAME_X) def set_dictionary_editor_frame_y(self, y): self._set(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_Y_OPTION, y) def get_dictionary_editor_frame_y(self): return self._get_int(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_Y_OPTION, DEFAULT_DICTIONARY_EDITOR_FRAME_Y) def set_serial_config_frame_x(self, x): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, x) def get_serial_config_frame_x(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_X) def set_serial_config_frame_y(self, y): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, y) def get_serial_config_frame_y(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_Y) def set_keyboard_config_frame_x(self, x): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, x) def get_keyboard_config_frame_x(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_X) def set_keyboard_config_frame_y(self, y): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, y) def get_keyboard_config_frame_y(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_Y) def _set(self, section, option, value): if not self._config.has_section(section): self._config.add_section(section) self._config.set(section, option, str(value)) def _get(self, section, option, default): if self._config.has_option(section, option): return self._config.get(section, option) return default def _get_bool(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getboolean(section, option) except ValueError: pass return default def _get_int(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getint(section, option) except ValueError: pass return default
class Config(object): def __init__(self): self._config = RawConfigParser() # A convenient place for other code to store a file name. self.target_file = None def _path_to_config_value(self, path): ''' Return config value for a path. If the path is below CONFIG_DIR, a relative path to it is returned, otherwise, an absolute path is returned. Note: relative path are automatically assumed to be relative to CONFIG_DIR. ''' path = os.path.realpath(os.path.join(CONFIG_DIR, path)) config_dir = os.path.realpath(CONFIG_DIR) + os.sep if path.startswith(config_dir): return path[len(config_dir):] else: return path def _path_from_config_value(self, value): ''' Return a path from a config value. If value is an absolute path, it is returned as is otherwise, an absolute path relative to CONFIG_DIR is returned. ''' return os.path.realpath(os.path.join(CONFIG_DIR, value)) def load(self, fp): self._config = RawConfigParser() try: self._config.readfp(fp) except ConfigParser.Error as e: raise InvalidConfigurationError(str(e)) def clear(self): self._config = RawConfigParser() def save(self, fp): self._config.write(fp) def clone(self): f = StringIO() self.save(f) c = Config() f.seek(0, 0) c.load(f) return c def set_machine_type(self, machine_type): self._set(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, machine_type) def get_machine_type(self): return self._get(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, DEFAULT_MACHINE_TYPE) def set_machine_specific_options(self, machine_name, options): if self._config.has_section(machine_name): self._config.remove_section(machine_name) self._config.add_section(machine_name) for k, v in options.items(): self._config.set(machine_name, k, str(v)) def get_machine_specific_options(self, machine_name): def convert(p, v): try: return p[1](v) except ValueError: return p[0] machine = machine_registry.get(machine_name) info = machine.get_option_info() defaults = {k: v[0] for k, v in info.items()} if self._config.has_section(machine_name): options = {o: self._config.get(machine_name, o) for o in self._config.options(machine_name) if o in info} options = {k: convert(info[k], v) for k, v in options.items()} defaults.update(options) return defaults def set_dictionary_file_names(self, filenames): if self._config.has_section(DICTIONARY_CONFIG_SECTION): self._config.remove_section(DICTIONARY_CONFIG_SECTION) self._config.add_section(DICTIONARY_CONFIG_SECTION) filenames = [self._path_to_config_value(path) for path in filenames] for ordinal, filename in enumerate(filenames, start=1): option = DICTIONARY_FILE_OPTION + str(ordinal) self._config.set(DICTIONARY_CONFIG_SECTION, option, filename) def get_dictionary_file_names(self): filenames = [] if self._config.has_section(DICTIONARY_CONFIG_SECTION): options = filter(lambda x: x.startswith(DICTIONARY_FILE_OPTION), self._config.options(DICTIONARY_CONFIG_SECTION)) options.sort(key=_dict_entry_key) filenames = [self._config.get(DICTIONARY_CONFIG_SECTION, o) for o in options] if not filenames: filenames = DEFAULT_DICTIONARIES filenames = [self._path_from_config_value(path) for path in filenames] return filenames def set_log_file_name(self, filename): filename = self._path_to_config_value(filename) self._set(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, filename) def get_log_file_name(self): filename = self._get(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, DEFAULT_LOG_FILE) return self._path_from_config_value(filename) def set_enable_stroke_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, log) def get_enable_stroke_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, DEFAULT_ENABLE_STROKE_LOGGING) def set_enable_translation_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, log) def get_enable_translation_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, DEFAULT_ENABLE_TRANSLATION_LOGGING) def set_auto_start(self, b): self._set(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, b) def get_auto_start(self): return self._get_bool(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, DEFAULT_MACHINE_AUTO_START) def set_show_stroke_display(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, b) def get_show_stroke_display(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, DEFAULT_STROKE_DISPLAY_SHOW) def set_show_suggestions_display(self, b): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_SHOW_OPTION, b) def get_show_suggestions_display(self): return self._get_bool(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_SHOW_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_SHOW) def get_space_placement(self): return self._get(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, DEFAULT_OUTPUT_CONFIG_SPACE_PLACEMENT) def set_space_placement(self, s): self._set(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, s) def set_stroke_display_on_top(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, b) def get_stroke_display_on_top(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, DEFAULT_STROKE_DISPLAY_ON_TOP) def set_suggestions_display_on_top(self, b): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_ON_TOP_OPTION, b) def get_suggestions_display_on_top(self): return self._get_bool(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_ON_TOP_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_ON_TOP) def set_stroke_display_style(self, s): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, s) def get_stroke_display_style(self): return self._get(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, DEFAULT_STROKE_DISPLAY_STYLE) def set_stroke_display_x(self, x): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, x) def get_stroke_display_x(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, DEFAULT_STROKE_DISPLAY_X) def set_stroke_display_y(self, y): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, y) def get_stroke_display_y(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, DEFAULT_STROKE_DISPLAY_Y) def set_suggestions_display_x(self, x): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_X_OPTION, x) def get_suggestions_display_x(self): return self._get_int(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_X_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_X) def set_suggestions_display_y(self, y): self._set(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_Y_OPTION, y) def get_suggestions_display_y(self): return self._get_int(SUGGESTIONS_DISPLAY_SECTION, SUGGESTIONS_DISPLAY_Y_OPTION, DEFAULT_SUGGESTIONS_DISPLAY_Y) def set_config_frame_x(self, x): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, x) def get_config_frame_x(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, DEFAULT_CONFIG_FRAME_X) def set_config_frame_y(self, y): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, y) def get_config_frame_y(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, DEFAULT_CONFIG_FRAME_Y) def set_config_frame_width(self, width): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, width) def get_config_frame_width(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, DEFAULT_CONFIG_FRAME_WIDTH) def set_config_frame_height(self, height): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, height) def get_config_frame_height(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, DEFAULT_CONFIG_FRAME_HEIGHT) def set_main_frame_x(self, x): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, x) def get_main_frame_x(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, DEFAULT_MAIN_FRAME_X) def set_main_frame_y(self, y): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, y) def get_main_frame_y(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, DEFAULT_MAIN_FRAME_Y) def set_translation_frame_x(self, x): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, x) def get_translation_frame_x(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, DEFAULT_TRANSLATION_FRAME_X) def set_translation_frame_y(self, y): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, y) def get_translation_frame_y(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, DEFAULT_TRANSLATION_FRAME_Y) def set_lookup_frame_x(self, x): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, x) def get_lookup_frame_x(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, DEFAULT_LOOKUP_FRAME_X) def set_lookup_frame_y(self, y): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, y) def get_lookup_frame_y(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, DEFAULT_LOOKUP_FRAME_Y) def set_dictionary_editor_frame_x(self, x): self._set(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_X_OPTION, x) def get_dictionary_editor_frame_x(self): return self._get_int(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_X_OPTION, DEFAULT_DICTIONARY_EDITOR_FRAME_X) def set_dictionary_editor_frame_y(self, y): self._set(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_Y_OPTION, y) def get_dictionary_editor_frame_y(self): return self._get_int(DICTIONARY_EDITOR_FRAME_SECTION, DICTIONARY_EDITOR_FRAME_Y_OPTION, DEFAULT_DICTIONARY_EDITOR_FRAME_Y) def set_serial_config_frame_x(self, x): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, x) def get_serial_config_frame_x(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_X) def set_serial_config_frame_y(self, y): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, y) def get_serial_config_frame_y(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_Y) def set_keyboard_config_frame_x(self, x): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, x) def get_keyboard_config_frame_x(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_X) def set_keyboard_config_frame_y(self, y): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, y) def get_keyboard_config_frame_y(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_Y) def _set(self, section, option, value): if not self._config.has_section(section): self._config.add_section(section) self._config.set(section, option, str(value)) def _get(self, section, option, default): if self._config.has_option(section, option): return self._config.get(section, option) return default def _get_bool(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getboolean(section, option) except ValueError: pass return default def _get_int(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getint(section, option) except ValueError: pass return default
def postverifytrans_hook(conduit): global always_run_triggers opts, args = conduit.getCmdLine() conf = conduit.getConf() if not always_run_triggers and not (opts and opts.posttrans_triggers): return base = conduit._base # Parse the trigger configs triggers_files = glob.glob(os.path.join(base.conf.installroot, triggers_configs_path, "*.conf")) triggers_config = RawConfigParser(dict_type=TriggerSectionDict) triggers_config.read(triggers_files) # Look at the files impacted by the transaction files_seen = [] triggers = [] for tsmem in conduit.getTsInfo().getMembers(): pkg = tsmem.po # We simply can't get the file list directly from the package object. # # In some cases, the object represents an installed package... which # has just been removed during the transaction. In other cases, it # represents an available package which was just installed. # # Some cases lead to the exception path almost all the time, some are # not optimised (e.g hitting the network when the package is # installed), so let's do things the hard way (for the programmer), but # properly. try: # Check the local RPM DB, since it's faster pkg_files = base.rpmdb.searchNevra(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)[0].filelist except Exception as e: # If that fails, try with the repo metadata try: pkg_files = base.pkgSack.searchNevra(pkg.name, pkg.epoch, pkg.version, pkg.release, pkg.arch)[0].filelist except Exception as e: if tsmem.updated_by or tsmem.obsoleted_by: # The package has just been updated/obsoleted, so: # 1. it is not on the system any more # 2. it is probably not in the repositories any more (we # only keep the latest version) # All in all, it's not surprising that we can't get the # file list in such a case, so let's not alarm the user. log_method = conduit.verbose_logger.debug else: # The package should really either be on the system or in # the repositories, something went wrong... log_method = conduit.verbose_logger.error log_method("posttrans-triggers: Could not get the file list " \ "for %s, ignoring" % pkg.ui_envra) continue # Watched path might be in /usr/lib{,64} if base.arch.basearch == "x86_64": libarch = "lib64" else: libarch = "lib" for f in pkg_files: if f in files_seen: continue for path in sorted(triggers_config.sections()): libarched_path = path % {"libarch": libarch} if f.startswith(libarched_path): try: t = triggers_config.get(path, "exec") except NoOptionError as e: conduit.verbose_logger.error("posttrans-triggers: Ignoring path" \ " %s: no 'exec' option found" % path) triggers_config.remove_section(path) continue # Try to be helpful vars = {"file": f, "path": libarched_path, "libarch": libarch} t = t % vars for cmd in t.split("\n"): split_cmd = shlex.split(cmd) if not split_cmd in triggers: triggers.append(split_cmd) files_seen.append(f) for split_cmd in sorted(triggers): # Filter the environment passed to the subprocesses env = dict([(k, v) for (k, v) in os.environ.items() \ if k.startswith("LC_") \ or k == "LANG" ]) env["PATH"] = "" try: p = subprocess.Popen(split_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env) except OSError as e: output = None if e.errno == 2: # The executable wasn't found, most likely because the # full path was not specified error = "%s: %s" % (e.strerror, split_cmd[0]) else: error = e except Exception as e: output = None error = e else: output, error = p.communicate() if p.returncode != 0: conduit.verbose_logger.error("posttrans-triggers: Failed to run" \ " command (%s)" % ' '.join(split_cmd)) finally: if output: conduit.verbose_logger.info("posttrans-triggers: %s" % output) if error: conduit.verbose_logger.error("posttrans-triggers: %s" % error)
class RepoStack(object): def __init__(self, rootdir='.', config='.repostack'): self.rootdir = os.path.abspath(rootdir) self.cfg = None self.cfg_filename = config self.cfg_abspath = os.path.join(self.rootdir, config) def _read_config(self): if not os.path.exists(self.cfg_abspath): raise Exception('This directory is not manged by repostack.' '\nFile "%s" does not exists.' % self.cfg_abspath) self.cfg = RawConfigParser() with open(self.cfg_abspath, 'r') as f: self.cfg.readfp(f, self.cfg_abspath) def _write_config(self): if not os.path.exists(self.cfg_abspath): raise Exception('This directory is not manged by repostack.' '\nFile "%s" does not exists.' % self.cfg_abspath) with open(self.cfg_abspath, 'w') as f: self.cfg.write(f) def _find_all_repos(self, start): repos = [] for name in os.listdir(start): path = os.path.join(start, name) if not os.path.isdir(path): continue if os.path.isdir(os.path.join(path, '.git')): repos.append(os.path.relpath(path, self.rootdir)) else: repos += self._find_all_repos(path) return repos def _find_managed_repos(self): for repo in self.cfg.sections(): if os.path.isdir(os.path.join(self.rootdir, repo, '.git')): yield repo def init(self, args): """ Usage: repostack [--dir=<path>] init [-h] Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message This will initialize repostack in the specified --dir directory or the current directory by default. It simply creates a new ".repostack" empty file. """ if os.path.exists(self.cfg_abspath): raise Exception('Repostack already manages this directory.' '\nFile "%s" already exists.' % self.cfg_abspath) checkdir = self.rootdir while checkdir != os.path.dirname(checkdir): checkdir = os.path.dirname(checkdir) checkpath = os.path.join(checkdir, self.cfg_filename) if os.path.exists(checkpath): raise Exception('Repostack already manages a parent directory.' '\nFile "%s" exists.' % checkpath) if not os.path.exists(self.rootdir): os.makedirs(self.rootdir) open(self.cfg_abspath, 'w').close() print 'Directory "%s" is now managed by repostack.' % self.rootdir def add(self, args): """ Usage: repostack [--dir=<path>] add [-hf] [<filepattern>...] Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message -f, --force force rewrite remote urls This will add repos that match <filepattern> to the stack of tracked repos (creates new sections in the ".repostack" file). If <filepattern> is not specified, it will add all untracked git repositories. If the repos are already tracked, it will only add additional tracking information about any new remotes, and inform the user if existing remotes conflict with the tracked ones. If the user wants to force update stackrepo config to match actual repos remotes, the --force flag should be set. """ self._read_config() for repo in _filter_repos( self._find_all_repos(self.rootdir), args['<filepattern>']): remotes = git.Repo(os.path.join(self.rootdir, repo)).remotes if not self.cfg.has_section(repo): self.cfg.add_section(repo) cfg_remotes = { k[7:]: v for k, v in self.cfg.items(repo) if k[:7] == 'remote_'} for r in remotes: if r.name in cfg_remotes and r.url != cfg_remotes[r.name] \ and not args['--force']: print '%s: remote "%s" not updated, use --force to ' \ 'overwrite.' % (repo, r.name) continue self.cfg.set(repo, 'remote_' + r.name, r.url) self._write_config() def rm(self, args): """ Usage: repostack [--dir=<path>] rm [-hk] <filepattern>... Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message -k, --keep do not remove repo from disk This will remove repos that match <filepattern> from the stack of tracked repos (removes sections from the ".repostack" file). The repos will also be removed from disk unless option --keep is set. """ self._read_config() for repo in _filter_repos(self.cfg.sections(), args['<filepattern>']): repopath = os.path.join(self.rootdir, repo) if os.path.exists(repopath) and not args['--keep']: shutil.rmtree(repopath) self.cfg.remove_section(repo) self._write_config() def checkout(self, args): """ Usage: repostack [--dir=<path>] checkout [-hf] <filepattern>... Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message -f, --force force rewrite remote urls If repos that match <filepattern> are not available yet, it will clone the repos and set all remotes. If they are already available, it will only set any new remotes, and inform the user if existing remotes conflict with the tracked ones. If user wants to override these conflicting remotes, the --force flag should be set. """ self._read_config() for repo in _filter_repos(self.cfg.sections(), args['<filepattern>']): grepo = git.Repo.init(os.path.join(self.rootdir, repo)) for k, v in self.cfg.items(repo): if not k.startswith('remote_'): continue remote = k[7:] if not hasattr(grepo.remotes, remote): grepo.create_remote(remote, v) continue gremote = getattr(grepo.remotes, remote) if gremote.url != v and not args['--force']: print '%s: remote "%s" differs from git repo\'s remote, ' \ 'use --force to overwrite url "%s" with "%s".' % ( repo, remote, gremote.url, v) continue gremote.config_writer.set('url', v) def status(self, args): """ Usage: repostack [--dir=<path>] status [-h] [<filepattern>...] Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message This will show the status of all repos (or matched repos if <filepattern> is specified): - available tracked repos - available untracked repos - unavailable tracked repos This will also mark available tracked repos that have diverged (their remotes may have changed). """ raise NotImplementedError('Not implemented yet.') def diff(self, args): """ Usage: repostack [--dir=<path>] diff [-h] [<filepattern>...] Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message This will show the diff for all available tracked repos which remotes have diverged (or for matched repos if <filepattern> is specified). """ raise NotImplementedError('Not implemented yet.') def do(self, args): """ Usage: repostack [--dir=<path>] do [-h] <command>... [--] [<filepattern>...] Global options: -d, --dir=<path> set repostack root directory [default: .] Command options: -h, --help show this message This will run a command in all available tracked repos (or in matched repos if <filepattern> is specified). """ self._read_config() p = Pool(4) for output in p.imap(_run, [ (p, args['<command>']) for p in _filter_repos( self._find_managed_repos(), args['<filepattern>'])]): print output
class Config(object): def __init__(self, buildout_dir, sources_dir=None): self.cfg_path = os.path.join(buildout_dir, '.mr.developer.cfg') self._config = RawConfigParser() self._config.optionxform = lambda s: s self._config.read(self.cfg_path) if sources_dir is not None: self.sources_dir = sources_dir self.develop = {} self.buildout_args = [] self.rewrites = { 'defaultcfg': [], 'local': [] } self.namedrepos = NAMED_REPOS if self._config.has_section('develop'): for package, value in self._config.items('develop'): value = value.lower() if value == 'true': self.develop[package] = True elif value == 'false': self.develop[package] = False elif value == 'auto': self.develop[package] = 'auto' else: raise ValueError("Invalid value in 'develop' section of '%s'" % self.cfg_path) if self._config.has_option('buildout', 'args'): args = self._config.get('buildout', 'args').split("\n") for arg in args: arg = arg.strip() if arg.startswith("'") and arg.endswith("'"): arg = arg[1:-1].replace("\\'", "'") elif arg.startswith('"') and arg.endswith('"'): arg = arg[1:-1].replace('\\"', '"') self.buildout_args.append(arg) if self._config.has_option('mr.developer', 'rewrites'): for rewrite in self._config.get('mr.developer', 'rewrites').split('\n'): self.rewrites['local'].append(rewrite.split()) # rewrites from default.cfg defaultcfg_path = os.path.join(os.path.expanduser('~'), '.buildout', 'default.cfg') if os.path.exists(defaultcfg_path): defaultcfg = RawConfigParser() # no idea what this does - copy pasted from above defaultcfg.optionxform = lambda s: s defaultcfg.read(defaultcfg_path) if defaultcfg.has_option('mr.developer', 'rewrites'): for rewrite in defaultcfg.get('mr.developer', 'rewrites').split('\n'): self.rewrites['defaultcfg'].append(rewrite.split()) def save(self): self._config.remove_section('develop') self._config.add_section('develop') for package in sorted(self.develop): state = self.develop[package] if state is 'auto': self._config.set('develop', package, 'auto') elif state is True: self._config.set('develop', package, 'true') elif state is False: self._config.set('develop', package, 'false') if not self._config.has_section('buildout'): self._config.add_section('buildout') self._config.set('buildout', 'args', "\n".join(repr(x) for x in self.buildout_args)) if not self._config.has_section('mr.developer'): self._config.add_section('mr.developer') self._config.set('mr.developer', 'rewrites', "\n".join(" ".join(x) for x in self.rewrites['local'])) self._config.write(open(self.cfg_path, "w"))
class MrxsFile(object): def __init__(self, filename): # Split filename dirname, ext = os.path.splitext(filename) if ext != '.mrxs': raise UnrecognizedFile # Parse slidedat self._slidedatfile = os.path.join(dirname, 'Slidedat.ini') self._dat = RawConfigParser() self._dat.optionxform = str try: with open(self._slidedatfile, 'rb') as fh: self._have_bom = (fh.read(len(UTF8_BOM)) == UTF8_BOM) if not self._have_bom: fh.seek(0) self._dat.readfp(fh) except IOError: raise UnrecognizedFile # Get file paths self._indexfile = os.path.join(dirname, self._dat.get(MRXS_HIERARCHICAL, 'INDEXFILE')) self._datafiles = [os.path.join(dirname, self._dat.get('DATAFILE', 'FILE_%d' % i)) for i in range(self._dat.getint('DATAFILE', 'FILE_COUNT'))] # Build levels self._make_levels() def _make_levels(self): self._levels = {} self._level_list = [] layer_count = self._dat.getint(MRXS_HIERARCHICAL, 'NONHIER_COUNT') for layer_id in range(layer_count): level_count = self._dat.getint(MRXS_HIERARCHICAL, 'NONHIER_%d_COUNT' % layer_id) for level_id in range(level_count): level = MrxsNonHierLevel(self._dat, layer_id, level_id, len(self._level_list)) self._levels[(level.layer_name, level.name)] = level self._level_list.append(level) @classmethod def _read_int32(cls, f): buf = f.read(4) if len(buf) != 4: raise IOError('Short read') return struct.unpack('<i', buf)[0] @classmethod def _assert_int32(cls, f, value): v = cls._read_int32(f) if v != value: raise ValueError('%d != %d' % (v, value)) def _get_data_location(self, record): with open(self._indexfile, 'rb') as fh: fh.seek(MRXS_NONHIER_ROOT_OFFSET) # seek to record table_base = self._read_int32(fh) fh.seek(table_base + record * 4) # seek to list head list_head = self._read_int32(fh) fh.seek(list_head) # seek to data page self._assert_int32(fh, 0) page = self._read_int32(fh) fh.seek(page) # check pagesize self._assert_int32(fh, 1) # read rest of prologue self._read_int32(fh) self._assert_int32(fh, 0) self._assert_int32(fh, 0) # read values position = self._read_int32(fh) size = self._read_int32(fh) fileno = self._read_int32(fh) return (self._datafiles[fileno], position, size) def _zero_record(self, record): path, offset, length = self._get_data_location(record) with open(path, 'r+b') as fh: fh.seek(0, 2) do_truncate = (fh.tell() == offset + length) if DEBUG: if do_truncate: print 'Truncating', path, 'to', offset else: print 'Zeroing', path, 'at', offset, 'for', length fh.seek(offset) buf = fh.read(len(JPEG_SOI)) if buf != JPEG_SOI: raise IOError('Unexpected data in nonhier image') if do_truncate: fh.truncate(offset) else: fh.seek(offset) fh.write('\0' * length) def _delete_index_record(self, record): if DEBUG: print 'Deleting record', record with open(self._indexfile, 'r+b') as fh: entries_to_move = len(self._level_list) - record - 1 if entries_to_move == 0: return # get base of table fh.seek(MRXS_NONHIER_ROOT_OFFSET) table_base = self._read_int32(fh) # read tail of table fh.seek(table_base + (record + 1) * 4) buf = fh.read(entries_to_move * 4) if len(buf) != entries_to_move * 4: raise IOError('Short read') # overwrite the target record fh.seek(table_base + record * 4) fh.write(buf) def _hier_keys_for_level(self, level): ret = [] for k, _ in self._dat.items(MRXS_HIERARCHICAL): if k == level.key_prefix or k.startswith(level.key_prefix + '_'): ret.append(k) return ret def _rename_section(self, old, new): if self._dat.has_section(old): if DEBUG: print '[%s] -> [%s]' % (old, new) self._dat.add_section(new) for k, v in self._dat.items(old): self._dat.set(new, k, v) self._dat.remove_section(old) elif DEBUG: print '[%s] does not exist' % old def _delete_section(self, section): if DEBUG: print 'Deleting [%s]' % section self._dat.remove_section(section) def _set_key(self, section, key, value): if DEBUG: prev = self._dat.get(section, key) print '[%s] %s: %s -> %s' % (section, key, prev, value) self._dat.set(section, key, value) def _rename_key(self, section, old, new): if DEBUG: print '[%s] %s -> %s' % (section, old, new) v = self._dat.get(section, old) self._dat.remove_option(section, old) self._dat.set(section, new, v) def _delete_key(self, section, key): if DEBUG: print 'Deleting [%s] %s' % (section, key) self._dat.remove_option(section, key) def _write(self): buf = StringIO() self._dat.write(buf) with open(self._slidedatfile, 'wb') as fh: if self._have_bom: fh.write(UTF8_BOM) fh.write(buf.getvalue().replace('\n', '\r\n')) def delete_level(self, layer_name, level_name): level = self._levels[(layer_name, level_name)] record = level.record # Zero image data self._zero_record(record) # Delete pointer from nonhier table in index self._delete_index_record(record) # Remove slidedat keys for k in self._hier_keys_for_level(level): self._delete_key(MRXS_HIERARCHICAL, k) # Remove slidedat section self._delete_section(level.section) # Rename section and keys for subsequent levels in the layer prev_level = level for cur_level in self._level_list[record + 1:]: if cur_level.layer_id != prev_level.layer_id: break for k in self._hier_keys_for_level(cur_level): new_k = k.replace(cur_level.key_prefix, prev_level.key_prefix, 1) self._rename_key(MRXS_HIERARCHICAL, k, new_k) self._set_key(MRXS_HIERARCHICAL, prev_level.section_key, prev_level.section) self._rename_section(cur_level.section, prev_level.section) prev_level = cur_level # Update level count within layer count_k = 'NONHIER_%d_COUNT' % level.layer_id count_v = self._dat.getint(MRXS_HIERARCHICAL, count_k) self._set_key(MRXS_HIERARCHICAL, count_k, count_v - 1) # Write slidedat self._write() # Refresh metadata self._make_levels()
class Configuration(object): def __init__(self, bus, target_name, file_name): self.bus = bus self.target_name = target_name self.file_name = file_name self.config = RawConfigParser() self.config.read(file_name) if target_name is not None: self.service = bus.create_service({"type": "autoconfigure", "target": target_name}, active=False, use_py_object=_AutoconfigureService(self)) self.sections_object = self.service.create_object("sections", self._compute_sections(), doc=sections_object_doc) self.options_object = self.service.create_object("options", self._compute_options(), doc=options_object_doc) @synchronized(_lock) def _save(self): with open(self.file_name, "w") as file: self.config.write(file) self.sections_object.set_value(self._compute_sections()) self.options_object.set_value(self._compute_options()) @synchronized(_lock) def _compute_sections(self): return self.config.sections() @synchronized(_lock) def _compute_options(self): return dict((section, dict(self.config.items(section))) for section in self.config.sections()) @synchronized(_lock) def sections(self): return self.config.sections() @synchronized(_lock) def add_section(self, name): self.config.add_section(name) self._save() @synchronized(_lock) def has_section(self, name): return self.config.has_section(name) @synchronized(_lock) def options(self, section): return self.config.options(section) @synchronized(_lock) def has_option(self, section, option): return self.config.has_option(section, option) @synchronized(_lock) def get(self, section, option): return self.config.get(section, option) @synchronized(_lock) def getint(self, section, option): return self.config.getint(section, option) @synchronized(_lock) def getfloat(self, section, option): return self.config.getfloat(section, option) @synchronized(_lock) def getboolean(self, section, option): return self.config.getboolean(section, option) @synchronized(_lock) def items(self, section): return self.config.items(section) @synchronized(_lock) def set(self, section, option, value): self.config.set(section, option, value) self._save() @synchronized(_lock) def remove_option(self, section, option): self.config.remove_option(section, option) self._save() @synchronized(_lock) def remove_section(self, section): self.config.remove_section(section) self._save()
def get_merged_config(**options): """Get the final merged configuration for supvervisord, as a string. This is the top-level function exported by this module. It collects the various config files from installed applications and the main project, combines them together based on priority, and returns the resulting configuration as a string. """ # Find and load the containing project module. # This can be specified explicity using the --project-dir option. # Otherwise, we attempt to guess by looking for the manage.py file. project_dir = options.get("project_dir") if project_dir is None: project_dir = guess_project_dir() # Build the default template context variables. # This is mostly useful information about the project and environment. ctx = { "PROJECT_DIR": project_dir, "PYTHON": os.path.realpath(os.path.abspath(sys.executable)), "SUPERVISOR_OPTIONS": rerender_options(options), "settings": settings, "environ": os.environ, } # Update our djtags module with the context it needs to run. djtags.project_dir = project_dir djtags.ctx = ctx # Initialise the ConfigParser. # Fortunately for us, ConfigParser has merge-multiple-config-files # functionality built into it. You just read each file in turn, and # values from later files overwrite values from former. cfg = RawConfigParser() # Start from the default configuration options. data = render_config(DEFAULT_CONFIG,ctx) cfg.readfp(StringIO(data)) # Add in each app-specific file in turn. for data in find_app_configs(ctx): cfg.readfp(StringIO(data)) # Add in the project-specific config file. projcfg = os.path.join(project_dir,CONFIG_FILE_NAME) if os.path.isfile(projcfg): with open(projcfg,"r") as f: data = render_config(f.read(),ctx) cfg.readfp(StringIO(data)) # Add in the options specified on the command-line. cfg.readfp(StringIO(get_config_from_options(**options))) # Add options from [program:__defaults__] to each program section # if it happens to be missing that option. PROG_DEFAULTS = "program:__defaults__" if cfg.has_section(PROG_DEFAULTS): for option in cfg.options(PROG_DEFAULTS): default = cfg.get(PROG_DEFAULTS,option) for section in cfg.sections(): if section.startswith("program:"): if not cfg.has_option(section,option): cfg.set(section,option,default) cfg.remove_section(PROG_DEFAULTS) # Add options from [program:__overrides__] to each program section # regardless of whether they already have that option. PROG_OVERRIDES = "program:__overrides__" if cfg.has_section(PROG_OVERRIDES): for option in cfg.options(PROG_OVERRIDES): override = cfg.get(PROG_OVERRIDES,option) for section in cfg.sections(): if section.startswith("program:"): cfg.set(section,option,override) cfg.remove_section(PROG_OVERRIDES) # Make sure we've got a port configured for supervisorctl to # talk to supervisord. It's passworded based on secret key. # If they have configured a unix socket then use that, otherwise # use an inet server on localhost at fixed-but-randomish port. username = hashlib.md5(settings.SECRET_KEY).hexdigest()[:7] password = hashlib.md5(username).hexdigest() if cfg.has_section("unix_http_server"): set_if_missing(cfg,"unix_http_server","username",username) set_if_missing(cfg,"unix_http_server","password",password) serverurl = "unix://" + cfg.get("unix_http_server","file") else: # This picks a "random" port in the 9000 range to listen on. # It's derived from the secret key, so it's stable for a given # project but multiple projects are unlikely to collide. port = int(hashlib.md5(password).hexdigest()[:3],16) % 1000 addr = "127.0.0.1:9%03d" % (port,) set_if_missing(cfg,"inet_http_server","port",addr) set_if_missing(cfg,"inet_http_server","username",username) set_if_missing(cfg,"inet_http_server","password",password) serverurl = "http://" + cfg.get("inet_http_server","port") set_if_missing(cfg,"supervisorctl","serverurl",serverurl) set_if_missing(cfg,"supervisorctl","username",username) set_if_missing(cfg,"supervisorctl","password",password) set_if_missing(cfg,"rpcinterface:supervisor", "supervisor.rpcinterface_factory", "supervisor.rpcinterface:make_main_rpcinterface") # Remove any [program:] sections with exclude=true for section in cfg.sections(): try: if cfg.getboolean(section,"exclude"): cfg.remove_section(section) except NoOptionError: pass # Sanity-check to give better error messages. for section in cfg.sections(): if section.startswith("program:"): if not cfg.has_option(section,"command"): msg = "Process name '%s' has no command configured" raise ValueError(msg % (section.split(":",1)[-1])) # Write it out to a StringIO and return the data s = StringIO() cfg.write(s) return s.getvalue()
class AwsCredentials(object): """Wraps a RawConfigParser to treat a section named 'default' as a nomral section.""" __REAL_DEFAULT_SECTION_NAME = 'default' __TEMP_DEFAULT_SECTION_NAME = '__default__' __REAL_DEFAULT_SECTION_HEADING = '[' + __REAL_DEFAULT_SECTION_NAME + ']' __TEMP_DEFAULT_SECTION_HEADING = '[' + __TEMP_DEFAULT_SECTION_NAME + ']' def __init__(self): self.__config = RawConfigParser() def read(self, path): with open(path, 'r') as file: content = file.read() content = content.replace(self.__REAL_DEFAULT_SECTION_HEADING, self.__TEMP_DEFAULT_SECTION_HEADING) content_io = StringIO(content) self.__config.readfp(content_io) def write(self, path): content_io = StringIO() self.__config.write(content_io) content = content_io.getvalue() content = content.replace(self.__TEMP_DEFAULT_SECTION_HEADING, self.__REAL_DEFAULT_SECTION_HEADING) with open(path, 'w') as file: file.write(content) def __to_temp_name(self, name): if name == self.__REAL_DEFAULT_SECTION_NAME: name = self.__TEMP_DEFAULT_SECTION_NAME return name def __to_real_name(self, name): if name == self.__TEMP_DEFAULT_SECTION_NAME: name = self.__REAL_DEFAULT_SECTION_NAME return name def sections(self): sections = self.__config.sections() sections = [self.__to_real_name(section) for section in sections] return sections def add_section(self, section): section = self.__to_temp_name(section) self.__config.add_section(section) def has_section(self, section): section = self.__to_temp_name(section) return self.__config.has_section(section) def options(self, section): section = self.__to_temp_name(section) return self.__config.options(section) def has_option(self, section, option): section = self.__to_temp_name(section) return self.__config.has_option(section, option) def get(self, section, option): section = self.__to_temp_name(section) return self.__config.get(section, option) def items(self, section): section = self.__to_temp_name(section) return self.__config.items(section) def set(self, section, option, value): section = self.__to_temp_name(section) self.__config.set(section, option, value) def remove_option(self, section, option): section = self.__to_temp_name(section) return self.__config.remove_option(section, section, option) def remove_section(self, section): section = self.__to_temp_name(section) return self.__config.remove_section(section)
def execute(*args, **kw): if not os.path.isfile( '/etc/kolab-freebusy/config.ini') and not os.path.isfile( '/etc/kolab-freebusy/config.ini.sample'): log.error(_("Free/Busy is not installed on this system")) return if not os.path.isfile('/etc/kolab-freebusy/config.ini'): os.rename('/etc/kolab-freebusy/config.ini.sample', '/etc/kolab-freebusy/config.ini') imap_backend = conf.get('kolab', 'imap_backend') admin_login = conf.get(imap_backend, 'admin_login') admin_password = conf.get(imap_backend, 'admin_password') imap_uri = conf.get(imap_backend, 'imap_uri') if imap_uri == None: imap_uri = conf.get(imap_backend, 'uri') scheme = None hostname = None port = None result = urlparse(imap_uri) if hasattr(result, 'hostname'): hostname = result.hostname if hasattr(result, 'port'): port = result.port if hasattr(result, 'scheme'): scheme = result.scheme else: scheme = imap_uri.split(':')[0] (hostname, port) = imap_uri.split('/')[2].split(':') if scheme == 'imaps' and (port == None or port == ''): port = 993 if scheme == None or scheme == '': scheme = 'imap' if port == None or port == '': port = 143 resources_imap_uri = '%s://%s:%s@%s:%s/%%kolabtargetfolder?acl=lrs' % ( scheme, admin_login, admin_password, hostname, port) users_imap_uri = '%s://%%s:%s@%s:%s/?proxy_auth=%s' % ( scheme, admin_password, hostname, port, admin_login) freebusy_settings = { 'httpauth': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'filter': '(&(objectClass=kolabInetOrgPerson)(|(mail=%s)(alias=%s)(uid=%s)))', }, 'trustednetworks': { 'allow': ','.join(get_local_ips()) }, 'directory "local"': { 'type': 'static', 'fbsource': 'file:/var/lib/kolab-freebusy/%s.ifb', }, 'directory "local-cache"': { 'type': 'static', 'fbsource': 'file:/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m' }, 'directory "kolab-people"': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'filter': '(&(objectClass=kolabInetOrgPerson)(|(mail=%s)(alias=%s)))', 'attributes': 'mail', 'lc_attributes': 'mail', 'primary_domain': conf.get('kolab', 'primary_domain'), 'fbsource': users_imap_uri, 'cacheto': '/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m', 'loglevel': 300, }, 'directory "kolab-resources"': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'resource_base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'attributes': 'mail, kolabtargetfolder', 'filter': '(&(objectClass=kolabsharedfolder)(kolabfoldertype=event)(mail=%s))', 'primary_domain': conf.get('kolab', 'primary_domain'), 'fbsource': resources_imap_uri, 'cacheto': '/var/cache/kolab-freebusy/%s.ifb', 'expires': '15m', 'loglevel': 300, }, 'directory "kolab-resource-collections"': { 'type': 'ldap', 'host': conf.get('ldap', 'ldap_uri'), 'base_dn': conf.get('ldap', 'resource_base_dn'), 'bind_dn': conf.get('ldap', 'service_bind_dn'), 'bind_pw': conf.get('ldap', 'service_bind_pw'), 'filter': '(&(objectClass=kolabgroupofuniquenames)(mail=%s))', 'attributes': 'uniquemember', 'mail' 'resolve_dn': 'uniquemember', 'resolve_attribute': 'mail', 'primary_domain': conf.get('kolab', 'primary_domain'), 'fbsource': 'aggregate://%uniquemember', 'directories': 'kolab-resources', 'cacheto': '/var/cache/kolab-freebusy/%mail.ifb', 'expires': '15m', 'loglevel': 300, }, } cfg_parser = RawConfigParser() cfg_parser.read('/etc/kolab-freebusy/config.ini') for section in freebusy_settings.keys(): if len(freebusy_settings[section].keys()) < 1: cfg_parser.remove_section(section) continue for key in freebusy_settings[section].keys(): if not cfg_parser.has_section(section): cfg_parser.add_section(section) cfg_parser.set(section, key, freebusy_settings[section][key]) fp = open('/etc/kolab-freebusy/config.ini', "w+") cfg_parser.write(fp) fp.close()
def get_files_info(directory, data_list=None): ret = [] base_path = join(data_path, directory) index_config = join(base_path, 'index.cfg') index = RawConfigParser() index.modified = False if isfile(index_config): index.read(index_config) files_list = [ f for f in listdir(base_path) if isfile(join(base_path, f)) and f[-4:] == '.csv' ] removed_order = None order_num = len(index.sections()) for f in files_list: file_path = join(base_path, f) info = { 'file': f, 'dir': directory, 'size': getsize(file_path), 'mtime': getmtime(file_path), } if index.has_section(f): info['order'] = index.getint(f, 'order') info['active'] = index.getboolean(f, 'active') info['comment'] = index.get(f, 'comment') else: index.add_section(f) order_num += 1 info['order'] = order_num info['active'] = True info['comment'] = u'' index.set(f, 'order', info['order']) index.set(f, 'active', info['active']) index.set(f, 'comment', info['comment']) index.modified = True if data_list is not None: data = next( (x for x in data_list if x.get('file') == info['file'])) if data is not None and data.get('remove') is True: index.remove_section(f) index.modified = True removed_order = data['order'] unlink(file_path) continue elif data is not None: info['order'] = int(data.get('order', info['order'])) info['active'] = bool(data.get('active', info['active'])) info['comment'] = unicode(data.get('comment', info['comment'])) index.set(f, 'order', info['order']) index.set(f, 'active', info['active']) index.set(f, 'comment', info['comment']) index.modified = True ret.append(info) if removed_order is not None: ret.sort(key=lambda nfo: nfo['order']) for i, info in enumerate(ret): if info['order'] > removed_order: info['order'] -= 1 index.set(info['file'], 'order', info['order']) if index.modified: with open(index_config, 'wb') as fd: index.write(fd) ret.sort(key=lambda nfo: nfo['order']) return ret
def get_merged_config(**options): """Get the final merged configuration for supvervisord, as a string. This is the top-level function exported by this module. It combines the config file from the main project with default settings and those specified in the command-line, processes various special section names, and returns the resulting configuration as a string. """ # Find and load the containing project module. # This can be specified explicity using the --project-dir option. # Otherwise, we attempt to guess by looking for the manage.py file. project_dir = options.get("project_dir") if project_dir is None: project_dir = guess_project_dir() # Find the config file to load. # Default to <project-dir>/supervisord.conf. config_file = options.get("config_file") if config_file is None: config_file = os.path.join(project_dir, CONFIG_FILE) # Build the default template context variables. # This is mostly useful information about the project and environment. ctx = { "PROJECT_DIR": project_dir, "PYTHON": os.path.realpath(os.path.abspath(sys.executable)), "SUPERVISOR_OPTIONS": rerender_options(options), "settings": settings, "environ": os.environ, } # Initialise the ConfigParser. # Fortunately for us, ConfigParser has merge-multiple-config-files # functionality built into it. You just read each file in turn, and # values from later files overwrite values from former. cfg = RawConfigParser() # Start from the default configuration options. data = render_config(DEFAULT_CONFIG, ctx).decode() cfg.readfp(StringIO(data)) # Add in the project-specific config file. with open(config_file, "r") as f: data = render_config(f.read(), ctx).decode() cfg.readfp(StringIO(data)) # Add in the options specified on the command-line. cfg.readfp(StringIO(get_config_from_options(**options))) # Add options from [program:__defaults__] to each program section # if it happens to be missing that option. PROG_DEFAULTS = "program:__defaults__" if cfg.has_section(PROG_DEFAULTS): for option in cfg.options(PROG_DEFAULTS): default = cfg.get(PROG_DEFAULTS, option) for section in cfg.sections(): if section.startswith("program:"): if not cfg.has_option(section, option): cfg.set(section, option, default) cfg.remove_section(PROG_DEFAULTS) # Add options from [program:__overrides__] to each program section # regardless of whether they already have that option. PROG_OVERRIDES = "program:__overrides__" if cfg.has_section(PROG_OVERRIDES): for option in cfg.options(PROG_OVERRIDES): override = cfg.get(PROG_OVERRIDES, option) for section in cfg.sections(): if section.startswith("program:"): cfg.set(section, option, override) cfg.remove_section(PROG_OVERRIDES) # Make sure we've got a port configured for supervisorctl to # talk to supervisord. It's passworded based on secret key. # If they have configured a unix socket then use that, otherwise # use an inet server on localhost at fixed-but-randomish port. username = hashlib.md5(settings.SECRET_KEY.encode()).hexdigest()[:7] password = hashlib.md5(username.encode()).hexdigest() if cfg.has_section("unix_http_server"): set_if_missing(cfg, "unix_http_server", "username", username) set_if_missing(cfg, "unix_http_server", "password", password) serverurl = "unix://" + cfg.get("unix_http_server", "file") else: # This picks a "random" port in the 9000 range to listen on. # It's derived from the secret key, so it's stable for a given # project but multiple projects are unlikely to collide. port = int(hashlib.md5(password.encode()).hexdigest()[:3], 16) % 1000 addr = "127.0.0.1:9%03d" % (port, ) set_if_missing(cfg, "inet_http_server", "port", addr) set_if_missing(cfg, "inet_http_server", "username", username) set_if_missing(cfg, "inet_http_server", "password", password) serverurl = "http://" + cfg.get("inet_http_server", "port") set_if_missing(cfg, "supervisorctl", "serverurl", serverurl) set_if_missing(cfg, "supervisorctl", "username", username) set_if_missing(cfg, "supervisorctl", "password", password) set_if_missing(cfg, "rpcinterface:supervisor", "supervisor.rpcinterface_factory", "supervisor.rpcinterface:make_main_rpcinterface") # Remove any [program:] sections with exclude=true for section in cfg.sections(): try: if cfg.getboolean(section, "exclude"): cfg.remove_section(section) except NoOptionError: pass # Sanity-check to give better error messages. for section in cfg.sections(): if section.startswith("program:"): if not cfg.has_option(section, "command"): msg = "Process name '%s' has no command configured" raise ValueError(msg % (section.split(":", 1)[-1])) # Write it out to a StringIO and return the data s = StringIO() cfg.write(s) return s.getvalue()
class ConfigWriter(): def __init__(self): # Location of kkauto.cfg file # store basic device information to connect appium self.config_dir = path.expanduser('~/') self.config_file_name = '.kkauto.cfg' self.config_location = path.join(self.config_dir, self.config_file_name) self.config = RawConfigParser() self.requests = ['platform', 'platform.version', 'name'] self.appium_connect = ['remote.port', 'remote.host'] self.appium_port = 4723 self.port_idx = 0 self.config_start() def config_start(self): self.config_file = open(self.config_location, 'w') def set_local_apk(self, platform, file_path): self.config.add_section('kkbox') if platform == 'android': self.config.set('kkbox', 'android.app-path', file_path) elif platform == 'ios': self.config.set('kkbox', 'ios.app-path', file_path) def set_default_serialno(self, platform, device_id): if platform == 'android': # [android] # default-serialno=<ANDROID_SERIALNO> if not self.config.has_section('android'): self.config.add_section('android') print 'android-default add' self.config.set('android', 'default-serialno', device_id) else: #self.config.remove_section('android') print 'section = [android] already existeds' elif platform == 'ios': # [ios] # default-udid=<IOS_UDID> if not self.config.has_section('ios'): self.config.add_section('ios') print 'ios-default add' self.config.set('ios', 'default-udid', device_id) else: #self.config.remove_section('ios') print 'section = [ios] already existed' elif platform == 'device': # [device] # default-serialno=<ANDROID_SERIALNO> if not self.config.has_section('device'): self.config.add_section('device') print 'android-default add' self.config.set('device', 'default-serialno', device_id) else: #self.config.remove_section('device') print 'section = [device] already existed' def set_default_udid(self, udid): device_sect = self.id_format(udid) if not self.config.has_section(udid): self.config.add_section(device_sect) def get_devices_id(self): "Return andoid devices id with list" command = 'adb devices' ids = subprocess.check_output(command, shell=True) ids = ids.strip('\n').replace('\tdevice', "").split('\n') ids.pop(0) return ids def get_property(self, device_id, prop): """ Get device property by device_id Properties Example: [net.bt.name]: [Android] [ro.product.brand]: [Android] [dhcp.wlan0.gateway]: [192.168.0.1] [ro.build.version.release]: [5.0.2] [ro.build.version.sdk]: [21] [ro.product.brand]: [InFocus] [ro.product.model]: [InFocus M810] [ro.product.manufacturer]: [InFocus] """ property_dic = { 'platform.version': 'ro.build.version.release', 'platform': 'net.bt.name', 'name': 'ro.product.model' } command = 'adb -s ' + device_id + ' shell getprop ' + property_dic[prop] #print 'command: ', command result = subprocess.check_output(command, shell=True).strip('\n').strip('\r') #print 'value: ', result return result def id_format(self, device_id): return 'device-%s' % device_id def _option_process(self, device_id, option_list): device_sect = self.id_format(device_id) if not self.config.has_section(device_sect): self.config.add_section(device_sect) for option in option_list: self.config.set(device_sect, option, self.get_property(device_id, option)) else: print 'section = [%s] already existed' % device_sect #self.config.remove_section(device_sect) def set_device_config_ios(self, device_id='<IOS_UDID>'): self._option_process(device_id, self.requests) def set_device_config(self, device_id=''): self._option_process(device_id, self.requests) def set_appium_config(self, device_id): device_sect = self.id_format(device_id) if not self.config.has_section(device_sect): self.config.add_section(device_sect) self.config.set(device_sect, self.appium_connect[0], self.appium_port + self.port_idx) self.port_idx += 2 def _set_status(self, device_id, status): device_sect = self.id_format(device_id) self.config.set(device_sect, 'status', status) def set_device_available(self, device_id): self._set_status(device_id, 'available') def set_device_busy(self, device_id): self._set_status(device_id, 'busy') def config_close(self): self.config.write(self.config_file) self.config_file.close() # remove swp in vim command = 'rm ' + '~/.kkauto.cfg.swp' if path.exists(path.join(self.config_location, '.swp')): subprocess.check_output(command, shell=True) def get_sections(self): return self.config.sections() def get_options(self, section): return self.config.options(section) def get_option(self, section, option): return self.config.get(section, option) def get_port(self, section): return self.get_option(section, 'remote.port') def remove_all_sections(self): for section in self.get_sections(): self.config.remove_section(section) def set_account_config(self, device_id, product, information, value): device_sect = self.id_format(device_id) opt = "%s_%s" % (product, information) self.config.set(device_sect, opt, value)
class ParamStore(object): def __init__(self, root_dir, file_name): self._lock = Lock() with self._lock: if not os.path.isdir(root_dir): raise RuntimeError( 'Directory "' + root_dir + '" does not exist.') self._path = os.path.join(root_dir, file_name) self._dirty = False # open config file self._config = RawConfigParser() self._config.read(self._path) def __del__(self): self.flush() def flush(self): if not self._dirty: return with self._lock: self._dirty = False of = open(self._path, 'w') self._config.write(of) of.close() def get(self, section, option, default=None): """Get a parameter value and return a string. If default is specified and section or option are not defined in the file, they are created and set to default, which is then the return value. """ with self._lock: if not self._config.has_option(section, option): if default is not None: self._set(section, option, default) return default return self._config.get(section, option) def get_datetime(self, section, option, default=None): result = self.get(section, option, default) if result: return safestrptime(result) return result def set(self, section, option, value): """Set option in section to string value.""" with self._lock: self._set(section, option, value) def _set(self, section, option, value): if not self._config.has_section(section): self._config.add_section(section) elif (self._config.has_option(section, option) and self._config.get(section, option) == value): return self._config.set(section, option, value) self._dirty = True def unset(self, section, option): """Remove option from section.""" with self._lock: if not self._config.has_section(section): return if self._config.has_option(section, option): self._config.remove_option(section, option) self._dirty = True if not self._config.options(section): self._config.remove_section(section) self._dirty = True
class Config(object): def __init__(self): self._config = RawConfigParser() # A convenient place for other code to store a file name. self.target_file = None def load(self, fp): self._config = RawConfigParser() try: self._config.readfp(fp) except ConfigParser.Error as e: raise InvalidConfigurationError(str(e)) def clear(self): self._config = RawConfigParser() def save(self, fp): self._config.write(fp) def clone(self): f = StringIO() self.save(f) c = Config() f.seek(0, 0) c.load(f) return c def set_machine_type(self, machine_type): self._set(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, machine_type) def get_machine_type(self): return self._get(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, DEFAULT_MACHINE_TYPE) def set_machine_specific_options(self, machine_name, options): if self._config.has_section(machine_name): self._config.remove_section(machine_name) self._config.add_section(machine_name) for k, v in options.items(): self._config.set(machine_name, k, str(v)) def get_machine_specific_options(self, machine_name): def convert(p, v): try: return p[1](v) except ValueError: return p[0] machine = machine_registry.get(machine_name) info = machine.get_option_info() defaults = {k: v[0] for k, v in info.items()} if self._config.has_section(machine_name): options = {o: self._config.get(machine_name, o) for o in self._config.options(machine_name) if o in info} options = {k: convert(info[k], v) for k, v in options.items()} defaults.update(options) return defaults def set_dictionary_file_names(self, filenames): if self._config.has_section(DICTIONARY_CONFIG_SECTION): self._config.remove_section(DICTIONARY_CONFIG_SECTION) self._config.add_section(DICTIONARY_CONFIG_SECTION) for ordinal, filename in enumerate(filenames, start=1): option = DICTIONARY_FILE_OPTION + str(ordinal) self._config.set(DICTIONARY_CONFIG_SECTION, option, filename) def get_dictionary_file_names(self): filenames = [] if self._config.has_section(DICTIONARY_CONFIG_SECTION): options = filter(lambda x: x.startswith(DICTIONARY_FILE_OPTION), self._config.options(DICTIONARY_CONFIG_SECTION)) options.sort(key=_dict_entry_key) filenames = [self._config.get(DICTIONARY_CONFIG_SECTION, o) for o in options] if not filenames or filenames == ['dict.json']: filenames = [DEFAULT_DICTIONARY_FILE] return filenames def set_log_file_name(self, filename): self._set(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, filename) def get_log_file_name(self): return self._get(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, DEFAULT_LOG_FILE) def set_enable_stroke_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, log) def get_enable_stroke_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, DEFAULT_ENABLE_STROKE_LOGGING) def set_enable_translation_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, log) def get_enable_translation_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, DEFAULT_ENABLE_TRANSLATION_LOGGING) def set_auto_start(self, b): self._set(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, b) def get_auto_start(self): return self._get_bool(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, DEFAULT_MACHINE_AUTO_START) def set_show_stroke_display(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, b) def get_show_stroke_display(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, DEFAULT_STROKE_DISPLAY_SHOW) def get_space_placement(self): return self._get(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, DEFAULT_OUTPUT_CONFIG_SPACE_PLACEMENT) def set_space_placement(self, s): self._set(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, s) def set_stroke_display_on_top(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, b) def get_stroke_display_on_top(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, DEFAULT_STROKE_DISPLAY_ON_TOP) def set_stroke_display_style(self, s): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, s) def get_stroke_display_style(self): return self._get(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, DEFAULT_STROKE_DISPLAY_STYLE) def set_stroke_display_x(self, x): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, x) def get_stroke_display_x(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, DEFAULT_STROKE_DISPLAY_X) def set_stroke_display_y(self, y): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, y) def get_stroke_display_y(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, DEFAULT_STROKE_DISPLAY_Y) def set_config_frame_x(self, x): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, x) def get_config_frame_x(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, DEFAULT_CONFIG_FRAME_X) def set_config_frame_y(self, y): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, y) def get_config_frame_y(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, DEFAULT_CONFIG_FRAME_Y) def set_config_frame_width(self, width): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, width) def get_config_frame_width(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, DEFAULT_CONFIG_FRAME_WIDTH) def set_config_frame_height(self, height): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, height) def get_config_frame_height(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, DEFAULT_CONFIG_FRAME_HEIGHT) def set_main_frame_x(self, x): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, x) def get_main_frame_x(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, DEFAULT_MAIN_FRAME_X) def set_main_frame_y(self, y): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, y) def get_main_frame_y(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, DEFAULT_MAIN_FRAME_Y) def set_translation_frame_x(self, x): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, x) def get_translation_frame_x(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, DEFAULT_TRANSLATION_FRAME_X) def set_translation_frame_y(self, y): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, y) def get_translation_frame_y(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, DEFAULT_TRANSLATION_FRAME_Y) # <<<<<<< HEAD # ======= # def set_lookup_frame_x(self, x): # self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, x) # def get_lookup_frame_x(self): # return self._get_int(LOOKUP_FRAME_SECTION, # LOOKUP_FRAME_X_OPTION, # DEFAULT_LOOKUP_FRAME_X) # def set_lookup_frame_y(self, y): # self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, y) # def get_lookup_frame_y(self): # return self._get_int(LOOKUP_FRAME_SECTION, # LOOKUP_FRAME_Y_OPTION, # DEFAULT_LOOKUP_FRAME_Y) # >>>>>>> 318dca0a57fbc4ecb11b7c3b33fe465db263b753 def set_serial_config_frame_x(self, x): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, x) def get_serial_config_frame_x(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_X) def set_serial_config_frame_y(self, y): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, y) def get_serial_config_frame_y(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_Y) def set_keyboard_config_frame_x(self, x): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, x) def get_keyboard_config_frame_x(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_X) def set_keyboard_config_frame_y(self, y): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, y) def get_keyboard_config_frame_y(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_Y) def _set(self, section, option, value): if not self._config.has_section(section): self._config.add_section(section) self._config.set(section, option, str(value)) def _get(self, section, option, default): if self._config.has_option(section, option): return self._config.get(section, option) return default def _get_bool(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getboolean(section, option) except ValueError: pass return default def _get_int(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getint(section, option) except ValueError: pass return default
class Config(object): def __init__(self): self._config = RawConfigParser() # A convenient place for other code to store a file name. self.target_file = None def load(self, fp): self._config = RawConfigParser() try: self._config.readfp(fp) except ConfigParser.Error as e: raise InvalidConfigurationError(str(e)) def clear(self): self._config = RawConfigParser() def save(self, fp): self._config.write(fp) def clone(self): f = StringIO() self.save(f) c = Config() f.seek(0, 0) c.load(f) return c def set_machine_type(self, machine_type): self._set(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, machine_type) def get_machine_type(self): return self._get(MACHINE_CONFIG_SECTION, MACHINE_TYPE_OPTION, DEFAULT_MACHINE_TYPE) def set_machine_specific_options(self, machine_name, options): if self._config.has_section(machine_name): self._config.remove_section(machine_name) self._config.add_section(machine_name) for k, v in options.items(): self._config.set(machine_name, k, str(v)) def get_machine_specific_options(self, machine_name): def convert(p, v): try: return p[1](v) except ValueError: return p[0] machine = machine_registry.get(machine_name) info = machine.get_option_info() defaults = {k: v[0] for k, v in info.items()} if self._config.has_section(machine_name): options = {o: self._config.get(machine_name, o) for o in self._config.options(machine_name) if o in info} options = {k: convert(info[k], v) for k, v in options.items()} defaults.update(options) return defaults def set_dictionary_file_names(self, filenames): if self._config.has_section(DICTIONARY_CONFIG_SECTION): self._config.remove_section(DICTIONARY_CONFIG_SECTION) self._config.add_section(DICTIONARY_CONFIG_SECTION) for ordinal, filename in enumerate(filenames, start=1): option = DICTIONARY_FILE_OPTION + str(ordinal) self._config.set(DICTIONARY_CONFIG_SECTION, option, filename) def get_dictionary_file_names(self): filenames = [] if self._config.has_section(DICTIONARY_CONFIG_SECTION): options = filter(lambda x: x.startswith(DICTIONARY_FILE_OPTION), self._config.options(DICTIONARY_CONFIG_SECTION)) options.sort(key=_dict_entry_key) filenames = [self._config.get(DICTIONARY_CONFIG_SECTION, o) for o in options] if not filenames or filenames == ['dict.json']: filenames = [DEFAULT_DICTIONARY_FILE] return filenames def set_log_file_name(self, filename): self._set(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, filename) def get_log_file_name(self): return self._get(LOGGING_CONFIG_SECTION, LOG_FILE_OPTION, DEFAULT_LOG_FILE) def set_enable_stroke_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, log) def get_enable_stroke_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_STROKE_LOGGING_OPTION, DEFAULT_ENABLE_STROKE_LOGGING) def set_enable_translation_logging(self, log): self._set(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, log) def get_enable_translation_logging(self): return self._get_bool(LOGGING_CONFIG_SECTION, ENABLE_TRANSLATION_LOGGING_OPTION, DEFAULT_ENABLE_TRANSLATION_LOGGING) def set_auto_start(self, b): self._set(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, b) def get_auto_start(self): return self._get_bool(MACHINE_CONFIG_SECTION, MACHINE_AUTO_START_OPTION, DEFAULT_MACHINE_AUTO_START) def set_show_stroke_display(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, b) def get_show_stroke_display(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_SHOW_OPTION, DEFAULT_STROKE_DISPLAY_SHOW) def get_space_placement(self): return self._get(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, DEFAULT_OUTPUT_CONFIG_SPACE_PLACEMENT) def set_space_placement(self, s): self._set(OUTPUT_CONFIG_SECTION, OUTPUT_CONFIG_SPACE_PLACEMENT_OPTION, s) def set_stroke_display_on_top(self, b): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, b) def get_stroke_display_on_top(self): return self._get_bool(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_ON_TOP_OPTION, DEFAULT_STROKE_DISPLAY_ON_TOP) def set_stroke_display_style(self, s): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, s) def get_stroke_display_style(self): return self._get(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_STYLE_OPTION, DEFAULT_STROKE_DISPLAY_STYLE) def set_stroke_display_x(self, x): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, x) def get_stroke_display_x(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_X_OPTION, DEFAULT_STROKE_DISPLAY_X) def set_stroke_display_y(self, y): self._set(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, y) def get_stroke_display_y(self): return self._get_int(STROKE_DISPLAY_SECTION, STROKE_DISPLAY_Y_OPTION, DEFAULT_STROKE_DISPLAY_Y) def set_config_frame_x(self, x): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, x) def get_config_frame_x(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_X_OPTION, DEFAULT_CONFIG_FRAME_X) def set_config_frame_y(self, y): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, y) def get_config_frame_y(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_Y_OPTION, DEFAULT_CONFIG_FRAME_Y) def set_config_frame_width(self, width): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, width) def get_config_frame_width(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_WIDTH_OPTION, DEFAULT_CONFIG_FRAME_WIDTH) def set_config_frame_height(self, height): self._set(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, height) def get_config_frame_height(self): return self._get_int(CONFIG_FRAME_SECTION, CONFIG_FRAME_HEIGHT_OPTION, DEFAULT_CONFIG_FRAME_HEIGHT) def set_main_frame_x(self, x): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, x) def get_main_frame_x(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_X_OPTION, DEFAULT_MAIN_FRAME_X) def set_main_frame_y(self, y): self._set(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, y) def get_main_frame_y(self): return self._get_int(MAIN_FRAME_SECTION, MAIN_FRAME_Y_OPTION, DEFAULT_MAIN_FRAME_Y) def set_translation_frame_x(self, x): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, x) def get_translation_frame_x(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_X_OPTION, DEFAULT_TRANSLATION_FRAME_X) def set_translation_frame_y(self, y): self._set(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, y) def get_translation_frame_y(self): return self._get_int(TRANSLATION_FRAME_SECTION, TRANSLATION_FRAME_Y_OPTION, DEFAULT_TRANSLATION_FRAME_Y) def set_lookup_frame_x(self, x): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, x) def get_lookup_frame_x(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_X_OPTION, DEFAULT_LOOKUP_FRAME_X) def set_lookup_frame_y(self, y): self._set(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, y) def get_lookup_frame_y(self): return self._get_int(LOOKUP_FRAME_SECTION, LOOKUP_FRAME_Y_OPTION, DEFAULT_LOOKUP_FRAME_Y) def set_serial_config_frame_x(self, x): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, x) def get_serial_config_frame_x(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_X_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_X) def set_serial_config_frame_y(self, y): self._set(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, y) def get_serial_config_frame_y(self): return self._get_int(SERIAL_CONFIG_FRAME_SECTION, SERIAL_CONFIG_FRAME_Y_OPTION, DEFAULT_SERIAL_CONFIG_FRAME_Y) def set_keyboard_config_frame_x(self, x): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, x) def get_keyboard_config_frame_x(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_X_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_X) def set_keyboard_config_frame_y(self, y): self._set(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, y) def get_keyboard_config_frame_y(self): return self._get_int(KEYBOARD_CONFIG_FRAME_SECTION, KEYBOARD_CONFIG_FRAME_Y_OPTION, DEFAULT_KEYBOARD_CONFIG_FRAME_Y) def _set(self, section, option, value): if not self._config.has_section(section): self._config.add_section(section) self._config.set(section, option, str(value)) def _get(self, section, option, default): if self._config.has_option(section, option): return self._config.get(section, option) return default def _get_bool(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getboolean(section, option) except ValueError: pass return default def _get_int(self, section, option, default): try: if self._config.has_option(section, option): return self._config.getint(section, option) except ValueError: pass return default