summaryrefslogtreecommitdiffstats
path: root/pykolab/plugins
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-03-13 17:53:43 +0000
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-03-13 17:53:43 +0000
commit11c54d423e6a95c35932e83f81f367469a96c378 (patch)
tree5cf16d31d598fafd8872de09715138686c5f6059 /pykolab/plugins
parent354522b3d14ff28c4d976aeab35cb8ac93906b5f (diff)
downloadpykolab-11c54d423e6a95c35932e83f81f367469a96c378.tar.gz
Redo plugins so they can be binary compiled
Diffstat (limited to 'pykolab/plugins')
-rw-r--r--pykolab/plugins/__init__.py264
-rw-r--r--pykolab/plugins/defaultfolders/__init__.py44
-rw-r--r--pykolab/plugins/dynamicquota/__init__.py69
-rw-r--r--pykolab/plugins/recipientpolicy/__init__.py87
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