diff options
author | Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> | 2011-03-13 17:53:43 +0000 |
---|---|---|
committer | Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> | 2011-03-13 17:53:43 +0000 |
commit | 11c54d423e6a95c35932e83f81f367469a96c378 (patch) | |
tree | 5cf16d31d598fafd8872de09715138686c5f6059 /pykolab/plugins | |
parent | 354522b3d14ff28c4d976aeab35cb8ac93906b5f (diff) | |
download | pykolab-11c54d423e6a95c35932e83f81f367469a96c378.tar.gz |
Redo plugins so they can be binary compiled
Diffstat (limited to 'pykolab/plugins')
-rw-r--r-- | pykolab/plugins/__init__.py | 264 | ||||
-rw-r--r-- | pykolab/plugins/defaultfolders/__init__.py | 44 | ||||
-rw-r--r-- | pykolab/plugins/dynamicquota/__init__.py | 69 | ||||
-rw-r--r-- | pykolab/plugins/recipientpolicy/__init__.py | 87 |
4 files changed, 464 insertions, 0 deletions
diff --git a/pykolab/plugins/__init__.py b/pykolab/plugins/__init__.py new file mode 100644 index 0000000..116b777 --- /dev/null +++ b/pykolab/plugins/__init__.py @@ -0,0 +1,264 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program 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; version 3 or, at your option, any later version +# +# This program 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 Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +import logging +import os +import pdb +import pykolab +import sys +import traceback + +if False: + import pykolab.plugins.defaultfolders + import pykolab.plugins.dynamicquota + import pykolab.plugins.recipientpolicy + +# Translation +from pykolab.translate import _ + +class KolabPlugins: + """ + Detects, loads and interfaces with plugins for different + Kolab components. + """ + def __init__(self, init=False, conf=None): + """ + Searches the plugin directory for plugins, and loads + them into a list. + """ + self.conf = conf + + self.log = logging.getLogger('pykolab.plugins') + + self.plugins = {} + + for plugin_path in [ '/usr/share/pykolab/plugins', './pykolab/plugins' ]: + if os.path.isdir(plugin_path): + for plugin in os.listdir(plugin_path): + if os.path.isdir('%s/%s/' %(plugin_path,plugin,)): + self.plugins[plugin] = False + + self.check_plugins(init=init) + + def check_plugins(self, init=False): + """ + Checks all plugins in self.plugins and sets the values to + True (loadable) or False -- not enabled, not installed or + not loadable. + """ + for plugin in self.plugins: + try: + exec("from pykolab.plugins import %s" %(plugin)) + self.plugins[plugin] = True + self.load_plugins(plugins=[plugin], init=init) + except ImportError, e: + if not init: print >> sys.stderr, _("ImportError for plugin %s: %s") % (plugin,e) + traceback.print_exc() + self.plugins[plugin] = False + except RuntimeError, e: + if not init: print >> sys.stderr, _("RuntimeError for plugin %s: %s") % (plugin,e) + traceback.print_exc() + self.plugins[plugin] = False + except Exception, e: + if not init: print >> sys.stderr, _("Plugin %s failed to load (%s: %s)") % (plugin, e.__class__, e) + traceback.print_exc() + except: + traceback.print_exc() + + def load_plugins(self, plugins=[], init=False): + """ + Loads plugins specified by a list of plugins or loads them all + """ + + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if self.plugins[plugin]: + try: + exec("self.%s = %s.Kolab%s(conf=self.conf)" % (plugin,plugin,plugin.capitalize())) + except: + # TODO: A little better verbosity please! + traceback.print_exc() + + def set_defaults(self, defaults, plugins=[]): + """ + Test for a function set_defaults() in all available and loaded plugins and execute plugin.set_defaults() + """ + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),"set_defaults"): + try: + getattr(self,plugin).set_defaults(defaults) + except TypeError, e: + print >> sys.stderr, _("Cannot set defaults for plugin %s: %s") % (plugin,e) + except RuntimeError, e: + print >> sys.stderr, _("Cannot set defaults for plugin %s: %s") % (plugin,e) + except: + print >> sys.stderr, _("Cannot set defaults for plugin %s: Unknown Error") % (plugin) + + else: + if hasattr(self.conf, "log"): + self.conf.log.debug(_("Not setting defaults for plugin %s: No function 'set_defaults()'") % plugin, level=5) + else: + print >> sys.stderr, _("Not setting defaults for plugin %s: No function 'set_defaults()'") % plugin + + def set_runtime(self, runtime, plugins=[]): + """ + Set runtime variables from plugins, like 'i_did_all_this' + """ + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),"set_runtime"): + try: + getattr(self,plugin).set_runtime(runtime) + except RuntimeError, e: + print >> sys.stderr, _("Cannot set runtime for plugin %s: %s") % (plugin,e) + else: + print >> sys.stderr, _("Not setting runtime for plugin %s: No function 'set_runtime()'") % plugin + + def add_options(self, parser, plugins=[]): + """ + Add options specified in a plugin to parser. Takes a list of plugin names or does them all + """ + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),"add_options"): + try: + exec("self.%s.add_options(parser)" % plugin) + except RuntimeError, e: + print >> sys.stderr, _("Cannot add options for plugin %s: %s") % (plugin,e) + else: + if hasattr(self.conf, "log"): + self.conf.log.debug(_("Not adding options for plugin %s: No function 'add_options()'") % plugin, level=5) + else: + print >> sys.stderr, _("Not adding options for plugin %s: No function 'add_options()'") % plugin + + def check_options(self, conf, plugins=[]): + """ + Executes plugin.check_plugins() for all enabled plugins or the list of plugin names specified. + """ + + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),"check_options"): + try: + exec("self.%s.check_options(conf, conf.cli_options)" % plugin) + except AttributeError, e: + print >> sys.stderr, _("Cannot check options for plugin %s: %s") % (plugin,e) + else: + print >> sys.stderr, _("Not checking options for plugin %s: No function 'check_options()'") % plugin + + def plugin_check_setting(self, func, option, val, plugins=[]): + """ + Checks one setting specified by 'option' against the 'val' it is passed by all plugins or by the list of plugins specified + """ + + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),"%s_%s" % (func,option)): + exec("retval = getattr(self,plugin).%s_%s(val)" % (func,option)) + return retval + + return False + + def exec_hook(self, hook, plugins=[], kw={}, args=()): + """Execute a hook""" + + if len(plugins) < 1: + plugins = self.plugins.keys() + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + retval = None + + if hasattr(getattr(self,plugin),hook): + try: + exec("retval = self.%s.%s(kw=%r, args=%r)" % (plugin,hook,kw,args)) + except TypeError, e: + print >> sys.stderr, _("Cannot execute hook %s for plugin %s: %s") % (hook,plugin,e) + except AttributeError, e: + print >> sys.stderr, _("Cannot execute hook %s for plugin %s: %s") % (hook,plugin,e) + + return retval + + + def return_true_boolean_from_plugins(self, bool, plugins=[]): + """Given the name of a boolean, walks all specified plugins, or all available plugins, and returns True if a plugin has it set to true""" + if len(plugins) < 1: + plugins = self.plugins.keys() + + retval = False + + for plugin in plugins: + if not self.plugins[plugin]: + continue + if not hasattr(self,plugin): + continue + + if hasattr(getattr(self,plugin),bool): + try: + exec("boolval = self.%s.%s" % (plugin,bool)) + except AttributeError, e: + pass + else: + boolval = None + + if boolval: retval = True + + return retval diff --git a/pykolab/plugins/defaultfolders/__init__.py b/pykolab/plugins/defaultfolders/__init__.py new file mode 100644 index 0000000..426b293 --- /dev/null +++ b/pykolab/plugins/defaultfolders/__init__.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program 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; version 3 or, at your option, any later version +# +# This program 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 Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +__all__ = [ + 'KolabDefaultfolders' + ] + +class KolabDefaultfolders(object): + """ + Example plugin to create a set of default folders. + """ + + def __init__(self, conf=None): + self.conf = conf + + def create_user_folders(self, kw={}, args=()): + """ + The arguments passed to the 'create_user_folders' hook: + + - imap connection + - user folder + """ + + (folder, additional_folders) = args + + exec("additional_folders = %s" %(additional_folders)) + + return additional_folders diff --git a/pykolab/plugins/dynamicquota/__init__.py b/pykolab/plugins/dynamicquota/__init__.py new file mode 100644 index 0000000..c91ebfc --- /dev/null +++ b/pykolab/plugins/dynamicquota/__init__.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program 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; version 3 or, at your option, any later version +# +# This program 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 Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +class KolabDynamicquota(object): + """ + Example plugin making quota adjustments given arbitrary conditions. + """ + + def __init__(self, conf=None): + self.conf = conf + + def set_user_folder_quota(self, kw={}, args=()): + """ + The arguments passed to the 'set_user_folder_quota' hook: + + - used (integer, in KB) + - current quota (integer, in KB) + - quota (integer, in KB) + """ + + #print args + + (used, current_quota, new_quota, default_quota) = args + + # Escape the user without quota + if new_quota == 0: + # Unless default quota is set + if default_quota > 0: + #print "new quota is 0, but default quota > 0, returning default quota" + return default_quota + + #print "new quota is 0, and default quota is no larger then 0, returning 0" + return 0 + + # Make your adjustments here, for example: + # + # - increase the quota by 10% if the currently used storage size + # is over 90% + + if new_quota < int(float(used) * 1.1): + #print "new quota is smaller then 110%% of what is currently used, returning 110%% of used" + new_quota = int(float(used) * 1.1) + elif new_quota > int(float(used) * 1.1): + # TODO: If the current quota in IMAP had been set to 0, but we want to apply quota, and + # 0 is current_quota, 90% of that is still 0... + #print "new quota is larger then 110%% of what is currently used, returning 90%% of current quota" + new_quota = int(float(current_quota) * 0.9) + + if default_quota > new_quota: + #print "default quota is more then the calculated new quota" + return default_quota + + return new_quota diff --git a/pykolab/plugins/recipientpolicy/__init__.py b/pykolab/plugins/recipientpolicy/__init__.py new file mode 100644 index 0000000..fbf0179 --- /dev/null +++ b/pykolab/plugins/recipientpolicy/__init__.py @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- +# Copyright 2010-2011 Kolab Systems AG (http://www.kolabsys.com) +# +# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com> +# +# This program 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; version 3 or, at your option, any later version +# +# This program 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 Library General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +from pykolab import utils +from pykolab.auth import Auth +from pykolab.translate import _ + +class KolabRecipientpolicy(object): + """ + Example plugin making quota adjustments given arbitrary conditions. + """ + + def __init__(self, conf=None): + self.conf = conf + + #def mail_domain_space_policy_check(self, kw={}, args=()): + #(mail, alternative_mail, domain_name, domain_root_dn) = args + + ## Your actions go here. For example: + #return (mail, alternative_mail) + + def set_primary_mail(self, kw={}, args=()): + """ + The arguments passed to the 'set_user_attrs_mail' hook: + + - current user attributes + """ + + (user_attrs, primary_domain, secondary_domains) = args + + user_attrs = utils.normalize(user_attrs) + + if not user_attrs.has_key('domain'): + user_attrs['domain'] = primary_domain + elif not user_attrs['domain'] == primary_domain: + user_attrs['domain'] = primary_domain + + try: + mail = kw['primary_mail'] % user_attrs + return mail.lower() + except KeyError, e: + self.conf.log.warning(_("Attribute substitution for 'mail' failed in Recipient Policy")) + return user_attrs['mail'].lower() + + def set_secondary_mail(self, kw={}, args=()): + """ + The arguments passed to the 'set_user_attrs_alternative_mail' hook: + + - current user attributes + """ + + (user_attrs, primary_domain, secondary_domains) = args + + user_attrs = utils.normalize(user_attrs) + + user_attrs['standard_domain'] = primary_domain + + exec("alternative_mail_routines = %s" % kw['secondary_mail']) + + alternative_mail = [] + + for routine in alternative_mail_routines.keys(): + for _domain in [ primary_domain ] + secondary_domains: + user_attrs['domain'] = _domain + try: + exec("retval = '%s'.%s" % (routine,alternative_mail_routines[routine] % user_attrs)) + except KeyError, e: + self.conf.log.warning(_("Attribute substitution for 'alternative_mail' failed in Recipient Policy")) + alternative_mail.append(retval) + + return alternative_mail |