~ubuntu-branches/debian/lenny/screenlets/lenny

« back to all changes in this revision

Viewing changes to src/lib/backend.py

  • Committer: Bazaar Package Importer
  • Author(s): Julien Lavergne
  • Date: 2007-10-19 16:52:50 UTC
  • Revision ID: james.westby@ubuntu.com-20071019165250-rzvyfmphfsbl6kip
Tags: upstream-0.0.10
ImportĀ upstreamĀ versionĀ 0.0.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
# screenlets.backend (c) RYX (aka Rico Pfaus) 2007 <ryx@ryxperience.com>
 
4
#
 
5
# INFO:
 
6
# - The backend offers an abstracted way of saving a Screenlet's data
 
7
#
 
8
# TODO: 
 
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).
 
11
#
 
12
 
 
13
import glob
 
14
import os
 
15
import gobject
 
16
 
 
17
 
 
18
try:
 
19
        import gconf
 
20
except:
 
21
        print "GConf python module not found. GConf settings backend is disabled."
 
22
 
 
23
 
 
24
class ScreenletsBackend:
 
25
        """The backend performs the loading/saving of the 'key=value'-strings. 
 
26
        Extend this superclass to implement different saving-backends."""
 
27
        
 
28
        def __init__ (self):
 
29
                pass
 
30
        
 
31
        def delete_instance (self, id):
 
32
                """Delete an instance's configuration by its id."""
 
33
                pass
 
34
        
 
35
        def flush (self):
 
36
                """Immediately store all values to disk (in case the backend doesn't
 
37
                save in realtime anyway."""
 
38
                pass
 
39
        
 
40
        def load_option (self, id, name):
 
41
                """Load one option for the instance with the given id."""
 
42
                pass
 
43
        
 
44
        def load_instance (self, id):
 
45
                """Load all options for the instance with the given id."""
 
46
                pass
 
47
        
 
48
        def save_option (self, id, name, value):
 
49
                """Save one option for the instance with the given id."""
 
50
                pass
 
51
        
 
52
 
 
53
class GconfBackend:
 
54
        """Backend for storing settings in the GConf registry"""
 
55
        
 
56
        gconf_dir = '/apps/screenlets/'
 
57
        
 
58
        def __init__ (self):
 
59
                ScreenletsBackend.__init__(self)
 
60
                print 'GConfBackend: initializing'
 
61
                self.client = gconf.client_get_default()
 
62
        
 
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)
 
66
                return True
 
67
        
 
68
        def flush (self):
 
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
 
72
 
 
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)
 
76
        
 
77
        def load_instance (self, id):
 
78
                """Load all options for the instance with the given id."""
 
79
                keys = []
 
80
                vals = []
 
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))
 
86
                return None
 
87
        
 
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
 
92
 
 
93
 
 
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')."""
 
99
        
 
100
        # internals
 
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
 
105
        
 
106
        # attribs
 
107
        path = ''                               # the path to store the files
 
108
        
 
109
        # Constructor
 
110
        def __init__ (self, path):
 
111
                ScreenletsBackend.__init__(self)
 
112
                self.path = path
 
113
                self.__load_cache()
 
114
        
 
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]
 
119
                        try:
 
120
                                import os
 
121
                                os.remove(self.path + id + '.ini')
 
122
                        except Exception,ex:
 
123
                                print ex
 
124
                                print "Temporary file didn't exist - nothing to remove."
 
125
                                return False
 
126
                print "CachingBackend: <#" + id + "> removed!"
 
127
                return True
 
128
        
 
129
        def flush (self):
 
130
                """Immediately save all pending data."""
 
131
                self.__save_cache()
 
132
        
 
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
 
146
                if self.__timeout:
 
147
                        gobject.source_remove(self.__timeout)
 
148
                self.__timeout = gobject.timeout_add(self.__delay_time, 
 
149
                        self.__save_cache)#, id)
 
150
        
 
151
        def load_option (self, id, name):
 
152
                """TODO: Load option from the backend (returned as str)."""
 
153
                return self.__instances[id][name]
 
154
        
 
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]
 
160
                return None
 
161
 
 
162
        def __load_cache (self):
 
163
                """Load all cached files from path."""
 
164
                # perform saving
 
165
                print "CachingBackend: Loading instances from cache"
 
166
                # get dir content of self.path
 
167
                dirname = self.path
 
168
                dirlst = glob.glob(dirname + '*')
 
169
                tdlen = len(dirname)
 
170
                lst = []
 
171
                for fname in dirlst:
 
172
                        dname = fname[tdlen:]
 
173
                        if dname.endswith('.ini'):
 
174
                                id = dname[:-4]
 
175
                                print "CachingBackend: Loading <"+id+">"
 
176
                                #print "ID: "+id
 
177
                                if self.__instances.has_key(id) == False:
 
178
                                        self.__instances[id] = {}
 
179
                                # open file
 
180
                                try:
 
181
                                        f = open(fname, 'r')
 
182
                                        lines = f.readlines()
 
183
                                        # read all options for this element from file
 
184
                                        for line in lines:
 
185
                                                #print "LOAD: "+line[:-1]
 
186
                                                parts = line[:-1].split('=', 1)
 
187
                                                if len(parts) > 1:
 
188
                                                        self.__instances[id][parts[0]] = parts[1]
 
189
                                        f.close()
 
190
                                except Exception, ex:
 
191
                                        print "Error while loading options: " + str(ex)
 
192
        
 
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)
 
201
                                break
 
202
                        # create list with options
 
203
                        print "CachingBackend: Saving <#"+id+"> :) ..."
 
204
                        lst = []
 
205
                        for oname in self.__instances[id]:
 
206
                                lst.append([oname, self.__instances[id][oname]])
 
207
                        # and save them (if any)
 
208
                        if len(lst) > 0:
 
209
                                try:
 
210
                                        f = open(self.path + id + '.ini', 'w')
 
211
                                        for el in lst:
 
212
                                                f.write(el[0] + '=' + el[1] + "\n")
 
213
                                        f.close()
 
214
                                        print "OK"
 
215
                                except:
 
216
                                        print "error while saving config: "+self.path+oname
 
217
                # clear queue
 
218
                self.__queue = []
 
219
                # NOT continue the timeout-function (!!!!!)
 
220
                return False
 
221
 
 
222