diff --git a/portail_citoyen2/models.py b/portail_citoyen2/models.py index 7dcfad9..e48fd77 100644 --- a/portail_citoyen2/models.py +++ b/portail_citoyen2/models.py @@ -4,6 +4,10 @@ from django.db.models.signals import class_prepared MAX_USERNAME_LENGTH = 255 +from . import plugins + +plugins.init() + def longer_username_signal(sender, *args, **kwargs): if (sender.__name__ == "User" and sender.__module__ == "django.contrib.auth.models"): diff --git a/portail_citoyen2/plugins.py b/portail_citoyen2/plugins.py new file mode 100644 index 0000000..286bd1e --- /dev/null +++ b/portail_citoyen2/plugins.py @@ -0,0 +1,59 @@ +from pkg_resources import iter_entry_points +import logging + +from django.conf.urls import patterns, include, url + +logger = logging.getLogger(__name__) + +PLUGIN_GROUP_NAME = 'portail_citoyen2.plugin' + +class PluginError(Exception): + pass + +def get_plugins(*args, **kwargs): + plugins = [] + for entrypoint in iter_entry_points(PLUGIN_GROUP_NAME): + try: + plugin = entrypoint.load() + except Exception, e: + logger.exception('failed to load entrypoint %s', entrypoint) + raise PluginError('failed to load entrypoint %s' % entrypoint) + plugins.append(plugin(*args, **kwargs)) + return plugins + +def register_plugins_urls(urlpatterns): + pre_urls = [] + post_urls = [] + for plugin in get_plugins(): + if hasattr(plugin, 'get_before_urls'): + pre_urls.append(url('^', include(plugin.get_before_urls()))) + if hasattr(plugin, 'get_after_urls'): + post_urls.append(url('^', include(plugin.get_after_urls()))) + pre_patterns = patterns('', *pre_urls) + post_patterns = patterns('', *post_urls) + return pre_patterns + urlpatterns + post_patterns + +def register_plugins_apps(installed_apps): + for plugin in get_plugins(): + if hasattr(plugin, 'get_apps'): + apps = plugin.get_apps() + for app in apps: + if app not in installed_apps: + installed_apps += (app, ) + return installed_apps + +def register_plugins_middleware(middlewares): + for plugin in get_plugins(): + if hasattr(plugin, 'get_before_middleware'): + pre_middleware = plugin.get_before_middleware() + middlewares = tuple(set(pre_middleware + middlewares)) + if hasattr(plugin, 'get_after_middleware'): + post_middleware = plugin.get_after_middleware() + middlewares = tuple(set(post_middleware + middlewares)) + return middlewares + +def init(): + for plugin in get_plugins(): + if hasattr(plugin, 'init'): + plugin.init() + diff --git a/portail_citoyen2/settings.py b/portail_citoyen2/settings.py index 0619ed8..f916961 100644 --- a/portail_citoyen2/settings.py +++ b/portail_citoyen2/settings.py @@ -3,6 +3,8 @@ from django.core.exceptions import ImproperlyConfigured import os import logging.handlers +from . import plugins + gettext_noop = lambda s: s # Python dotted path to the WSGI application used by Django's runserver. WSGI_APPLICATION = 'portail_citoyen2.wsgi.application' @@ -105,6 +107,8 @@ MIDDLEWARE_CLASSES = ( 'entrouvert.djommon.middleware.VersionMiddleware', ) +MIDDLEWARE_CLASSES = plugins.register_plugins_middleware(MIDDLEWARE_CLASSES) + ROOT_URLCONF = 'portail_citoyen2.urls' INSTALLED_APPS = ( @@ -136,6 +140,8 @@ INSTALLED_APPS = ( 'portail_citoyen2', ) +INSTALLED_APPS = plugins.register_plugins_apps(INSTALLED_APPS) + try: import cmsplugin_blurp INSTALLED_APPS += ( diff --git a/portail_citoyen2/urls.py b/portail_citoyen2/urls.py index 57204f8..12d47ae 100644 --- a/portail_citoyen2/urls.py +++ b/portail_citoyen2/urls.py @@ -2,7 +2,7 @@ from django.conf.urls import patterns, include, url from django.contrib import admin from django.conf import settings -from . import views +from . import views, plugins admin.autodiscover() @@ -31,3 +31,4 @@ urlpatterns += patterns('', url(r'^', include('cms.urls')), ) +urlpatterns = plugins.register_plugins_urls(urlpatterns)