1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 import glob
19 import os
20 import gtk
21 import gobject
22 import gettext
23 import screenlets
24
25 gettext.textdomain('screenlets')
26 gettext.bindtextdomain('screenlets', screenlets.INSTALL_PREFIX + '/share/locale')
27
29 return gettext.gettext(s)
30
31
32 try:
33 import gconf
34 except:
35 print "GConf python module not found. GConf settings backend is disabled."
36
37
39 """The backend performs the loading/saving of the 'key=value'-strings.
40 Extend this superclass to implement different saving-backends."""
41
44
46 """Delete an instance's configuration by its id."""
47 pass
48
50 """Immediately store all values to disk (in case the backend doesn't
51 save in realtime anyway."""
52 pass
53
55 """Load one option for the instance with the given id."""
56 pass
57
59 """Load all options for the instance with the given id."""
60 pass
61
63 """Save one option for the instance with the given id."""
64 pass
65
66
68 """Backend for storing settings in the GConf registry"""
69
70 gconf_dir = '/apps/screenlets/'
71
76
78 """Delete an instance's configuration by its id."""
79 os.system('gconftool-2 --recursive-unset ' + self.key + id)
80 return True
81
83 """Immediately store all values to disk (in case the backend doesn't
84 save in realtime anyway."""
85 pass
86
88 """Load one option for the instance with the given id."""
89 return self.client.get_string(self.gconf_dir + id + '/' + name)
90
92 """Load all options for the instance with the given id."""
93 keys = []
94 vals = []
95 for i in self.client.all_entries(self.gconf_dir + id):
96 keys.append(i.key.split('/')[4])
97 vals.append(self.client.get_string(i.key))
98 return dict(zip(keys, vals))
99 return None
100
102 """Save one option for the instance with the given id."""
103 self.client.set_string(self.gconf_dir + id + '/' + name, value)
104 print 'Saved option %s%s/%s = %s' % (self.gconf_dir, id, name, value)
105
106
108 """A backend that stores the settings in arrays and saves after a short
109 interval to avoid overhead when multiple values are set within a short time.
110 The data gets saved into $HOME/.config/Screenlets/<Screenletname>/, in a
111 file for each element (named like its id with the extension '.ini')."""
112
113
114 __instances = {}
115 __delay_time = 3000
116 __timeout = None
117 __queue = []
118
119
120 path = ''
121
122
127
129 """Delete an instance from the list and from the filesystem."""
130 if self.__instances.has_key(id):
131 del self.__instances[id]
132 try:
133 import os
134 os.remove(self.path + id + '.ini')
135 except Exception,ex:
136 print ex
137 print "Temporary file didn't exist - nothing to remove."
138 return False
139 print "CachingBackend: <#%s> removed!" % id
140 return True
141
143 """Immediately save all pending data."""
144 self.__save_cache()
145
163
165 """TODO: Load option from the backend (returned as str)."""
166 return self.__instances[id][name]
167
169 """Load all options for the instance with the given id."""
170
171 if self.__instances.has_key(id):
172 return self.__instances[id]
173 return None
174
176 """Load all cached files from path."""
177
178 print "CachingBackend: Loading instances from cache"
179
180 dirname = self.path
181 dirlst = glob.glob(dirname + '*')
182 tdlen = len(dirname)
183 lst = []
184 for fname in dirlst:
185 dname = fname[tdlen:]
186 if dname.endswith('.ini'):
187 id = dname[:-4]
188 print "CachingBackend: Loading <%s>" % id
189
190 if self.__instances.has_key(id) == False:
191 self.__instances[id] = {}
192
193 try:
194 f = open(fname, 'r')
195 lines = f.readlines()
196
197 for line in lines:
198
199 parts = line[:-1].split('=', 1)
200 if len(parts) > 1:
201
202
203
204 if parts[0] == 'x':
205 if parts[1].startswith("*"):
206 parts[1] = parts[1].strip("*")
207 add_width = 0
208 if parts[1].startswith("_"):
209 add_width = int(float(self.__instances[id]["width"])*float(self.__instances[id]["scale"]))
210 print "ADD W", add_width
211 parts[1] = str(gtk.gdk.screen_width() - int(parts[1].strip("_")) - add_width)
212 print ">>>X", parts[1]
213 if parts[0] == 'y':
214 if parts[1].startswith("*"):
215 parts[1] = parts[1].strip("*")
216 add_height = 0
217 if parts[1].startswith("_"):
218 add_height = int(float(self.__instances[id]["height"])*float(self.__instances[id]["scale"]))
219 print "ADD H", add_height
220 parts[1] = str(gtk.gdk.screen_height() - int(parts[1].strip("_")) - add_height)
221 print ">>>Y", parts[1]
222 if parts[0] == 'rel_x':
223 parts[0] = 'x'
224 add_width = 0
225 if parts[1].startswith("_"):
226 add_width = int(float(self.__instances[id]["width"])*float(self.__instances[id]["scale"]))
227 print "ADD W", add_width
228 parts[1] = str(int(gtk.gdk.screen_width()*float(parts[1].strip("_"))) - add_width)
229 print ">>>X", parts[1]
230 if parts[0] == 'rel_y':
231 parts[0] = 'y'
232 add_height = 0
233 if parts[1].startswith("_"):
234 add_height = int(float(self.__instances[id]["height"])*float(self.__instances[id]["scale"]))
235 print "ADD H", add_height
236 parts[1] = str(int(gtk.gdk.screen_height()*float(parts[1].strip("_"))) - add_height)
237 print ">>>Y", parts[1]
238 if parts[0] == 'rel_scale':
239 parts[0] = 'scale'
240 scale = float(self.__instances[id]["scale"])
241 initial_scale = scale + float(gtk.gdk.screen_height()*gtk.gdk.screen_width())/float(parts[1])
242 if initial_scale < 1.5:
243 initial_scale = 1.5
244 if initial_scale > 3:
245 initial_scale = 3
246 parts[1] = str(initial_scale)
247
248 print ">>>SCALE", parts[1]
249 if parts[0] == 'rel_font_name':
250 parts[0] = 'font_name'
251 print "|||", parts[1]
252 font_parts = parts[1].split(" ")
253 parts[1]=""
254 for fp in font_parts:
255 if len(fp.strip("0123456789.")) == 0:
256 parts[1]+= str( round(float(fp)*float(self.__instances[id]["scale"]), 1) ) + " "
257 else:
258 parts[1]+= fp + " "
259 parts[1] = parts[1].strip(" ")
260 print ">>>FONT_NAME", parts[1]
261
262 print "%s='%s'" % (parts[0], parts[1])
263 self.__instances[id][parts[0]] = parts[1]
264 f.close()
265 except Exception, ex:
266 print "Error while loading options: %s" % str(ex)
267
269 """Save the cache (for all pending instances in queue) to self.path."""
270
271 for id in self.__queue:
272
273 if self.__instances.has_key(id) == False:
274 print "Queue-element <%s> not found (already removed?)!" % id
275 self.__queue.remove(id)
276 break
277
278
279 lst = []
280 for oname in self.__instances[id]:
281 lst.append([oname, self.__instances[id][oname]])
282
283 if len(lst) > 0:
284 self.__save_settings (self.path + id + '.ini', lst)
285
286 self.__queue = []
287
288 return False
289
291 """ Try to save settings in a file, first save this to a temporal file avoid encodings a disk full errors """
292 filenametmp = filename + '.tmp'
293 isOk = True
294 newini = ''
295 try:
296
297 for el in lst:
298 newini += "%s=%s\n" % (el[0], el[1])
299 except:
300 isOk = False
301 print "error while convert config to string (encoding error?), I lose your last changes :'("
302
303 if isOk:
304
305 try:
306 open(filenametmp, 'w').write(newini)
307 except:
308 isOk = False
309 print "error while saving configuration to a temporal file %s, disk full?" % filenametmp
310
311 if isOk:
312
313 try:
314 import shutil
315 shutil.move(filenametmp, filename)
316 except:
317 print "error while moving temporal file to configuration file, %s > %s, sorry, I lose your settings. :'(" % (filenametmp, filename)
318