diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..347ed97107aa6f0e5001a30f3e1b70d7f8e9ddf8 --- /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 0000000000000000000000000000000000000000..562f25158ba32d80d0c780d6ba927f2419d1c6b9 --- /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 cd7c43ed95f32cc78fefcd4caf3ff73ddb7f2d69..c984464ab9f9464b2f68e2ad7142ca08bb374205 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 0614301db0b7b4b2f6133704988c6c95a8dc6971..98580c91fa46217ba1c2fcd6522e0acb4f300559 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 33388990818ce75f5c9034922c9ff72f47f08c53..cd472c51c70de0f814b9f0980fb581ccba7f516c 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__":