1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 """\
27 X2GoProcessIniFile - helper class for parsing .ini files
28
29 """
30 __NAME__ = 'x2goinifiles-pylib'
31
32
33 import os
34 import ConfigParser
35 import types
36 import cStringIO
37 import copy
38
39
40 from defaults import LOCAL_HOME as _current_home
41 import log
42 import utils
45 """
46 Base class for processing the different ini files used by X2Go
47 clients. Primarily used to standardize the content of the different
48 X2Go client ini file (settings, printing, sessions, xconfig).
49
50 If entries are omitted in an ini file, they are filled with
51 default values (as hard coded in Python X2Go), so the resulting objects
52 always contain the same fields.
53
54 """
55
57 """\
58 @param config_files: a list of configuration file names (e.g. a global filename and a user's home
59 directory filename)
60 @type config_files: C{list}
61 @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
62 Python X2Go's hard coded defaults in L{defaults}
63 @type defaults: C{dict}
64 @param logger: you can pass an L{X2GoLogger} object to the
65 L{X2GoIniFile} constructor
66 @type logger: L{X2GoLogger} instance
67 @param loglevel: if no L{X2GoLogger} object has been supplied a new one will be
68 constructed with the given loglevel
69 @type loglevel: C{int}
70
71 """
72 self.user_config_file = None
73 self._write_user_config = True
74
75
76 if not config_files:
77 config_files = []
78
79 if logger is None:
80 self.logger = log.X2GoLogger(loglevel=loglevel)
81 else:
82 self.logger = copy.deepcopy(logger)
83 self.logger.tag = __NAME__
84
85 self.config_files = config_files
86
87 if utils._checkIniFileDefaults(defaults):
88 self.defaultValues = defaults
89 else:
90 self.defaultValues = {}
91
92
93
94
95
96 self.iniConfig = ConfigParser.SafeConfigParser()
97 self.iniConfig.optionxform = str
98
99 _create_file = False
100 for file_name in self.config_files:
101 file_name = os.path.normpath(file_name)
102 if file_name.startswith(_current_home):
103 if not os.path.exists(file_name):
104 utils.touch_file(file_name)
105 _create_file = True
106 self.user_config_file = file_name
107 break
108 self.load()
109
110 if _create_file:
111 self._write_user_config = True
112 self._X2GoIniFile__write()
113
115 """\
116 R(e-r)ead configuration file(s).
117
118 """
119 self.logger('proposed config files are %s' % self.config_files, loglevel=log.loglevel_INFO, )
120 _found_config_files = self.iniConfig.read(self.config_files)
121 self.logger('config files found: %s' % _found_config_files or 'none', loglevel=log.loglevel_INFO, )
122
123 for file_name in _found_config_files:
124 if file_name.startswith(os.path.normpath(_current_home)):
125
126 self.user_config_file = file_name
127 break
128
129 self.config_files = _found_config_files
130 self._fill_defaults()
131
133 result = 'X2GoIniFile('
134 for p in dir(self):
135 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
136 result += p + '=' + str(self.__dict__[p]) + ','
137 result = result.strip(',')
138 return result + ')'
139
141 """\
142 Stores a value for a given section and key.
143
144 This methods affects a SafeConfigParser object held in
145 RAM. No configuration file is affected by this
146 method. To write the configuration to disk use
147 the L{write()} method.
148
149 @param section: the ini file section
150 @type section: C{str}
151 @param key: the ini file key in the given section
152 @type key: C{str}
153 @param value: the value for the given section and key
154 @type value: C{str}, C{list}, C{booAl}, ...
155
156 """
157 if type(value) == type(u''):
158 value = value.encode(utils.get_encoding())
159 if type(value) is types.BooleanType:
160 self.iniConfig.set(section, key, str(int(value)))
161 elif type(value) in (types.ListType, types.TupleType):
162 self.iniConfig.set(section, key, ", ".join(value))
163 else:
164 self.iniConfig.set(section, key, str(value))
165
167 """\
168 Fills a C{SafeConfigParser} object with the default ini file
169 values as pre-defined in Python X2Go or. This SafeConfigParser
170 object is held in RAM. No configuration file is affected by this
171 method.
172
173 """
174 for section, sectionvalue in self.defaultValues.items():
175 for key, value in sectionvalue.items():
176 if self.iniConfig.has_option(section, key): continue
177 if not self.iniConfig.has_section(section):
178 self.iniConfig.add_section(section)
179 self._storeValue(section, key, value)
180
182 """\
183 Change a value for a given section and key. This method
184 does not have any effect on configuration files.
185
186 @param section: the ini file section
187 @type section: C{str}
188 @param key: the ini file key in the given section
189 @type key: C{str}
190 @param value: the value for the given section and key
191 @type value: C{str}, C{list}, C{bool}, ...
192
193 """
194 if not self.iniConfig.has_section(section):
195 self.iniConfig.add_section(section)
196 self._storeValue(section, key, value)
197 self._write_user_config = True
198 __update_value = update_value
199
201 """\
202 Write the ini file modifications (SafeConfigParser object) from RAM to disk.
203
204 For writing the first of the C{config_files} specified on instance construction
205 that is writable will be used.
206
207 @return: C{True} if the user config file has been successfully written, C{False} otherwise.
208 @rtype: C{bool}
209
210 """
211 if self.user_config_file and self._write_user_config:
212 try:
213 fd = open(self.user_config_file, 'wb')
214 self.iniConfig.write(fd)
215 fd.close()
216 self._write_user_config = False
217 return True
218 except Exception, e:
219 print e
220 return False
221 __write = write
222
224 """\
225 Retrieve a value type for a given section and key. The returned
226 value type is based on the default values dictionary.
227
228 @param section: the ini file section
229 @type section: C{str}
230 @param key: the ini file key in the given section
231 @type key: C{str}
232
233 @return: a Python variable type
234 @rtype: class
235
236 """
237 return type(self.defaultValues[section][key])
238
239 - def get_value(self, section, key, key_type=None):
240 """\
241 Retrieve a value for a given section and key.
242
243 @param section: the ini file section
244 @type section: C{str}
245 @param key: the ini file key in the given section
246 @type key: C{str}
247
248 @return: the value for the given section and key
249 @rtype: class
250
251 """
252 if key_type is None:
253 key_type = self.get_type(section, key)
254 if self.iniConfig.has_option(section, key):
255 if key_type is types.BooleanType:
256 return self.iniConfig.getboolean(section, key)
257 elif key_type is types.IntType:
258 return self.iniConfig.getint(section, key)
259 elif key_type is types.ListType:
260 _val = self.iniConfig.get(section, key)
261 _val = _val.strip()
262 if _val.startswith('[') and _val.endswith(']'):
263 return eval(_val)
264 elif ',' in _val:
265 _val = [ v.strip() for v in _val.split(',') ]
266 else:
267 _val = [ _val ]
268 return _val
269 else:
270 _val = self.iniConfig.get(section, key)
271 return _val.decode(utils.get_encoding())
272 get = get_value
273 __call__ = get_value
274
275 @property
277 """\
278 Returns a printable configuration file as a multi-line string.
279
280 """
281 stdout = cStringIO.StringIO()
282 self.iniConfig.write(stdout)
283 _ret_val = stdout.getvalue()
284 stdout.close()
285 return _ret_val
286