zeitgeist team mailing list archive
-
zeitgeist team
-
Mailing list archive
-
Message #01164
[Merge] lp:~zeitgeist/zeitgeist/autoload-extensions into lp:zeitgeist
Mikkel Kamstrup Erlandsen has proposed merging lp:~zeitgeist/zeitgeist/autoload-extensions into lp:zeitgeist.
Requested reviews:
Zeitgeist Framework Team (zeitgeist)
Related bugs:
#592600 Autoload extensions
https://bugs.launchpad.net/bugs/592600
THis branch implements automatic loading of extensions found in the extensions/ directory. You can still override this via the ZEITGEIST_{DEFAULT,EXTRA}_EXTENSIONS envvars.
It also installs zeitgeist-daemon.pc which defines a 'extensiondir' variable 3rd party extension developers can use to detect the path in which to install extensions.
--
https://code.launchpad.net/~zeitgeist/zeitgeist/autoload-extensions/+merge/28236
Your team Zeitgeist Framework Team is requested to review the proposed merge of lp:~zeitgeist/zeitgeist/autoload-extensions into lp:zeitgeist.
=== modified file 'Makefile.am'
--- Makefile.am 2009-12-08 14:08:44 +0000
+++ Makefile.am 2010-06-22 19:59:23 +0000
@@ -16,7 +16,8 @@
COPYRIGHT \
NEWS \
zeitgeist-daemon.py \
- zeitgeist-datahub.py
+ zeitgeist-datahub.py \
+ zeitgeist-daemon.pc.in
DISTCLEANFILES = \
intltool-extract \
@@ -27,6 +28,9 @@
zeitgeist-daemon \
zeitgeist-datahub
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = zeitgeist-daemon.pc
+
zeitgeist-daemon: zeitgeist-daemon.py
sed \
-e "s!\/usr\/bin\/env python!$(PYTHON)!" \
=== modified file '_zeitgeist/Makefile.am'
--- _zeitgeist/Makefile.am 2010-05-16 15:34:50 +0000
+++ _zeitgeist/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,6 +1,6 @@
SUBDIRS = engine loggers
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/
+appdir = $(datadir)/zeitgeist/_zeitgeist/
app_PYTHON = \
__init__.py \
=== modified file '_zeitgeist/engine/Makefile.am'
--- _zeitgeist/engine/Makefile.am 2010-06-08 10:21:27 +0000
+++ _zeitgeist/engine/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,6 +1,6 @@
SUBDIRS = extensions upgrades
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/engine/
+appdir = $(datadir)/zeitgeist/_zeitgeist/engine/
app_PYTHON = \
__init__.py \
=== modified file '_zeitgeist/engine/__init__.py'
--- _zeitgeist/engine/__init__.py 2010-05-27 19:51:09 +0000
+++ _zeitgeist/engine/__init__.py 2010-06-22 19:59:23 +0000
@@ -42,31 +42,6 @@
import main # _zeitgeist.engine.main
_engine = main.ZeitgeistEngine()
return _engine
-
-def _get_extensions():
- """looks at the `ZEITGEIST_DEFAULT_EXTENSIONS` environment variable
- to find the extensions which should be loaded on daemon startup, if
- this variable is not set the `Blacklist` and the `DataSourceRegistry`
- extension will be loaded. If this variable is set to an empty string
- no extensions are loaded by default.
- To load an extra set of extensions define the `ZEITGEIST_EXTRA_EXTENSIONS`
- variable.
- The format of these variables should just be a no-space comma
- separated list of module.class names"""
- default_extensions = os.environ.get("ZEITGEIST_DEFAULT_EXTENSIONS", None)
- if default_extensions is not None:
- extensions = default_extensions.split(",")
- else:
- extensions = [
- "_zeitgeist.engine.extensions.blacklist.Blacklist",
- "_zeitgeist.engine.extensions.datasource_registry.DataSourceRegistry",
- ]
- extra_extensions = os.environ.get("ZEITGEIST_EXTRA_EXTENSIONS", None)
- if extra_extensions is not None:
- extensions += extra_extensions.split(",")
- extensions = filter(None, extensions)
- log.debug("daemon is configured to run with these extensions: %r" %extensions)
- return extensions
class _Constants:
# Directories
@@ -79,9 +54,6 @@
DBUS_INTERFACE = ZeitgeistDBusInterface.INTERFACE_NAME
SIG_EVENT = "asaasay"
- # Extensions
- DEFAULT_EXTENSIONS = _get_extensions()
-
# Required version of DB schema
CORE_SCHEMA="core"
CORE_SCHEMA_VERSION = 1
=== modified file '_zeitgeist/engine/extension.py'
--- _zeitgeist/engine/extension.py 2010-04-01 20:10:36 +0000
+++ _zeitgeist/engine/extension.py 2010-06-22 19:59:23 +0000
@@ -3,6 +3,7 @@
# Zeitgeist
#
# Copyright © 2009 Markus Korn <thekorn@xxxxxx>
+# Copyright © 2010 Mikkel Kamstrup Erlandsen <mikkel.kamstrup@xxxxxxxxx>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -17,12 +18,15 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import os
import logging
import weakref # avoid circular references as they confuse garbage collection
logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger("zeitgeist.extension")
+import zeitgeist
+
def safe_issubclass(obj, cls):
try:
return issubclass(obj, cls)
@@ -87,7 +91,48 @@
"""
return event
-def load_class(path):
+def get_extensions():
+ """looks at the `ZEITGEIST_DEFAULT_EXTENSIONS` environment variable
+ to find the extensions which should be loaded on daemon startup, if
+ this variable is not set the "extensiondir" variable of the configuration
+ will be scanned for .py files with classes extending Extension
+ If this variable is set to an empty string no extensions are loaded by
+ default.
+ To load an extra set of extensions define the `ZEITGEIST_EXTRA_EXTENSIONS`
+ variable.
+ The format of these variables should just be a no-space comma
+ separated list of module.class names"""
+ default_extensions = os.environ.get("ZEITGEIST_DEFAULT_EXTENSIONS", None)
+ if default_extensions is not None:
+ extensions = map(_load_class, default_extensions.split(","))
+ else:
+ extensions = _scan_extensions ()
+ extra_extensions = os.environ.get("ZEITGEIST_EXTRA_EXTENSIONS", None)
+ if extra_extensions is not None:
+ extensions += map(_load_class, extra_extensions.split(","))
+ extensions = filter(None, extensions)
+ log.debug("daemon is configured to run with these extensions: %r" %extensions)
+ return extensions
+
+def _scan_extensions():
+ """Look in zeitgeist._config.extensiondir for .py files and return
+ a list of classes with all the classes that extends the Extension class"""
+ config = zeitgeist._config
+ log.debug("Searching for extensions in: %s" % config.extensiondir)
+ extensions = []
+ modules = filter(lambda m : m.endswith(".py"), os.listdir(config.extensiondir))
+ modules = map(lambda m : m.rpartition(".")[0], modules)
+ for mod in modules:
+ _zg = __import__ ("_zeitgeist.engine.extensions." + mod)
+ ext = getattr(_zg.engine.extensions, mod)
+ for cls in dir(ext):
+ cls = getattr(ext, cls)
+ if safe_issubclass(cls, Extension) and not cls is Extension:
+ extensions.append(cls)
+ return extensions
+
+
+def _load_class(path):
"""
Load and return a class from a fully qualified string.
Fx. "_zeitgeist.engine.extensions.myext.MyClass"
=== modified file '_zeitgeist/engine/extensions/Makefile.am'
--- _zeitgeist/engine/extensions/Makefile.am 2010-01-21 00:42:48 +0000
+++ _zeitgeist/engine/extensions/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,4 +1,4 @@
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/engine/extensions
+appdir = $(datadir)/zeitgeist/_zeitgeist/engine/extensions
app_PYTHON = \
__init__.py \
=== modified file '_zeitgeist/engine/main.py'
--- _zeitgeist/engine/main.py 2010-05-14 17:16:49 +0000
+++ _zeitgeist/engine/main.py 2010-06-22 19:59:23 +0000
@@ -34,7 +34,7 @@
from zeitgeist.datamodel import Event as OrigEvent, StorageState, TimeRange, \
ResultType, get_timestamp_for_now, Interpretation, Symbol, NEGATION_OPERATOR, WILDCARD
from _zeitgeist.engine.datamodel import Event, Subject
-from _zeitgeist.engine.extension import ExtensionsCollection, load_class
+from _zeitgeist.engine.extension import ExtensionsCollection, get_extensions
from _zeitgeist.engine import constants
from _zeitgeist.engine.sql import get_default_cursor, unset_cursor, \
TableLookup, WhereClause
@@ -116,9 +116,9 @@
raise RuntimeError("old database version")
# Load extensions
- default_extensions = map(load_class, constants.DEFAULT_EXTENSIONS)
+ default_extensions = get_extensions()
self.__extensions = ExtensionsCollection(self,
- defaults=default_extensions)
+ defaults=default_extensions)
self._interpretation = TableLookup(cursor, "interpretation")
self._manifestation = TableLookup(cursor, "manifestation")
=== modified file '_zeitgeist/engine/upgrades/Makefile.am'
--- _zeitgeist/engine/upgrades/Makefile.am 2010-06-08 10:21:27 +0000
+++ _zeitgeist/engine/upgrades/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,4 +1,4 @@
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/engine/upgrades
+appdir = $(datadir)/zeitgeist/_zeitgeist/engine/upgrades
app_PYTHON = \
__init__.py \
=== modified file '_zeitgeist/loggers/Makefile.am'
--- _zeitgeist/loggers/Makefile.am 2009-07-11 23:20:37 +0000
+++ _zeitgeist/loggers/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,6 +1,6 @@
SUBDIRS = datasources
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/loggers/
+appdir = $(datadir)/zeitgeist/_zeitgeist/loggers/
app_PYTHON = \
__init__.py \
=== modified file '_zeitgeist/loggers/datasources/Makefile.am'
--- _zeitgeist/loggers/datasources/Makefile.am 2009-11-25 17:01:07 +0000
+++ _zeitgeist/loggers/datasources/Makefile.am 2010-06-22 19:59:23 +0000
@@ -1,4 +1,4 @@
-appdir = $(prefix)/share/zeitgeist/_zeitgeist/loggers/datasources
+appdir = $(datadir)/zeitgeist/_zeitgeist/loggers/datasources
app_PYTHON = \
__init__.py \
=== added file 'acinclude.m4'
--- acinclude.m4 1970-01-01 00:00:00 +0000
+++ acinclude.m4 2010-06-22 19:59:23 +0000
@@ -0,0 +1,40 @@
+dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
+dnl
+dnl example
+dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
+dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
+
+AC_DEFUN([AS_AC_EXPAND],
+[
+ EXP_VAR=[$1]
+ FROM_VAR=[$2]
+
+ dnl first expand prefix and exec_prefix if necessary
+ prefix_save=$prefix
+ exec_prefix_save=$exec_prefix
+
+ dnl if no prefix given, then use /usr/local, the default prefix
+ if test "x$prefix" = "xNONE"; then
+ prefix=$ac_default_prefix
+ fi
+ dnl if no exec_prefix given, then use prefix
+ if test "x$exec_prefix" = "xNONE"; then
+ exec_prefix=$prefix
+ fi
+
+ full_var="$FROM_VAR"
+ dnl loop until it doesn't change anymore
+ while true; do
+ new_full_var="`eval echo $full_var`"
+ if test "x$new_full_var"="x$full_var"; then break; fi
+ full_var=$new_full_var
+ done
+
+ dnl clean up
+ full_var=$new_full_var
+ AC_SUBST([$1], "$full_var")
+
+ dnl restore prefix and exec_prefix
+ prefix=$prefix_save
+ exec_prefix=$exec_prefix_save
+])
=== modified file 'configure.ac'
--- configure.ac 2010-06-21 10:22:38 +0000
+++ configure.ac 2010-06-22 19:59:23 +0000
@@ -13,12 +13,17 @@
AM_GLIB_GNU_GETTEXT
IT_PROG_INTLTOOL([0.35.0])
+# Expand variables needed for config.py
+AS_AC_EXPAND(DATADIR, $datarootdir)
+AC_SUBST(DATADIR)
+
AC_CONFIG_FILES([
Makefile
doc/Makefile
extra/Makefile
extra/ontology/Makefile
po/Makefile.in
+ zeitgeist-daemon.pc
zeitgeist/Makefile
_zeitgeist/Makefile
_zeitgeist/loggers/Makefile
=== added file 'zeitgeist-daemon.pc.in'
--- zeitgeist-daemon.pc.in 1970-01-01 00:00:00 +0000
+++ zeitgeist-daemon.pc.in 2010-06-22 19:59:23 +0000
@@ -0,0 +1,7 @@
+prefix=@prefix@
+extensiondir=@datadir@/zeitgeist/_zeitgeist/engine/extensions
+
+Name: @PACKAGE_NAME@
+Description: Zeitgeist Engine Extensions
+Version: @PACKAGE_VERSION@
+
=== modified file 'zeitgeist/__init__.py'
--- zeitgeist/__init__.py 2009-12-31 23:12:25 +0000
+++ zeitgeist/__init__.py 2010-06-22 19:59:23 +0000
@@ -23,6 +23,7 @@
pkgdatadir = os.path.join(bindir, "data")
privatepythondir = bindir
datasourcedir = os.path.join(bindir, "_zeitgeist/loggers/datasources")
+ extensiondir = os.path.join(bindir, "_zeitgeist/engine/extensions")
libdir = ""
libexecdir = ""
PACKAGE = "zeitgeist"
=== modified file 'zeitgeist/_config.py.in'
--- zeitgeist/_config.py.in 2009-12-30 19:03:24 +0000
+++ zeitgeist/_config.py.in 2010-06-22 19:59:23 +0000
@@ -4,7 +4,8 @@
localedir = "@datadir@/locale"
pkgdatadir = "@pkgdatadir@"
privatepythondir = "@prefix@/share/zeitgeist"
-datasourcedir = "@prefix@/share/zeitgeist/_zeitgeist/loggers/datasources"
+datasourcedir = "@datadir@/zeitgeist/_zeitgeist/loggers/datasources"
+extensiondir = "@datadir@/zeitgeist/_zeitgeist/engine/extensions"
libdir = "@libdir@"
libexecdir = "@libexecdir@"
PACKAGE = "@PACKAGE@"