| 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
24 gettext.textdomain('screenlets')
25 gettext.bindtextdomain('screenlets', '/usr/share/locale')
26
29
30
31 try:
32 import gconf
33 except:
34 print "GConf python module not found. GConf settings backend is disabled."
35
36
38 """The backend performs the loading/saving of the 'key=value'-strings.
39 Extend this superclass to implement different saving-backends."""
40
43
47
49 """Immediately store all values to disk (in case the backend doesn't
50 save in realtime anyway."""
51 pass
52
56
60
64
65
67 """Backend for storing settings in the GConf registry"""
68
69 gconf_dir = '/apps/screenlets/'
70
72 ScreenletsBackend.__init__(self)
73 print 'GConfBackend: initializing'
74 self.client = gconf.client_get_default()
75
77 """Delete an instance's configuration by its id."""
78 os.system('gconftool-2 --recursive-unset ' + self.key + id)
79 return True
80
82 """Immediately store all values to disk (in case the backend doesn't
83 save in realtime anyway."""
84 pass #No need, GConf saves in realtime
85
87 """Load one option for the instance with the given id."""
88 return self.client.get_string(self.gconf_dir + id + '/' + name)
89
91 """Load all options for the instance with the given id."""
92 keys = []
93 vals = []
94 for i in self.client.all_entries(self.gconf_dir + id):
95 keys.append(i.key.split('/')[4])
96 vals.append(self.client.get_string(i.key))
97 return dict(zip(keys, vals))
98 return None
99
104
105
107 """A backend that stores the settings in arrays and saves after a short
108 interval to avoid overhead when multiple values are set within a short time.
109 The data gets saved into $HOME/.config/Screenlets/<Screenletname>/, in a
110 file for each element (named like its id with the extension '.ini')."""
111
112 # internals
113 __instances = {} # a dict with (id:dict)-entries cntaining the data
114 __delay_time = 3000 # delay to wait before performing save
115 __timeout = None # the id of the timeout-function
116 __queue = [] # list with ids of instances that need saving
117
118 # attribs
119 path = '' # the path to store the files
120
121 # Constructor
126
128 """Delete an instance from the list and from the filesystem."""
129 if self.__instances.has_key(id):
130 del self.__instances[id]
131 try:
132 import os
133 os.remove(self.path + id + '.ini')
134 except Exception,ex:
135 print ex
136 print "Temporary file didn't exist - nothing to remove."
137 return False
138 print "CachingBackend: <#%s> removed!" % id
139 return True
140
144
146 """Save option for an instance to cache and start saving-timeout
147 for that element (value must be of type string)."""
148 # create key for option, if not existent yet
149 if self.__instances.has_key(id) == False:
150 self.__instances[id] = {}
151 # set option in array
152 self.__instances[id][name] = str(value)
153 #print "CachingBackend.save_option: "+name+"="+self.__instances[id][name]
154 # if id is not already in queue, add the id to the queue
155 if self.__queue.count(id) == 0:
156 self.__queue.append(id)
157 # reset timeout and start new
158 if self.__timeout:
159 gobject.source_remove(self.__timeout)
160 self.__timeout = gobject.timeout_add(self.__delay_time,
161 self.__save_cache)#, id)
162
164 """TODO: Load option from the backend (returned as str)."""
165 return self.__instances[id][name]
166
168 """Load all options for the instance with the given id."""
169 #print "Load element: "+id
170 if self.__instances.has_key(id):
171 return self.__instances[id]
172 return None
173
175 """Load all cached files from path."""
176 # perform saving
177 print "CachingBackend: Loading instances from cache"
178 # get dir content of self.path
179 dirname = self.path
180 dirlst = glob.glob(dirname + '*')
181 tdlen = len(dirname)
182 lst = []
183 for fname in dirlst:
184 dname = fname[tdlen:]
185 if dname.endswith('.ini'):
186 id = dname[:-4]
187 print "CachingBackend: Loading <%s>" % id
188 #print "ID: "+id
189 if self.__instances.has_key(id) == False:
190 self.__instances[id] = {}
191 # open file
192 try:
193 f = open(fname, 'r')
194 lines = f.readlines()
195 # read all options for this element from file
196 for line in lines:
197 #print "LOAD: "+line[:-1]
198 parts = line[:-1].split('=', 1)
199 if len(parts) > 1:
200 # undocumented feature to resize screenlet dynamically on first launch
201 # by boamaod for Estobuntu
202 if parts[0] == 'rel_x':
203 parts[0] = 'x'
204 parts[1] = str(int(gtk.gdk.screen_width()*float(parts[1])))
205 if parts[0] == 'rel_y':
206 parts[0] = 'y'
207 parts[1] = str(int(gtk.gdk.screen_height()*float(parts[1])))
208 if parts[0] == 'rel_scale':
209 parts[0] = 'scale'
210 parts[1] = str(gtk.gdk.screen_height()/float(parts[1]))
211 print "%s='%s'" % (parts[0], parts[1])
212 self.__instances[id][parts[0]] = parts[1]
213 f.close()
214 except Exception, ex:
215 print "Error while loading options: %s" % str(ex)
216
218 """Save the cache (for all pending instances in queue) to self.path."""
219 # loop through all instances in queue:
220 for id in self.__queue:
221 # if element with id not exists, remove it and break
222 if self.__instances.has_key(id) == False:
223 print "Queue-element <%s> not found (already removed?)!" % id
224 self.__queue.remove(id)
225 break
226 # create list with options
227 #print "CachingBackend: Saving <#%s> :) ..." % id
228 lst = []
229 for oname in self.__instances[id]:
230 lst.append([oname, self.__instances[id][oname]])
231 # and save them (if any)
232 if len(lst) > 0:
233 self.__save_settings (self.path + id + '.ini', lst)
234 # clear queue
235 self.__queue = []
236 # NOT continue the timeout-function (!!!!!)
237 return False
238
240 """ Try to save settings in a file, first save this to a temporal file avoid encodings a disk full errors """
241 filenametmp = filename + '.tmp'
242 isOk = True
243 newini = ''
244 try:
245 # Is posible to fail with encoding error?
246 for el in lst:
247 newini += "%s=%s\n" % (el[0], el[1])
248 except:
249 isOk = False
250 print "error while convert config to string (encoding error?), I lose your last changes :'("
251
252 if isOk:
253 # Write the new settings to a temporal file, disk full, encoding, rights may fails at this point.
254 try:
255 open(filenametmp, 'w').write(newini)
256 except:
257 isOk = False
258 print "error while saving configuration to a temporal file %s, disk full?" % filenametmp
259
260 if isOk:
261 # Move saved settings to definitive configuration file, disk error o incorrect rights may fails at this point.
262 try:
263 import shutil
264 shutil.move(filenametmp, filename)
265 except:
266 print "error while moving temporal file to configuration file, %s > %s, sorry, I lose your settings. :'(" % (filenametmp, filename)
267
| Home | Trees | Indices | Help |
|
|---|
| Generated by Epydoc 3.0.1 on Sat Dec 4 19:47:06 2010 | http://epydoc.sourceforge.net |