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.
13
13
# This program is distributed in the hope that it will be useful,
33
32
return issubclass(obj, cls)
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.
40
if safe_issubclass(extension, Extension):
41
return extension.__name__
42
elif isinstance(extension, Extension):
43
return extension.__class__.__name__
46
"Can't identify %r, an extension has to be a subclass or "
47
"instance of extension.Extension" %extension)
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.
50
62
def __init__(self, engine):
51
63
self.engine = weakref.proxy(engine)
67
This method gets called before Zeitgeist stops.
69
Execution of this method isn't guaranteed, and you shouldn't do
70
anything slow in there.
53
74
def pre_insert_event(self, event, sender):
55
76
Hook applied to all events before they are inserted into the
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)
168
189
# Find user extensions
169
190
log.debug("Searching for user extensions in: %s" % constants.USER_EXTENSION_PATH)
170
191
user_modules = []
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)
175
196
pass # USER_EXTENSION_PATH doesn't exist
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:
236
256
return "%s(%r)" %(self.__class__.__name__, sorted(self.__methods.keys()))
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)
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)
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
256
274
def unload(self, extension=None):
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):
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__
289
ext_name = get_extension_name(extension)
290
log.debug("Unloading extension '%s'" % ext_name)
279
291
obj = self.__extensions[ext_name]
280
293
for method in obj.PUBLIC_METHODS:
281
294
del self.methods[method]
282
295
del self.__extensions[ext_name]