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) |