Package screenlets :: Module backend
[hide private]
[frames] | no frames]

Source Code for Module screenlets.backend

  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 gobject 
 21  import gettext 
 22   
 23  gettext.textdomain('screenlets') 
 24  gettext.bindtextdomain('screenlets', '/usr/share/locale') 
 25   
26 -def _(s):
27 return gettext.gettext(s)
28 29 30 try: 31 import gconf 32 except: 33 print _("GConf python module not found. GConf settings backend is disabled.") 34 35
36 -class ScreenletsBackend:
37 """The backend performs the loading/saving of the 'key=value'-strings. 38 Extend this superclass to implement different saving-backends.""" 39
40 - def __init__ (self):
41 pass
42
43 - def delete_instance (self, id):
44 """Delete an instance's configuration by its id.""" 45 pass
46
47 - def flush (self):
48 """Immediately store all values to disk (in case the backend doesn't 49 save in realtime anyway.""" 50 pass
51
52 - def load_option (self, id, name):
53 """Load one option for the instance with the given id.""" 54 pass
55
56 - def load_instance (self, id):
57 """Load all options for the instance with the given id.""" 58 pass
59
60 - def save_option (self, id, name, value):
61 """Save one option for the instance with the given id.""" 62 pass
63 64
65 -class GconfBackend (ScreenletsBackend):
66 """Backend for storing settings in the GConf registry""" 67 68 gconf_dir = '/apps/screenlets/' 69
70 - def __init__ (self):
71 ScreenletsBackend.__init__(self) 72 print _('GConfBackend: initializing') 73 self.client = gconf.client_get_default()
74
75 - def delete_instance (self, id):
76 """Delete an instance's configuration by its id.""" 77 os.system('gconftool-2 --recursive-unset ' + self.key + id) 78 return True
79
80 - def flush (self):
81 """Immediately store all values to disk (in case the backend doesn't 82 save in realtime anyway.""" 83 pass #No need, GConf saves in realtime
84
85 - def load_option (self, id, name):
86 """Load one option for the instance with the given id.""" 87 return self.client.get_string(self.gconf_dir + id + '/' + name)
88
89 - def load_instance (self, id):
90 """Load all options for the instance with the given id.""" 91 keys = [] 92 vals = [] 93 for i in self.client.all_entries(self.gconf_dir + id): 94 keys.append(i.key.split('/')[4]) 95 vals.append(self.client.get_string(i.key)) 96 return dict(zip(keys, vals)) 97 return None
98
99 - def save_option (self, id, name, value):
100 """Save one option for the instance with the given id.""" 101 self.client.set_string(self.gconf_dir + id + '/' + name, value) 102 print _('Saved option %s%s/%s = %s') % (self.gconf_dir, id, name, value)
103 104
105 -class CachingBackend (ScreenletsBackend):
106 """A backend that stores the settings in arrays and saves after a short 107 interval to avoid overhead when multiple values are set within a short time. 108 The data gets saved into $HOME/.config/Screenlets/<Screenletname>/, in a 109 file for each element (named like its id with the extension '.ini').""" 110 111 # internals 112 __instances = {} # a dict with (id:dict)-entries cntaining the data 113 __delay_time = 3000 # delay to wait before performing save 114 __timeout = None # the id of the timeout-function 115 __queue = [] # list with ids of instances that need saving 116 117 # attribs 118 path = '' # the path to store the files 119 120 # Constructor
121 - def __init__ (self, path):
122 ScreenletsBackend.__init__(self) 123 self.path = path 124 self.__load_cache()
125
126 - def delete_instance (self, id):
127 """Delete an instance from the list and from the filesystem.""" 128 if self.__instances.has_key(id): 129 del self.__instances[id] 130 try: 131 import os 132 os.remove(self.path + id + '.ini') 133 except Exception,ex: 134 print ex 135 print _("Temporary file didn't exist - nothing to remove.") 136 return False 137 print _("CachingBackend: <#%s> removed!") % id 138 return True
139
140 - def flush (self):
141 """Immediately save all pending data.""" 142 self.__save_cache()
143
144 - def save_option (self, id, name, value):
145 """Save option for an instance to cache and start saving-timeout 146 for that element (value must be of type string).""" 147 # create key for option, if not existent yet 148 if self.__instances.has_key(id) == False: 149 self.__instances[id] = {} 150 # set option in array 151 self.__instances[id][name] = str(value) 152 #print "CachingBackend.save_option: "+name+"="+self.__instances[id][name] 153 # if id is not already in queue, add the id to the queue 154 if self.__queue.count(id) == 0: 155 self.__queue.append(id) 156 # reset timeout and start new 157 if self.__timeout: 158 gobject.source_remove(self.__timeout) 159 self.__timeout = gobject.timeout_add(self.__delay_time, 160 self.__save_cache)#, id)
161
162 - def load_option (self, id, name):
163 """TODO: Load option from the backend (returned as str).""" 164 return self.__instances[id][name]
165
166 - def load_instance (self, id):
167 """Load all options for the instance with the given id.""" 168 #print "Load element: "+id 169 if self.__instances.has_key(id): 170 return self.__instances[id] 171 return None
172
173 - def __load_cache (self):
174 """Load all cached files from path.""" 175 # perform saving 176 print "CachingBackend: Loading instances from cache" 177 # get dir content of self.path 178 dirname = self.path 179 dirlst = glob.glob(dirname + '*') 180 tdlen = len(dirname) 181 lst = [] 182 for fname in dirlst: 183 dname = fname[tdlen:] 184 if dname.endswith('.ini'): 185 id = dname[:-4] 186 print _("CachingBackend: Loading <%s>") % id 187 #print "ID: "+id 188 if self.__instances.has_key(id) == False: 189 self.__instances[id] = {} 190 # open file 191 try: 192 f = open(fname, 'r') 193 lines = f.readlines() 194 # read all options for this element from file 195 for line in lines: 196 #print "LOAD: "+line[:-1] 197 parts = line[:-1].split('=', 1) 198 if len(parts) > 1: 199 self.__instances[id][parts[0]] = parts[1] 200 f.close() 201 except Exception, ex: 202 print _("Error while loading options: %s") % str(ex)
203
204 - def __save_cache (self):
205 """Save the cache (for all pending instances in queue) to self.path.""" 206 # loop through all instances in queue: 207 for id in self.__queue: 208 # if element with id not exists, remove it and break 209 if self.__instances.has_key(id) == False: 210 print _("Queue-element <%s> not found (already removed?)!") % id 211 self.__queue.remove(id) 212 break 213 # create list with options 214 print _("CachingBackend: Saving <#%s> :) ...") % id 215 lst = [] 216 for oname in self.__instances[id]: 217 lst.append([oname, self.__instances[id][oname]]) 218 # and save them (if any) 219 if len(lst) > 0: 220 try: 221 f = open(self.path + id + '.ini', 'w') 222 for el in lst: 223 f.write(el[0] + '=' + el[1] + "\n") 224 f.close() 225 print "OK" 226 except: 227 print _("error while saving config: %s%s") % (self.path, oname) 228 # clear queue 229 self.__queue = [] 230 # NOT continue the timeout-function (!!!!!) 231 return False
232