~ubuntu-branches/ubuntu/quantal/zeitgeist/quantal

« back to all changes in this revision

Viewing changes to _zeitgeist/engine/extension.py

  • Committer: Bazaar Package Importer
  • Author(s): Siegfried-Angel Gevatter Pujals
  • Date: 2011-01-22 14:15:38 UTC
  • mfrom: (1.1.7 upstream) (6.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20110122141538-8poh0211pn8uv1xc
Tags: 0.7-1
* New upstream release. Some of the changes are:
   - Various performance improvements (speed, reduced I/O, etc).
   - Enhancements to the extensions system (eg. feature to ask which
     extensions are active).
   - Various bug fixes (eg. fixed find_event_for_template Python API method).
   - Added new mimetype mappings.
* Updated debian/copyright and debian/zeitgeist-core.install.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
#
8
8
# This program is free software: you can redistribute it and/or modify
9
9
# it under the terms of the GNU Lesser General Public License as published by
10
 
# the Free Software Foundation, either version 3 of the License, or
 
10
# the Free Software Foundation, either version 2.1 of the License, or
11
11
# (at your option) any later version.
12
12
#
13
13
# This program is distributed in the hope that it will be useful,
22
22
import logging
23
23
import weakref # avoid circular references as they confuse garbage collection
24
24
 
25
 
logging.basicConfig(level=logging.DEBUG)
26
25
log = logging.getLogger("zeitgeist.extension")
27
26
 
28
27
import zeitgeist
33
32
                return issubclass(obj, cls)
34
33
        except TypeError:
35
34
                return False
 
35
                
 
36
def get_extension_name(extension):
 
37
        """ We are using the name of the Extension-class as extension's unique
 
38
        name, later we might want to prepend modul or package names.
 
39
        """
 
40
        if safe_issubclass(extension, Extension):
 
41
                return extension.__name__
 
42
        elif isinstance(extension, Extension):
 
43
                return extension.__class__.__name__
 
44
        else:
 
45
                raise TypeError(
 
46
                        "Can't identify %r, an extension has to be a subclass or "
 
47
                        "instance of extension.Extension" %extension)
36
48
 
37
49
class Extension(object):
38
50
        """ Base class for all extensions
45
57
        inserted and retrieved from the log. These hooks can either block the
46
58
        event completely, modify it, or add additional metadata to it.
47
59
        """
48
 
        PUBLIC_METHODS = None
 
60
        PUBLIC_METHODS = []
49
61
        
50
62
        def __init__(self, engine):
51
63
                self.engine = weakref.proxy(engine)
52
64
        
 
65
        def unload(self):
 
66
                """
 
67
                This method gets called before Zeitgeist stops.
 
68
                
 
69
                Execution of this method isn't guaranteed, and you shouldn't do
 
70
                anything slow in there.
 
71
                """
 
72
                pass
 
73
        
53
74
        def pre_insert_event(self, event, sender):
54
75
                """
55
76
                Hook applied to all events before they are inserted into the
162
183
        
163
184
        # Find system extensions
164
185
        log.debug("Searching for system extensions in: %s" % config.extensiondir)
165
 
        sys_modules = filter(lambda m : m.endswith(".py"), os.listdir(config.extensiondir))
166
 
        sys_modules = modules = map(lambda m : "_zeitgeist.engine.extensions." + m.rpartition(".")[0], sys_modules)
 
186
        sys_modules = filter(lambda m: m.endswith(".py"), os.listdir(config.extensiondir))
 
187
        sys_modules = map(lambda m: "_zeitgeist.engine.extensions." + m.rpartition(".")[0], sys_modules)
167
188
        
168
189
        # Find user extensions
169
190
        log.debug("Searching for user extensions in: %s" % constants.USER_EXTENSION_PATH)
170
191
        user_modules = []
171
192
        try:
172
 
                user_modules = filter(lambda m : m.endswith(".py"), os.listdir(os.path.expanduser(constants.USER_EXTENSION_PATH)))
173
 
                user_modules = map(lambda m : m.rpartition(".")[0], user_modules)
 
193
                user_modules = filter(lambda m: m.endswith(".py"), os.listdir(os.path.expanduser(constants.USER_EXTENSION_PATH)))
 
194
                user_modules = map(lambda m: m.rpartition(".")[0], user_modules)
174
195
        except OSError:
175
196
                pass # USER_EXTENSION_PATH doesn't exist
176
197
        
177
198
        # If we have module conflicts let the user extensions win,
178
199
        # and remove the system provided extension from our list
179
 
        user_module_names = map(lambda m : os.path.basename(m), user_modules)
 
200
        user_module_names = map(lambda m: os.path.basename(m), user_modules)
180
201
        for mod in list(sys_modules):
181
202
                mod_name = mod.rpartition(".")[2]
182
203
                if mod_name in user_module_names:
197
218
                        if safe_issubclass(cls, Extension) and not cls is Extension:
198
219
                                extensions.append(cls)
199
220
        return extensions
200
 
                        
201
221
 
202
222
def _load_class(path):
203
223
        """
236
256
                return "%s(%r)" %(self.__class__.__name__, sorted(self.__methods.keys()))
237
257
                        
238
258
        def load(self, extension):
239
 
                log.debug("Loading extension '%s'" % extension.__name__)
240
259
                if not issubclass(extension, Extension):
241
260
                        raise TypeError("Unable to load %r, all extensions must be "
242
261
                                "subclasses of %r" % (extension, Extension))
243
 
                if getattr(extension, "PUBLIC_METHODS", None) is None:
244
 
                        raise ValueError("Unable to load %r, this extension has not "
245
 
                                "defined any methods" % extension)
 
262
                ext_name = get_extension_name(extension)
 
263
                log.debug("Loading extension '%s'" %ext_name)
246
264
                try:
247
265
                        obj = extension(self.__engine)
248
266
                except Exception:
249
 
                        log.exception("Failed loading the '%s' extension" % extension.__name__)
 
267
                        log.exception("Failed loading the '%s' extension" %ext_name)
250
268
                        return False
251
269
 
252
270
                for method in obj.PUBLIC_METHODS:
253
271
                        self._register_method(method, getattr(obj, method))
254
 
                self.__extensions[obj.__class__.__name__] = obj
 
272
                self.__extensions[ext_name] = obj
255
273
                
256
274
        def unload(self, extension=None):
257
275
                """
265
283
                        
266
284
                        # We need to clone the key list to avoid concurrent
267
285
                        # modification of the extension dict
268
 
                        for ext_name in list(self.__extensions.iterkeys()):
269
 
                                self.unload(self.__extensions[ext_name])
 
286
                        for ext in list(self):
 
287
                                self.unload(ext)
270
288
                else:
271
 
                        log.debug("Unloading extension '%s'" \
272
 
                                          % extension.__class__.__name__)
273
 
                        if safe_issubclass(extension, Extension):
274
 
                                ext_name = extension.__name__
275
 
                        elif isinstance(extension, Extension):
276
 
                                ext_name = extension.__class__.__name__
277
 
                        else:
278
 
                                raise TypeError
 
289
                        ext_name = get_extension_name(extension)
 
290
                        log.debug("Unloading extension '%s'" % ext_name)
279
291
                        obj = self.__extensions[ext_name]
 
292
                        obj.unload()
280
293
                        for method in obj.PUBLIC_METHODS:
281
294
                                del self.methods[method]
282
295
                        del self.__extensions[ext_name]
348
361
        
349
362
        def __iter__(self):
350
363
                return self.__extensions.itervalues()
 
364
                
 
365
        def iter_names(self):
 
366
                return self.__extensions.iterkeys()