From 840f426dc64e9fb9bf97b70a2a93743acd0b8f4d Mon Sep 17 00:00:00 2001 From: Wannes Rombouts <wapiflapi@yahoo.fr> Date: Thu, 6 Jun 2013 15:21:39 +0200 Subject: [PATCH] First draft, config files are updated, basic plugin handling is in place, but we still need to define the hooks. --- plugins/__init__.py | 38 +++++++++++++++++++++++++ src/extensions.py | 68 +++++++++++++++++++++++++++++++++++++++++++++ src/mra.yaml.sample | 10 +++++++ src/mralogs.py | 10 ++++++- src/server.py | 8 +++++- 5 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 plugins/__init__.py create mode 100644 src/extensions.py diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 0000000..347ed97 --- /dev/null +++ b/plugins/__init__.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python2.7 +# -*- coding: utf-8 -*- + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # +# MapServer REST API is a python wrapper around MapServer which # +# allows to manipulate a mapfile in a RESTFul way. It has been # +# developped to match as close as possible the way the GeoServer # +# REST API acts. # +# # +# Copyright (C) 2011-2013 Neogeo Technologies. # +# # +# This file is part of MapServer Rest API. # +# # +# MapServer Rest API is free software: you can redistribute it # +# and/or modify it under the terms of the GNU General Public License # +# as published by the Free Software Foundation, either version 3 of # +# the License, or (at your option) any later version. # +# # +# MapServer Rest API is distributed in the hope that it will be # +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +# This package is used for easy management of plugins. Just drop them in +# this folder and they will automatically be loaded if this folder is +# present in the mra.yaml configuration under plugins/loadpaths + +import os, os.path + +__all__ = [] +for module in os.listdir(os.path.dirname(__file__)): + name, ext = os.path.splitext(module) + if name != "__init__" and ext in ["", ".py"]: + __all__.append(name) + diff --git a/src/extensions.py b/src/extensions.py new file mode 100644 index 0000000..562f251 --- /dev/null +++ b/src/extensions.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python2.7 +# -*- coding: utf-8 -*- + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# # +# MapServer REST API is a python wrapper around MapServer which # +# allows to manipulate a mapfile in a RESTFul way. It has been # +# developped to match as close as possible the way the GeoServer # +# REST API acts. # +# # +# Copyright (C) 2011-2013 Neogeo Technologies. # +# # +# This file is part of MapServer Rest API. # +# # +# MapServer Rest API is free software: you can redistribute it # +# and/or modify it under the terms of the GNU General Public License # +# as published by the Free Software Foundation, either version 3 of # +# the License, or (at your option) any later version. # +# # +# MapServer Rest API is distributed in the hope that it will be # +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty # +# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +import sys +import os.path +import logging + +class ExtensionManager(object): + + def __init__(self, ): + self.extentions = {} + + def load_plugins(self, pkg_name): + sys.path.append(__file__) + __import__(pkg_name, globals(), locals(), ["*"]) + sys.path.remove(__file__) + + def load_plugins_dir(self, dir_path): + path, pkg = os.path.split(os.path.abspath(dir_path)) + pkg, _ = os.path.splitext(pkg) + print "Loading %s from %s" % (pkg, path) + + sys.path.append(path) + try: + self.load_plugins(pkg) + except ImportError: + logging.error("Could not load plugin package '%s' from %s" % (pkg, path)) + else: + logging.info("Loaded plugin package '%s' from %s" % (pkg, path)) + sys.path.remove(path) + + def extend(self, name, *args, **kwargs): + for f in self.extentions.get(name, []): + f(*args, **kwargs) + + def register(self, name, f=None): + if f == None: + def decorator(f): + self.register(name, f) + return f + return decorator + + self.extentions.setdefault(name, []).append(f) + +plugins = ExtensionManager() diff --git a/src/mra.yaml.sample b/src/mra.yaml.sample index cd7c43e..c984464 100644 --- a/src/mra.yaml.sample +++ b/src/mra.yaml.sample @@ -27,3 +27,13 @@ testing: active: False # Which map file to use to create new test files. model: model + +plugins: + # The paths in this lists will be loaded as plugins. + # A plugin can be a python package, if that is the case it + # should define the __all__ attribute to indicate which modules + # should be handled as plugins. (An example can be found in /plugins) + + loadpaths: [ +# "/path/to/your/plugins" + ] diff --git a/src/mralogs.py b/src/mralogs.py index 0614301..98580c9 100644 --- a/src/mralogs.py +++ b/src/mralogs.py @@ -24,6 +24,7 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +import sys import string import inspect import logging @@ -31,7 +32,14 @@ import functools def setup(log_level, log_file=None, format="%(asctime)s %(levelname)7s: %(message)s"): log_level = getattr(logging, log_level.upper()) - logging.basicConfig(filename=log_file, format=format, level=log_level) + + if log_file: + logging.basicConfig(filename=log_file, format=format, level=log_level) + + sh = logging.StreamHandler(sys.stderr) + sh.setLevel(log_level) + sh.setFormatter(logging.Formatter(format)) + logging.getLogger().addHandler(sh) class Reccord(logging.Handler): """A logging.Handler class which stores the records. diff --git a/src/server.py b/src/server.py index 3338899..cd472c5 100755 --- a/src/server.py +++ b/src/server.py @@ -24,6 +24,8 @@ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +import os.path + import web import json import urlparse @@ -41,7 +43,8 @@ from tools import get_mapfile, get_mapfile_workspace, get_config, href from pyxml import Entries -import os.path + +from extensions import plugins mralogs.setup(get_config("logging")["level"], get_config("logging")["file"], get_config("logging")["format"]) @@ -991,6 +994,9 @@ web.config.debug = get_config("debug").get("web_debug", False) webapp.exceptionManager.raise_all = get_config("debug").get("raise_all", False) HTTPCompatible.return_logs = get_config("logging").get("web_logs", False) +for pdir in get_config("plugins").get("loadpaths", []): + plugins.load_plugins_dir(pdir) + app = web.application(urls, globals()) if __name__ == "__main__": -- GitLab