3
# screenlets.backend (c) RYX (aka Rico Pfaus) 2007 <ryx@ryxperience.com>
6
# - The backend offers an abstracted way of saving a Screenlet's data
9
# - add "type"-argument to save_option and read_option to be able to correctly
10
# set the values in GconfBackend (instead of storing only strings).
21
print "GConf python module not found. GConf settings backend is disabled."
24
class ScreenletsBackend:
25
"""The backend performs the loading/saving of the 'key=value'-strings.
26
Extend this superclass to implement different saving-backends."""
31
def delete_instance (self, id):
32
"""Delete an instance's configuration by its id."""
36
"""Immediately store all values to disk (in case the backend doesn't
37
save in realtime anyway."""
40
def load_option (self, id, name):
41
"""Load one option for the instance with the given id."""
44
def load_instance (self, id):
45
"""Load all options for the instance with the given id."""
48
def save_option (self, id, name, value):
49
"""Save one option for the instance with the given id."""
54
"""Backend for storing settings in the GConf registry"""
56
gconf_dir = '/apps/screenlets/'
59
ScreenletsBackend.__init__(self)
60
print 'GConfBackend: initializing'
61
self.client = gconf.client_get_default()
63
def delete_instance (self, id):
64
"""Delete an instance's configuration by its id."""
65
os.system('gconftool-2 --recursive-unset ' + self.key + id)
69
"""Immediately store all values to disk (in case the backend doesn't
70
save in realtime anyway."""
71
pass #No need, GConf saves in realtime
73
def load_option (self, id, name):
74
"""Load one option for the instance with the given id."""
75
return self.client.get_string(self.gconf_dir + id + '/' + name)
77
def load_instance (self, id):
78
"""Load all options for the instance with the given id."""
81
print "Loading options for " + id
82
for i in self.client.all_entries(self.gconf_dir + id):
83
keys.append(i.key[34:])
84
vals.append(self.client.get_string(i.key))
85
return dict(zip(keys, vals))
88
def save_option (self, id, name, value):
89
"""Save one option for the instance with the given id."""
90
self.client.set_string(self.gconf_dir + id + '/' + name, value)
91
print 'Saved option ' + self.gconf_dir + id + '/' + name + ' = ' + value
94
class CachingBackend (ScreenletsBackend):
95
"""A backend that stores the settings in arrays and saves after a short
96
interval to avoid overhead when multiple values are set within a short time.
97
The data gets saved into $HOME/.config/Screenlets/<Screenletname>/, in a
98
file for each element (named like its id with the extension '.ini')."""
101
__instances = {} # a dict with (id:dict)-entries cntaining the data
102
__delay_time = 3000 # delay to wait before performing save
103
__timeout = None # the id of the timeout-function
104
__queue = [] # list with ids of instances that need saving
107
path = '' # the path to store the files
110
def __init__ (self, path):
111
ScreenletsBackend.__init__(self)
115
def delete_instance (self, id):
116
"""Delete an instance from the list and from the filesystem."""
117
if self.__instances.has_key(id):
118
del self.__instances[id]
121
os.remove(self.path + id + '.ini')
124
print "Temporary file didn't exist - nothing to remove."
126
print "CachingBackend: <#" + id + "> removed!"
130
"""Immediately save all pending data."""
133
def save_option (self, id, name, value):
134
"""Save option for an instance to cache and start saving-timeout
135
for that element (value must be of type string)."""
136
# create key for option, if not existent yet
137
if self.__instances.has_key(id) == False:
138
self.__instances[id] = {}
139
# set option in array
140
self.__instances[id][name] = str(value)
141
#print "CachingBackend.save_option: "+name+"="+self.__instances[id][name]
142
# if id is not already in queue, add the id to the queue
143
if self.__queue.count(id) == 0:
144
self.__queue.append(id)
145
# reset timeout and start new
147
gobject.source_remove(self.__timeout)
148
self.__timeout = gobject.timeout_add(self.__delay_time,
149
self.__save_cache)#, id)
151
def load_option (self, id, name):
152
"""TODO: Load option from the backend (returned as str)."""
153
return self.__instances[id][name]
155
def load_instance (self, id):
156
"""Load all options for the instance with the given id."""
157
#print "Load element: "+id
158
if self.__instances.has_key(id):
159
return self.__instances[id]
162
def __load_cache (self):
163
"""Load all cached files from path."""
165
print "CachingBackend: Loading instances from cache"
166
# get dir content of self.path
168
dirlst = glob.glob(dirname + '*')
172
dname = fname[tdlen:]
173
if dname.endswith('.ini'):
175
print "CachingBackend: Loading <"+id+">"
177
if self.__instances.has_key(id) == False:
178
self.__instances[id] = {}
182
lines = f.readlines()
183
# read all options for this element from file
185
#print "LOAD: "+line[:-1]
186
parts = line[:-1].split('=', 1)
188
self.__instances[id][parts[0]] = parts[1]
190
except Exception, ex:
191
print "Error while loading options: " + str(ex)
193
def __save_cache (self):
194
"""Save the cache (for all pending instances in queue) to self.path."""
195
# loop through all instances in queue:
196
for id in self.__queue:
197
# if element with id not exists, remove it and break
198
if self.__instances.has_key(id) == False:
199
print "Queue-element <"+id+"> not found (already removed?)!"
200
self.__queue.remove(id)
202
# create list with options
203
print "CachingBackend: Saving <#"+id+"> :) ..."
205
for oname in self.__instances[id]:
206
lst.append([oname, self.__instances[id][oname]])
207
# and save them (if any)
210
f = open(self.path + id + '.ini', 'w')
212
f.write(el[0] + '=' + el[1] + "\n")
216
print "error while saving config: "+self.path+oname
219
# NOT continue the timeout-function (!!!!!)