| Home | Trees | Indices | Help |
|
|---|
|
|
1 # This application is released under the GNU General Public License
2 # v3 (or, at your option, any later version). You can find the full
3 # text of the license under http://www.gnu.org/licenses/gpl.txt.
4 # By using, editing and/or distributing this software you agree to
5 # the terms and conditions of this license.
6 # Thank you for using free software!
7 #
8 # screenlets.backend (c) RYX (aka Rico Pfaus) 2007 <ryx@ryxperience.com>
9 #
10 # INFO:
11 # - The backend offers an abstracted way of saving a Screenlet's data
12 #
13 # TODO:
14 # - add "type"-argument to save_option and read_option to be able to correctly
15 # set the values in GconfBackend (instead of storing only strings).
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
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
48
50 """Immediately store all values to disk (in case the backend doesn't
51 save in realtime anyway."""
52 pass
53
57
61
65
66
68 """Backend for storing settings in the GConf registry"""
69
70 gconf_dir = '/apps/screenlets/'
71
73 ScreenletsBackend.__init__(self)
74 print 'GConfBackend: initializing'
75 self.client = gconf.client_get_default()
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 #No need, GConf saves in realtime
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
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 # internals
114 __instances = {} # a dict with (id:dict)-entries cntaining the data
115 __delay_time = 3000 # delay to wait before performing save
116 __timeout = None # the id of the timeout-function
117 __queue = [] # list with ids of instances that need saving
118
119 # attribs
120 path = '' # the path to store the files
121
122 # Constructor
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
145
147 """Save option for an instance to cache and start saving-timeout
148 for that element (value must be of type string)."""
149 # create key for option, if not existent yet
150 if self.__instances.has_key(id) == False:
151 self.__instances[id] = {}
152 # set option in array
153 self.__instances[id][name] = str(value)
154 #print "CachingBackend.save_option: "+name+"="+self.__instances[id][name]
155 # if id is not already in queue, add the id to the queue
156 if self.__queue.count(id) == 0:
157 self.__queue.append(id)
158 # reset timeout and start new
159 if self.__timeout:
160 gobject.source_remove(self.__timeout)
161 self.__timeout = gobject.timeout_add(self.__delay_time,
162 self.__save_cache)#, id)
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 #print "Load element: "+id
171 if self.__instances.has_key(id):
172 return self.__instances[id]
173 return None
174
176 """Load all cached files from path."""
177 # perform saving
178 print "CachingBackend: Loading instances from cache"
179 # get dir content of self.path
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 #print "ID: "+id
190 if self.__instances.has_key(id) == False:
191 self.__instances[id] = {}
192 # open file
193 try:
194 f = open(fname, 'r')
195 lines = f.readlines()
196 # read all options for this element from file
197 for line in lines:
198 #print "LOAD: "+line[:-1]
199 parts = line[:-1].split('=', 1)
200 if len(parts) > 1:
201 # undocumented feature to resize screenlet dynamically on first launch
202 # by boamaod for Estobuntu
203 if parts[0] == 'rel_x':
204 parts[0] = 'x'
205 parts[1] = str(int(gtk.gdk.screen_width()*float(parts[1])))
206 if parts[0] == 'rel_y':
207 parts[0] = 'y'
208 parts[1] = str(int(gtk.gdk.screen_height()*float(parts[1])))
209 if parts[0] == 'rel_scale':
210 parts[0] = 'scale'
211 parts[1] = str(gtk.gdk.screen_height()/float(parts[1]))
212 print "%s='%s'" % (parts[0], parts[1])
213 self.__instances[id][parts[0]] = parts[1]
214 f.close()
215 except Exception, ex:
216 print "Error while loading options: %s" % str(ex)
217
219 """Save the cache (for all pending instances in queue) to self.path."""
220 # loop through all instances in queue:
221 for id in self.__queue:
222 # if element with id not exists, remove it and break
223 if self.__instances.has_key(id) == False:
224 print "Queue-element <%s> not found (already removed?)!" % id
225 self.__queue.remove(id)
226 break
227 # create list with options
228 #print "CachingBackend: Saving <#%s> :) ..." % id
229 lst = []
230 for oname in self.__instances[id]:
231 lst.append([oname, self.__instances[id][oname]])
232 # and save them (if any)
233 if len(lst) > 0:
234 self.__save_settings (self.path + id + '.ini', lst)
235 # clear queue
236 self.__queue = []
237 # NOT continue the timeout-function (!!!!!)
238 return False
239
241 """ Try to save settings in a file, first save this to a temporal file avoid encodings a disk full errors """
242 filenametmp = filename + '.tmp'
243 isOk = True
244 newini = ''
245 try:
246 # Is posible to fail with encoding error?
247 for el in lst:
248 newini += "%s=%s\n" % (el[0], el[1])
249 except:
250 isOk = False
251 print "error while convert config to string (encoding error?), I lose your last changes :'("
252
253 if isOk:
254 # Write the new settings to a temporal file, disk full, encoding, rights may fails at this point.
255 try:
256 open(filenametmp, 'w').write(newini)
257 except:
258 isOk = False
259 print "error while saving configuration to a temporal file %s, disk full?" % filenametmp
260
261 if isOk:
262 # Move saved settings to definitive configuration file, disk error o incorrect rights may fails at this point.
263 try:
264 import shutil
265 shutil.move(filenametmp, filename)
266 except:
267 print "error while moving temporal file to configuration file, %s > %s, sorry, I lose your settings. :'(" % (filenametmp, filename)
268
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Mon Feb 28 23:21:28 2011 | http://epydoc.sourceforge.net |