# -*- coding: utf-8 -*- import string import inspect import re """ This interface provides a simple way to declare and store parameters in Modoboa's database. Core components or extensions can register their own parameters, which will be available and modifiable directly from the web interface. Only super users will be able to access this part of the web interface. """ _params = {} _params_order = {} _levels = {'A' : 'admin', 'U' : 'user'} class NotDefined(Exception): def __init__(self, app, name): self.app = app self.name = name def __str__(self): return "Application '%s' and/or parameter '%s' not defined" \ % (self.app, self.name) def register_app(app=None, aparams_opts=None, uparams_opts=None): """Manually register an application You don't need to call this function unless you want to provide specific options for your application parameters. For example, you can indicate that user-level parameters are only accessible for users that own a mailbox. :param app: the application's name :param aparams_opts: a dict containing options applicable to admin-level params :param uparams_opts: a dict containing options applicable to user-level params """ if app is None: app = __guess_extension() if _params.has_key(app): return _params[app] = {} _params[app]['options'] = {} _params_order[app] = {} for lvl in _levels.keys(): _params[app][lvl] = {} _params_order[app][lvl] = [] if aparams_opts: _params[app]['options']['A'] = aparams_opts if uparams_opts: _params[app]['options']['U'] = uparams_opts def unregister_app(app): """Unregister an application All parameters associated to this application will also be removed. :param app: the application's name (string) """ if not _params.has_key(app): return False del _params[app] return True def __is_defined(app, level, name): if not level in _levels.keys() \ or not app in _params.keys() \ or not name in _params[app][level].keys(): raise NotDefined(app, name) def __register(app, level, name, **kwargs): """Register a new parameter. ``app`` corresponds to a core component (admin, main) or to an extension. :param name: the application's name :param level: the level this parameter is available from :param name: the parameter's name """ if not app in _params.keys(): register_app(app) if not level in _levels.keys(): return if _params[app][level].has_key(name): return _params[app][level][name] = {} _params_order[app][level] += [name] for k, v in kwargs.iteritems(): _params[app][level][name][k] = v def __update(app, level, name, **kwargs): """Update a parameter's definition :param app: the application's name :param level: the level this parameter is available from :param name: the parameter's name """ if not app in _params.keys() or not level in _levels.keys() \ or not _params[app][level].has_key(name): return for k, v in kwargs.iteritems(): _params[app][level][name][k] = v def __guess_extension(): """Tries to guess the application's name by inspecting the stack :return: a string or None """ modname = inspect.getmodule(inspect.stack()[2][0]).__name__ m = re.match("(?:modoboa\.)?(?:extensions\.)?([^\.$]+)", modname) if m: return m.group(1) return None def register_admin(name, **kwargs): """Register a new parameter (admin level) Each parameter is associated to one application. If no application is provided, the function tries to guess the appropriate one. :param name: the parameter's name """ if kwargs.has_key("app"): app = kwargs["app"] del kwargs["app"] else: app = __guess_extension() return __register(app, 'A', name, **kwargs) def update_admin(name, **kwargs): """Update a parameter's definition (admin level) Each parameter is associated to one application. If no application is provided, the function tries to guess the appropriate one. :param name: the parameter's name """ if kwargs.has_key("app"): app = kwargs["app"] del kwargs["app"] else: app = __guess_extension() return __update(app, 'A', name, **kwargs) def register_user(name, **kwargs): """Register a new user-level parameter :param name: the parameter's name """ if kwargs.has_key("app"): app = kwargs["app"] del kwargs["app"] else: app = __guess_extension() return __register(app, 'U', name, **kwargs) def save_admin(name, value, app=None): from models import Parameter if app is None: app = __guess_extension() __is_defined(app, 'A', name) fullname = "%s.%s" % (app, name) try: p = Parameter.objects.get(name=fullname) except Parameter.DoesNotExist: p = Parameter() p.name = fullname if p.value != value: p.value = value.encode("unicode_escape").strip() p.save() return True def save_user(user, name, value, app=None): from models import UserParameter if app is None: app = __guess_extension() __is_defined(app, 'U', name) fullname = "%s.%s" % (app, name) try: p = UserParameter.objects.get(user=user, name=fullname) except UserParameter.DoesNotExist: p = UserParameter() p.user = user p.name = fullname if p.value != value: p.value = value.encode("unicode_escape").strip() p.save() return True def get_admin(name, app=None): from models import Parameter if app is None: app = __guess_extension() __is_defined(app, "A", name) try: p = Parameter.objects.get(name="%s.%s" % (app, name)) except Parameter.DoesNotExist: return _params[app]["A"][name]["deflt"] return p.value.decode("unicode_escape") def get_user(user, name, app=None): from models import UserParameter if app is None: app = __guess_extension() __is_defined(app, "U", name) try: p = UserParameter.objects.get(user=user, name="%s.%s" % (app, name)) except UserParameter.DoesNotExist: return _params[app]["U"][name]["deflt"] return p.value.decode("unicode_escape") def get_app_option(lvl, name, dflt, app=None): if app is None: app = __guess_extension() if not lvl in _params[app]['options']: return dflt if not _params[app]['options'][lvl].has_key(name): return dflt return _params[app]['options'][lvl][name]