blob: 2f98e6f69cb4f33e0a598ac8199a016347362852 [file] [log] [blame]
Tony Mack63935712013-03-26 13:23:12 -04001#!/usr/bin/python
2import sys
3import os
4import time
5import ConfigParser
6import tempfile
7import codecs
8from StringIO import StringIO
Tony Mack746b2302013-03-28 22:12:47 -04009from plstackapi.util.xml import Xml
Tony Mack63935712013-03-26 13:23:12 -040010
11default_config = \
12"""
13"""
14
15def isbool(v):
16 return v.lower() in ("true", "false")
17
18def str2bool(v):
19 return v.lower() in ("true", "1")
20
21class Config:
22
Tony Mack5f657962013-03-28 20:17:05 -040023 def __init__(self, config_file='/etc/planetstack/plstackapi_config'):
Tony Mack63935712013-03-26 13:23:12 -040024 self._files = []
25 self.config_path = os.path.dirname(config_file)
26 self.config = ConfigParser.ConfigParser()
27 self.filename = config_file
28 if not os.path.isfile(self.filename):
29 self.create(self.filename)
30 self.load(self.filename)
31
32
33 def _header(self):
34 header = """
35DO NOT EDIT. This file was automatically generated at
36%s from:
37
38%s
39""" % (time.asctime(), os.linesep.join(self._files))
40
41 # Get rid of the surrounding newlines
42 return header.strip().split(os.linesep)
43
44 def create(self, filename):
45 if not os.path.exists(os.path.dirname(filename)):
46 os.makedirs(os.path.dirname(filename))
47 configfile = open(filename, 'w')
48 configfile.write(default_config)
49 configfile.close()
50
51
52 def load(self, filename):
53 if filename:
54 try:
55 self.config.read(filename)
56 except ConfigParser.MissingSectionHeaderError:
57 if filename.endswith('.xml'):
58 self.load_xml(filename)
59 else:
60 self.load_shell(filename)
61 self._files.append(filename)
62 self.set_attributes()
63
64 def load_xml(self, filename):
65 xml = XML(filename)
66 categories = xml.xpath('//configuration/variables/category')
67 for category in categories:
68 section_name = category.get('id')
69 if not self.config.has_section(section_name):
70 self.config.add_section(section_name)
71 options = category.xpath('./variablelist/variable')
72 for option in options:
73 option_name = option.get('id')
74 value = option.xpath('./value')[0].text
75 if not value:
76 value = ""
77 self.config.set(section_name, option_name, value)
78
79 def load_shell(self, filename):
80 f = open(filename, 'r')
81 for line in f:
82 try:
83 if line.startswith('#'):
84 continue
85 parts = line.strip().split("=")
86 if len(parts) < 2:
87 continue
88 option = parts[0]
89 value = parts[1].replace('"', '').replace("'","")
90 section, var = self.locate_varname(option, strict=False)
91 if section and var:
92 self.set(section, var, value)
93 except:
94 pass
95 f.close()
96
97 def locate_varname(self, varname, strict=True):
98 varname = varname.lower()
99 sections = self.config.sections()
100 section_name = ""
101 var_name = ""
102 for section in sections:
103 if varname.startswith(section.lower()) and len(section) > len(section_name):
104 section_name = section.lower()
105 var_name = varname.replace(section_name, "")[1:]
106 if strict and not self.config.has_option(section_name, var_name):
107 raise ConfigParser.NoOptionError(var_name, section_name)
108 return (section_name, var_name)
109
110 def set_attributes(self):
111 sections = self.config.sections()
112 for section in sections:
113 for item in self.config.items(section):
114 name = "%s_%s" % (section, item[0])
115 value = item[1]
116 if isbool(value):
117 value = str2bool(value)
118 elif value.isdigit():
119 value = int(value)
120 setattr(self, name, value)
121 setattr(self, name.upper(), value)
122
123
124 def verify(self, config1, config2, validate_method):
125 return True
126
127 def validate_type(self, var_type, value):
128 return True
129
130 @staticmethod
131 def is_xml(config_file):
132 try:
133 x = Xml(config_file)
134 return True
135 except:
136 return False
137
138 @staticmethod
139 def is_ini(config_file):
140 try:
141 c = ConfigParser.ConfigParser()
142 c.read(config_file)
143 return True
144 except ConfigParser.MissingSectionHeaderError:
145 return False
146
147
148 def dump(self, sections = []):
149 sys.stdout.write(output_python())
150
151 def output_python(self, encoding = "utf-8"):
152 buf = codecs.lookup(encoding)[3](StringIO())
153 buf.writelines(["# " + line + os.linesep for line in self._header()])
154
155 for section in self.sections():
156 buf.write("[%s]%s" % (section, os.linesep))
157 for (name,value) in self.items(section):
158 buf.write("%s=%s%s" % (name,value,os.linesep))
159 buf.write(os.linesep)
160 return buf.getvalue()
161
162 def output_shell(self, show_comments = True, encoding = "utf-8"):
163 """
164 Return variables as a shell script.
165 """
166
167 buf = codecs.lookup(encoding)[3](StringIO())
168 buf.writelines(["# " + line + os.linesep for line in self._header()])
169
170 for section in self.sections():
171 for (name,value) in self.items(section):
172 # bash does not have the concept of NULL
173 if value:
174 option = "%s_%s" % (section.upper(), name.upper())
175 if isbool(value):
176 value = str(str2bool(value))
177 elif not value.isdigit():
178 value = '"%s"' % value
179 buf.write(option + "=" + value + os.linesep)
180 return buf.getvalue()
181
182 def output_php(self, encoding = "utf-8"):
183 """
184 Return variables as a PHP script.
185 """
186
187 buf = codecs.lookup(encoding)[3](StringIO())
188 buf.write("<?php" + os.linesep)
189 buf.writelines(["// " + line + os.linesep for line in self._header()])
190
191 for section in self.sections():
192 for (name,value) in self.items(section):
193 option = "%s_%s" % (section, name)
194 buf.write(os.linesep)
195 buf.write("// " + option + os.linesep)
196 if value is None:
197 value = 'NULL'
198 buf.write("define('%s', %s);" % (option, value) + os.linesep)
199
200 buf.write("?>" + os.linesep)
201
202 return buf.getvalue()
203
204 def output_xml(self, encoding = "utf-8"):
205 pass
206
207 def output_variables(self, encoding="utf-8"):
208 """
209 Return list of all variable names.
210 """
211
212 buf = codecs.lookup(encoding)[3](StringIO())
213 for section in self.sections():
214 for (name,value) in self.items(section):
215 option = "%s_%s" % (section,name)
216 buf.write(option + os.linesep)
217
218 return buf.getvalue()
219 pass
220
221 def write(self, filename=None):
222 if not filename:
223 filename = self.filename
224 configfile = open(filename, 'w')
225 self.config.write(configfile)
226
227 def save(self, filename=None):
228 self.write(filename)
229
230 def __getattr__(self, attr):
231 return getattr(self.config, attr)
232
233if __name__ == '__main__':
234 filename = None
235 if len(sys.argv) > 1:
236 filename = sys.argv[1]
237 config = Config(filename)
238 else:
239 config = Config()
240 config.dump()