Mercurial > hg > martINI
comparison martini/config.py @ 0:3c3522ce6e3a
initial import of martINI from https://svn.openplans.org/svn/standalone/martINI/
| author | k0s <k0scist@gmail.com> |
|---|---|
| date | Tue, 08 Dec 2009 15:13:28 -0500 |
| parents | |
| children | 09bed87f7fa4 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:3c3522ce6e3a |
|---|---|
| 1 #!/usr/bin/env python | |
| 2 | |
| 3 import os | |
| 4 import sys | |
| 5 import urllib2 | |
| 6 | |
| 7 from ConfigParser import ConfigParser | |
| 8 from ConfigParser import InterpolationMissingOptionError | |
| 9 from ConfigParser import MissingSectionHeaderError | |
| 10 from ConfigParser import NoOptionError | |
| 11 from StringIO import StringIO | |
| 12 | |
| 13 def file_pointer(resource): | |
| 14 """returns a file-like object given a string""" | |
| 15 # XXX could go in utils.py | |
| 16 | |
| 17 if not isinstance(resource, basestring): | |
| 18 # assume resource is already a file-like object | |
| 19 return resource | |
| 20 | |
| 21 if os.path.exists(resource): | |
| 22 return file(resource) | |
| 23 if sum([resource.startswith(http) for http in 'http://', 'https://']): | |
| 24 return urllib2.urlopen(resource) | |
| 25 return StringIO(resource) | |
| 26 | |
| 27 | |
| 28 class ConfigMunger(ConfigParser): | |
| 29 """combine configuration from .ini files""" | |
| 30 | |
| 31 def __init__(self, *conf, **kw): | |
| 32 ConfigParser.__init__(self, kw.get('defaults',{})) | |
| 33 self.read(*conf) | |
| 34 | |
| 35 def __getitem__(self, section): | |
| 36 """ | |
| 37 return an object with __getitem__ defined appropriately | |
| 38 to allow referencing like self['foo']['bar'] | |
| 39 """ | |
| 40 return dict(self.items(section)) | |
| 41 | |
| 42 def get(self, section, option, default=None, raw=False, vars=None): | |
| 43 try: | |
| 44 value = ConfigParser.get(self, section, option, raw, vars) | |
| 45 except NoOptionError: | |
| 46 return default | |
| 47 return value | |
| 48 | |
| 49 def set(self, section, option, value): | |
| 50 if section not in self.sections(): | |
| 51 self.add_section(section) | |
| 52 ConfigParser.set(self, section, option, value) | |
| 53 | |
| 54 def move_section(self, section, newname): | |
| 55 if self.has_section(section): | |
| 56 _section = self[section] | |
| 57 self.remove_section(section) | |
| 58 else: | |
| 59 _section = {} | |
| 60 self.read({newname: _section}) | |
| 61 | |
| 62 def dict(self): | |
| 63 """return a dictionary of dictionaries; | |
| 64 the outer with keys of section names; | |
| 65 the inner with keys, values of the section""" | |
| 66 return dict([(section, self[section]) | |
| 67 for section in self.sections()]) | |
| 68 | |
| 69 def read(self, *ini): | |
| 70 for _ini in ini: | |
| 71 if isinstance(_ini, dict): | |
| 72 for section, contents in _ini.items(): | |
| 73 for option, value in contents.items(): | |
| 74 self.set(section, option, value) | |
| 75 elif isinstance(_ini, list) or isinstance(_ini, tuple): | |
| 76 | |
| 77 # ensure list or tuple of 3-tuples | |
| 78 assert len([option for option in _ini | |
| 79 if isinstance(option, tuple) | |
| 80 and len(option) == 3]) | |
| 81 | |
| 82 for section, option, value in _ini: | |
| 83 self.set(section, option, value) | |
| 84 else: | |
| 85 fp = file_pointer(_ini) | |
| 86 try: | |
| 87 self.readfp(fp) | |
| 88 except MissingSectionHeaderError: | |
| 89 fp.seek(0) | |
| 90 fp = StringIO("[DEFAULTS]\n" + fp.read()) | |
| 91 self.readfp(fp) | |
| 92 | |
| 93 def missing(self): | |
| 94 """returns missing variable names""" | |
| 95 missing = set() | |
| 96 | |
| 97 for section in self.sections(): | |
| 98 for key, val in self.items(section, raw=True): | |
| 99 try: | |
| 100 self.get(section, key) | |
| 101 except InterpolationMissingOptionError, e: | |
| 102 missing.add(e.reference) | |
| 103 return missing | |
| 104 | |
| 105 def tuples(self): | |
| 106 """ | |
| 107 return options in format appropriate to trac: | |
| 108 [ (section, option, value) ] | |
| 109 """ | |
| 110 options = [] | |
| 111 for section in self.sections(): | |
| 112 options.extend([(section,) + item | |
| 113 for item in self.items(section)]) | |
| 114 return options | |
| 115 | |
| 116 def write(self, fp=sys.stdout, raw=False, sorted=True, vars=None): | |
| 117 sections = self.sections() | |
| 118 if sorted: | |
| 119 sections.sort() | |
| 120 | |
| 121 for section in sections: | |
| 122 print >> fp, '[%s]' % section | |
| 123 options = self.options(section) | |
| 124 if sorted: | |
| 125 options.sort() | |
| 126 for option in options: | |
| 127 print >> fp, "%s = %s" % (option, self.get(section, option, raw, vars)) | |
| 128 if section != sections[-1]: | |
| 129 print >> fp | |
| 130 | |
| 131 if __name__ == '__main__': | |
| 132 import sys | |
| 133 from optparse import OptionParser | |
| 134 parser = OptionParser() | |
| 135 parser.add_option('--missing', action="store_true", default=False, | |
| 136 help="list missing template variables") | |
| 137 munger = ConfigMunger() | |
| 138 options, args = parser.parse_args() | |
| 139 munger.read(*args) | |
| 140 if options.missing: | |
| 141 for missing in munger.missing(): | |
| 142 print missing | |
| 143 else: | |
| 144 munger.write(sys.stdout) |
