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 defaultValues = {
56 'none': {
57 'none': 'empty',
58 },
59 }
60 write_user_config = False
61 user_config_file = None
62
64 """\
65 @param config_files: a list of configuration file names (e.g. a global filename and a user's home
66 directory filename)
67 @type config_files: C{list}
68 @param defaults: a cascaded Python dicitionary structure with ini file defaults (to override
69 Python X2go's hard coded defaults in L{defaults}
70 @type defaults: dict
71 @param logger: you can pass an L{X2goLogger} object to the
72 L{X2goFwServer} constructor
73 @type logger: L{X2goLogger} instance
74 @param loglevel: if no L{X2goLogger} object has been supplied a new one will be
75 constructed with the given loglevel
76 @type loglevel: int
77
78 """
79
80 if not config_files:
81 config_files = []
82
83 if logger is None:
84 self.logger = log.X2goLogger(loglevel=loglevel)
85 else:
86 self.logger = copy.deepcopy(logger)
87 self.logger.tag = __NAME__
88
89 self.config_files = config_files
90
91 if utils._checkIniFileDefaults(defaults):
92 self.defaultValues = defaults
93
94
95
96
97
98 self.iniConfig = ConfigParser.SafeConfigParser()
99 self.iniConfig.optionxform = str
100
101 _create_file = False
102 for file_name in self.config_files:
103 if file_name.startswith(_current_home):
104 if not os.path.exists(file_name):
105 utils.touch_file(file_name)
106 _create_file = True
107 break
108
109 self.load()
110
111 if _create_file:
112 self.write_user_config = True
113 self.write()
114
116 """\
117 R(e-r)ead configuration file(s).
118
119 """
120 self.logger('proposed config files are %s' % self.config_files, loglevel=log.loglevel_INFO, )
121 _found_config_files = self.iniConfig.read(self.config_files)
122 self.logger('config files found: %s' % _found_config_files or 'none', loglevel=log.loglevel_INFO, )
123
124 for file_name in _found_config_files:
125 if file_name.startswith(_current_home):
126
127 self.user_config_file = file_name
128 break
129
130 self.config_files = _found_config_files
131 self._fill_defaults()
132
134 result = 'X2goIniFile('
135 for p in dir(self):
136 if '__' in p or not p in self.__dict__ or type(p) is types.InstanceType: continue
137 result += p + '=' + str(self.__dict__[p])
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
160 if type(value) is types.BooleanType:
161 self.iniConfig.set(section, key, str(int(value)))
162 else:
163 self.iniConfig.set(section, key, str(value))
164
166 """\
167 Fills a C{SafeConfigParser} object with the default ini file
168 values as pre-defined in Python X2go or. This SafeConfigParser
169 object is held in RAM. No configuration file is affected by this
170 method.
171
172 """
173 for section, sectionvalue in self.defaultValues.items():
174 for key, value in sectionvalue.items():
175 if self.iniConfig.has_option(section, key): continue
176 if not self.iniConfig.has_section(section):
177 self.iniConfig.add_section(section)
178 self._storeValue(section, key, value)
179
181 """\
182 Change a value for a given section and key. This method
183 does not have any effect on configuration files.
184
185 @param section: the ini file section
186 @type section: C{str}
187 @param key: the ini file key in the given section
188 @type key: C{str}
189 @param value: the value for the given section and key
190 @type value: C{str}, C{list}, C{bool}, ...
191
192 """
193 if not self.iniConfig.has_section(section):
194 self.iniConfig.add_section(section)
195 self._storeValue(section, key, value)
196 self.write_user_config = True
197
199 """\
200 Write the ini file modifications (SafeConfigParser object) from RAM to disk.
201
202 For writing the first of the C{config_files} specified on instance construction
203 that is writable will be used.
204
205 """
206 if self.user_config_file and self.write_user_config:
207 fd = open(self.user_config_file, 'wb')
208 self.iniConfig.write(fd)
209 fd.close()
210 self.write_user_config = False
211
213 """\
214 Retrieve a value type for a given section and key. The returned
215 value type is based on the default values dictionary.
216
217 @param section: the ini file section
218 @type section: C{str}
219 @param key: the ini file key in the given section
220 @type key: C{str}
221
222 @return: a Python variable type
223 @rtype: class
224
225 """
226 return type(self.defaultValues[section][key])
227
228 - def get_value(self, section, key, key_type=None):
229 """\
230 Retrieve a value for a given section and key.
231
232 @param section: the ini file section
233 @type section: C{str}
234 @param key: the ini file key in the given section
235 @type key: C{str}
236
237 @return: the value for the given section and key
238 @rtype: class
239
240 """
241 if key_type is None:
242 key_type = self.get_type(section, key)
243 if self.iniConfig.has_option(section, key):
244 if key_type is types.BooleanType:
245 return self.iniConfig.getboolean(section, key)
246 elif key_type is types.IntType:
247 return self.iniConfig.getint(section, key)
248 elif key_type is types.ListType:
249 val = self.iniConfig.get(section, key)
250 if val.startswith('[') and val.endswith(']'):
251 return eval(val)
252 else:
253 raise TypeError
254 else:
255 _val = self.iniConfig.get(section, key)
256 return _val.decode(utils.get_encoding())
257 get = get_value
258 __call__ = get_value
259
260 @property
262 """\
263 Returns a printable configuration file as a multi-line string.
264
265 """
266 stdout = cStringIO.StringIO()
267 self.iniConfig.write(stdout)
268 _ret_val = stdout.getvalue()
269 stdout.close()
270 return _ret_val
271