Mercurial > hg > martINI
view martini/config.py @ 11:c77259f467a3
hopefully OrderedDict preservation actually works now
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Tue, 23 Aug 2016 18:17:11 -0700 |
parents | 66d11212175d |
children | 4faed08eb8d8 |
line wrap: on
line source
#!/usr/bin/env python import os import sys import urllib2 from ConfigParser import ConfigParser from ConfigParser import InterpolationMissingOptionError from ConfigParser import MissingSectionHeaderError from ConfigParser import NoOptionError from StringIO import StringIO try: from collections import OrderedDict except ImportError: from odict import OrderedDict def file_pointer(resource): """returns a file-like object given a string""" # XXX could go in utils.py if not isinstance(resource, basestring): # assume resource is already a file-like object return resource if os.path.exists(resource): return file(resource) if sum([resource.startswith(http) for http in 'http://', 'https://']): return urllib2.urlopen(resource) return StringIO(resource) class ConfigMunger(ConfigParser): """combine configuration from .ini files""" def __init__(self, *conf, **kw): ConfigParser.__init__(self, defaults=kw.get('defaults',{}), dict_type=OrderedDict) self.optionxform = str self.read(*conf) def __getitem__(self, section): """ return an object with __getitem__ defined appropriately to allow referencing like self['foo']['bar'] """ return OrderedDict(self.items(section)) def get(self, section, option, default=None, raw=False, vars=None): try: value = ConfigParser.get(self, section, option, raw, vars) except NoOptionError: return default return value def set(self, section, option, value): if section not in self.sections(): self.add_section(section) ConfigParser.set(self, section, option, value) def move_section(self, section, newname): if self.has_section(section): _section = self[section] self.remove_section(section) else: _section = OrderedDict() self.read(OrderedDict(newname=_section)) def dict(self): """ return a dictionary of dictionaries: the outer with keys of section names; the inner with keys, values of the section """ return OrderedDict([(section, self[section]) for section in self.sections()]) def read(self, *ini): for _ini in ini: if isinstance(_ini, (dict, OrderedDict)): for section, contents in _ini.items(): for option, value in contents.items(): self.set(section, option, value) elif isinstance(_ini, (list, tuple)): # ensure list or tuple of 3-tuples assert len([option for option in _ini if isinstance(option, tuple) and len(option) == 3]) for section, option, value in _ini: self.set(section, option, value) else: fp = file_pointer(_ini) try: self.readfp(fp) except MissingSectionHeaderError: fp.seek(0) fp = StringIO("[DEFAULTS]\n" + fp.read()) self.readfp(fp) def missing(self): """returns missing variable names""" missing = set() for section in self.sections(): for key, val in self.items(section, raw=True): try: self.get(section, key) except InterpolationMissingOptionError, e: missing.add(e.reference) return missing def tuples(self): """ return options in format appropriate to trac: [ (section, option, value) ] """ options = [] for section in self.sections(): options.extend([(section,) + item for item in self.items(section)]) return options def write(self, fp=sys.stdout, raw=False, sorted=True, vars=None): sections = self.sections() if sorted: sections.sort() for section in sections: print >> fp, '[%s]' % section options = self.options(section) if sorted: options.sort() for option in options: print >> fp, "%s = %s" % (option, self.get(section, option, raw=raw, vars=vars)) if section != sections[-1]: print >> fp if __name__ == '__main__': import sys from optparse import OptionParser parser = OptionParser() parser.add_option('--missing', action="store_true", default=False, help="list missing template variables") munger = ConfigMunger() options, args = parser.parse_args() munger.read(*args) if options.missing: for missing in munger.missing(): print missing else: munger.write(sys.stdout)