diff --git a/modoboa/extensions/amavis/__init__.py b/modoboa/extensions/amavis/__init__.py index 5e47ac577..1327288ae 100644 --- a/modoboa/extensions/amavis/__init__.py +++ b/modoboa/extensions/amavis/__init__.py @@ -8,6 +8,7 @@ Provides: * Per-domain settings """ +import sys from django.utils.translation import ugettext_lazy from modoboa.lib import events, parameters from modoboa.core.extensions import ModoExtension, exts_pool @@ -43,6 +44,8 @@ class Amavis(ModoExtension): parameters.register(ParametersForm, "Amavis") parameters.register(UserSettings, ugettext_lazy("Quarantine")) from modoboa.extensions.amavis import general_callbacks + if 'modoboa.extensions.amavis.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): events.unregister_extension() diff --git a/modoboa/extensions/limits/__init__.py b/modoboa/extensions/limits/__init__.py index 61a6961fe..2601c97e1 100644 --- a/modoboa/extensions/limits/__init__.py +++ b/modoboa/extensions/limits/__init__.py @@ -4,14 +4,13 @@ The *limits* extension ---------------------- """ +import sys from django.contrib.auth.models import Permission, Group from django.db import IntegrityError from django.contrib.contenttypes.models import ContentType -from django.utils.translation import ugettext as _, ugettext_lazy +from django.utils.translation import ugettext_lazy from modoboa.lib import events, parameters from modoboa.core.extensions import ModoExtension, exts_pool -from .models import LimitTemplates -from .forms import ResourcePoolForm levents = [ 'GetExtraLimitTemplates' @@ -56,102 +55,13 @@ class Limits(ModoExtension): parameters.register(ParametersForm, ugettext_lazy("Limits")) events.declare(levents) + from modoboa.extensions.limits import general_callbacks + if 'modoboa.extensions.limits.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): + events.unregister_extension() parameters.unregister() Group.objects.get(name="Resellers").delete() exts_pool.register_extension(Limits) - - -@events.observe("GetExtraRoles") -def get_extra_roles(user): - if user.is_superuser: - return [("Resellers", _("Reseller")), ] - return [] - - -@events.observe("ExtraAdminContent") -def display_pool_usage(user, target, currentpage): - from django.template.loader import render_to_string - - if target != "leftcol" or user.is_superuser: - return [] - if currentpage == "identities": - names = ["mailboxes_limit", "mailbox_aliases_limit"] - if user.has_perm("admin.add_domain"): - names += ["domain_admins_limit"] - else: - names = [ - tpl[0] for tpl in LimitTemplates().templates - if tpl[0] not in ["domain_admins_limit", "mailboxes_limit", - "mailbox_aliases_limit"] - and (len(tpl) == 3 or tpl[3] == user.group) - ] - - limits = user.limitspool.limit_set.filter(name__in=names, maxvalue__gt=0) - if len(limits) == 0: - return [] - return [render_to_string("limits/poolusage.html", dict(limits=limits))] - - -@events.observe("ExtraAccountForm") -def extra_account_form(user, account=None): - if not user.group in ["SuperAdmins", "Resellers"]: - return [] - if account is not None and \ - not account.group in ["Resellers", "DomainAdmins"]: - return [] - - return [ - dict( - id="resources", title=_("Resources"), cls=ResourcePoolForm - ) - ] - - -@events.observe("CheckExtraAccountForm") -def check_form_access(account, form): - if form["id"] != "resources": - return [True] - if not account.belongs_to_group("Resellers") and \ - not account.belongs_to_group("DomainAdmins"): - return [False] - return [True] - - -@events.observe("FillAccountInstances") -def fill_account_instances(user, account, instances): - if not user.is_superuser and not user.belongs_to_group("Resellers"): - return - if not account.belongs_to_group("Resellers") and \ - not account.belongs_to_group("DomainAdmins"): - return - instances["resources"] = account - - -@events.observe("GetStaticContent") -def get_static_content(caller, user): - if caller not in ['domains', 'identities']: - return [] - if user.group == "SimpleUsers": - return [] - return [""" - -"""] diff --git a/modoboa/extensions/limits/general_callbacks.py b/modoboa/extensions/limits/general_callbacks.py new file mode 100644 index 000000000..0d41c2449 --- /dev/null +++ b/modoboa/extensions/limits/general_callbacks.py @@ -0,0 +1,97 @@ +from django.utils.translation import ugettext as _ +from modoboa.lib import events +from modoboa.extensions.limits.models import LimitTemplates +from modoboa.extensions.limits.forms import ResourcePoolForm + + +@events.observe("GetExtraRoles") +def get_extra_roles(user): + if user.is_superuser: + return [("Resellers", _("Reseller")), ] + return [] + + +@events.observe("ExtraAdminContent") +def display_pool_usage(user, target, currentpage): + from django.template.loader import render_to_string + + if target != "leftcol" or user.is_superuser: + return [] + if currentpage == "identities": + names = ["mailboxes_limit", "mailbox_aliases_limit"] + if user.has_perm("admin.add_domain"): + names += ["domain_admins_limit"] + else: + names = [ + tpl[0] for tpl in LimitTemplates().templates + if tpl[0] not in ["domain_admins_limit", "mailboxes_limit", + "mailbox_aliases_limit"] + and (len(tpl) == 3 or tpl[3] == user.group) + ] + + limits = user.limitspool.limit_set.filter(name__in=names, maxvalue__gt=0) + if len(limits) == 0: + return [] + return [render_to_string("limits/poolusage.html", dict(limits=limits))] + + +@events.observe("ExtraAccountForm") +def extra_account_form(user, account=None): + if not user.group in ["SuperAdmins", "Resellers"]: + return [] + if account is not None and \ + not account.group in ["Resellers", "DomainAdmins"]: + return [] + + return [ + dict( + id="resources", title=_("Resources"), cls=ResourcePoolForm + ) + ] + + +@events.observe("CheckExtraAccountForm") +def check_form_access(account, form): + if form["id"] != "resources": + return [True] + if not account.belongs_to_group("Resellers") and \ + not account.belongs_to_group("DomainAdmins"): + return [False] + return [True] + + +@events.observe("FillAccountInstances") +def fill_account_instances(user, account, instances): + if not user.is_superuser and not user.belongs_to_group("Resellers"): + return + if not account.belongs_to_group("Resellers") and \ + not account.belongs_to_group("DomainAdmins"): + return + instances["resources"] = account + + +@events.observe("GetStaticContent") +def get_static_content(caller, user): + if caller not in ['domains', 'identities']: + return [] + if user.group == "SimpleUsers": + return [] + return [""" + +"""] diff --git a/modoboa/extensions/postfix_autoreply/__init__.py b/modoboa/extensions/postfix_autoreply/__init__.py index fdbebf511..c28dd67e0 100644 --- a/modoboa/extensions/postfix_autoreply/__init__.py +++ b/modoboa/extensions/postfix_autoreply/__init__.py @@ -6,13 +6,20 @@ This module provides a way to integrate Modoboa auto-reply functionality into Postfix. """ +import sys from django.utils.translation import ugettext_lazy from modoboa.lib import events, parameters from modoboa.core.extensions import ModoExtension, exts_pool -from .models import Transport, Alias +from modoboa.extensions.postfix_autoreply.models import ( + Transport, Alias +) class PostfixAutoreply(ModoExtension): + """ + Auto-reply (vacation) functionality using Postfix. + + """ name = "postfix_autoreply" label = "Postfix autoreply" version = "1.0" @@ -38,14 +45,12 @@ class PostfixAutoreply(ModoExtension): def load(self): from modoboa.extensions.postfix_autoreply.app_settings import ParametersForm parameters.register(ParametersForm, ugettext_lazy("Automatic replies")) + from modoboa.extensions.postfix_autoreply import general_callbacks + if 'modoboa.extensions.postfix_autoreply.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): - events.unregister("DomainCreated", onDomainCreated) - events.unregister("DomainDeleted", onDomainDeleted) - events.unregister("MailboxCreated", onMailboxCreated) - events.unregister("MailboxDeleted", onMailboxDeleted) - events.unregister("MailboxModified", onModifyMailbox) - events.unregister("UserMenuDisplay", menu) + events.unregister_extension() parameters.unregister() exts_pool.register_extension(PostfixAutoreply) @@ -55,87 +60,3 @@ exts_pool.register_extension(PostfixAutoreply) def extra_routes(): return [(r'^user/autoreply/$', 'modoboa.extensions.postfix_autoreply.views.autoreply'), ] - - -@events.observe("ExtraUprefsJS") -def extra_js(user): - return ["""function autoreply_cb() { - $('#id_untildate').datepicker({format: 'yyyy-mm-dd', language: '%s'}); -} -""" % parameters.get_user(user, "LANG", app="core") - ] - - -@events.observe("UserMenuDisplay") -def menu(target, user): - if target != "uprefs_menu": - return [] - if not user.mailbox_set.count(): - return [] - return [ - {"name": "autoreply", - "class": "ajaxlink", - "url": "autoreply/", - "label": ugettext_lazy("Auto-reply message")} - ] - - -@events.observe("DomainCreated") -def onDomainCreated(user, domain): - transport = Transport() - transport.domain = "autoreply.%s" % domain.name - transport.method = "autoreply:" - transport.save() - - -@events.observe("DomainModified") -def onDomainModified(domain): - if domain.oldname == domain.name: - return - Transport.objects.filter(domain="autoreply.%s" % domain.oldname) \ - .update(domain="autoreply.%s" % domain.name) - for al in Alias.objects.filter(full_address__contains="@%s" % domain.oldname): - new_address = al.full_address.replace("@%s" % domain.oldname, "@%s" % domain.name) - al.full_address = new_address - al.autoreply_address = "%s@autoreply.%s" % (new_address, domain.name) - al.save() - - -@events.observe("DomainDeleted") -def onDomainDeleted(domain): - Transport.objects.filter(domain="autoreply.%s" % domain.name).delete() - - -@events.observe("MailboxCreated") -def onMailboxCreated(user, mailbox): - alias = Alias() - alias.full_address = mailbox.full_address - alias.autoreply_address = \ - "%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name) - alias.save() - - -@events.observe("MailboxDeleted") -def onMailboxDeleted(mailboxes): - from modoboa.extensions.admin.models import Mailbox - - if isinstance(mailboxes, Mailbox): - mailboxes = [mailboxes] - for mailbox in mailboxes: - try: - alias = Alias.objects.get(full_address=mailbox.full_address) - except Alias.DoesNotExist: - pass - else: - alias.delete() - - -@events.observe("MailboxModified") -def onModifyMailbox(mailbox, oldmailbox): - if oldmailbox.full_address == mailbox.full_address: - return - alias = Alias.objects.get(full_address=oldmailbox.full_address) - alias.full_address = mailbox.full_address - alias.autoreply_address = \ - "%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name) - alias.save() diff --git a/modoboa/extensions/postfix_autoreply/general_callbacks.py b/modoboa/extensions/postfix_autoreply/general_callbacks.py new file mode 100644 index 000000000..c28de5e9c --- /dev/null +++ b/modoboa/extensions/postfix_autoreply/general_callbacks.py @@ -0,0 +1,87 @@ +from django.utils.translation import ugettext_lazy +from modoboa.lib import events, parameters +from modoboa.extensions.postfix_autoreply.models import Transport, Alias + + +@events.observe("ExtraUprefsJS") +def extra_js(user): + return ["""function autoreply_cb() { + $('#id_untildate').datepicker({format: 'yyyy-mm-dd', language: '%s'}); +} +""" % parameters.get_user(user, "LANG", app="core") + ] + + +@events.observe("UserMenuDisplay") +def menu(target, user): + if target != "uprefs_menu": + return [] + if not user.mailbox_set.count(): + return [] + return [ + {"name": "autoreply", + "class": "ajaxlink", + "url": "autoreply/", + "label": ugettext_lazy("Auto-reply message")} + ] + + +@events.observe("DomainCreated") +def onDomainCreated(user, domain): + transport = Transport() + transport.domain = "autoreply.%s" % domain.name + transport.method = "autoreply:" + transport.save() + + +@events.observe("DomainModified") +def onDomainModified(domain): + if domain.oldname == domain.name: + return + Transport.objects.filter(domain="autoreply.%s" % domain.oldname) \ + .update(domain="autoreply.%s" % domain.name) + for al in Alias.objects.filter(full_address__contains="@%s" % domain.oldname): + new_address = al.full_address.replace("@%s" % domain.oldname, "@%s" % domain.name) + al.full_address = new_address + al.autoreply_address = "%s@autoreply.%s" % (new_address, domain.name) + al.save() + + +@events.observe("DomainDeleted") +def onDomainDeleted(domain): + Transport.objects.filter(domain="autoreply.%s" % domain.name).delete() + + +@events.observe("MailboxCreated") +def onMailboxCreated(user, mailbox): + alias = Alias() + alias.full_address = mailbox.full_address + alias.autoreply_address = \ + "%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name) + alias.save() + + +@events.observe("MailboxDeleted") +def onMailboxDeleted(mailboxes): + from modoboa.extensions.admin.models import Mailbox + + if isinstance(mailboxes, Mailbox): + mailboxes = [mailboxes] + for mailbox in mailboxes: + try: + alias = Alias.objects.get(full_address=mailbox.full_address) + except Alias.DoesNotExist: + pass + else: + alias.delete() + + +@events.observe("MailboxModified") +def onModifyMailbox(mailbox, oldmailbox): + if oldmailbox.full_address == mailbox.full_address: + return + alias = Alias.objects.get(full_address=oldmailbox.full_address) + alias.full_address = mailbox.full_address + alias.autoreply_address = \ + "%s@autoreply.%s" % (mailbox.full_address, mailbox.domain.name) + alias.save() diff --git a/modoboa/extensions/postfix_relay_domains/__init__.py b/modoboa/extensions/postfix_relay_domains/__init__.py index 10aba023a..dfe3fff0d 100644 --- a/modoboa/extensions/postfix_relay_domains/__init__.py +++ b/modoboa/extensions/postfix_relay_domains/__init__.py @@ -1,4 +1,5 @@ # coding: utf-8 +import sys from django.contrib.auth.models import Group, Permission from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy @@ -88,10 +89,16 @@ class PostfixRelayDomains(ModoExtension): ) events.declare(extension_events) from modoboa.extensions.postfix_relay_domains import general_callbacks + if 'modoboa.extensions.postfix_relay_domains.general_callbacks' in sys.modules: + reload(general_callbacks) if exts_pool.is_extension_enabled('limits'): import limits_callbacks + if 'modoboa.extensions.postfix_relay_domains.limits_callbacks' in sys.modules: + reload(limits_callbacks) if exts_pool.is_extension_enabled('amavis'): import amavis_callbacks + if 'modoboa.extensions.postfix_relay_domains.amavis_callbacks' in sys.modules: + reload(amavis_callbacks) def destroy(self): events.unregister_extension() diff --git a/modoboa/extensions/sievefilters/__init__.py b/modoboa/extensions/sievefilters/__init__.py index c5b88c95f..76cade1f7 100644 --- a/modoboa/extensions/sievefilters/__init__.py +++ b/modoboa/extensions/sievefilters/__init__.py @@ -1,6 +1,6 @@ # coding: utf-8 -from django.utils.translation import ugettext as _, ugettext_lazy -from django.core.urlresolvers import reverse +import sys +from django.utils.translation import ugettext_lazy from modoboa.lib import events, parameters from modoboa.core.extensions import ModoExtension, exts_pool @@ -16,38 +16,12 @@ class SieveFilters(ModoExtension): from .app_settings import ParametersForm, UserSettings parameters.register(ParametersForm, ugettext_lazy("Sieve filters")) parameters.register(UserSettings, ugettext_lazy("Message filters")) + from modoboa.extensions.sievefilters import general_callbacks + if 'modoboa.extensions.sievefilters.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): - events.unregister("UserMenuDisplay", menu) + events.unregister_extension() parameters.unregister() exts_pool.register_extension(SieveFilters) - - -@events.observe("UserMenuDisplay") -def menu(target, user): - if target != "options_menu": - return [] - if not user.mailbox_set.count(): - return [] - return [ - {"name": "sievefilters", - "label": _("Message filters"), - "url": reverse("modoboa.extensions.sievefilters.views.index"), - "img": "icon-check"} - ] - - -@events.observe("UserLogout") -def userlogout(request): - from .lib import SieveClient - - if not request.user.mailbox_set.count(): - return - try: - sc = SieveClient(user=request.user.username, - password=request.session["password"]) - except Exception: - pass - else: - sc.logout() diff --git a/modoboa/extensions/sievefilters/general_callbacks.py b/modoboa/extensions/sievefilters/general_callbacks.py new file mode 100644 index 000000000..0ce7a381b --- /dev/null +++ b/modoboa/extensions/sievefilters/general_callbacks.py @@ -0,0 +1,32 @@ +from django.utils.translation import ugettext as _ +from django.core.urlresolvers import reverse +from modoboa.lib import events + + +@events.observe("UserMenuDisplay") +def menu(target, user): + if target != "options_menu": + return [] + if not user.mailbox_set.count(): + return [] + return [ + {"name": "sievefilters", + "label": _("Message filters"), + "url": reverse("modoboa.extensions.sievefilters.views.index"), + "img": "icon-check"} + ] + + +@events.observe("UserLogout") +def userlogout(request): + from .lib import SieveClient + + if not request.user.mailbox_set.count(): + return + try: + sc = SieveClient(user=request.user.username, + password=request.session["password"]) + except Exception: + pass + else: + sc.logout() diff --git a/modoboa/extensions/stats/__init__.py b/modoboa/extensions/stats/__init__.py index 7197cc01c..e08b12b55 100644 --- a/modoboa/extensions/stats/__init__.py +++ b/modoboa/extensions/stats/__init__.py @@ -7,8 +7,8 @@ This module provides support to retrieve statistics from postfix log : sent, received, bounced, rejected """ -from django.core.urlresolvers import reverse -from django.utils.translation import ugettext as _, ugettext_lazy +import sys +from django.utils.translation import ugettext_lazy from modoboa.lib import events, parameters from modoboa.core.extensions import ModoExtension, exts_pool @@ -17,7 +17,9 @@ class Stats(ModoExtension): name = "stats" label = "Statistics" version = "1.0" - description = ugettext_lazy("Graphical statistics about emails traffic using RRDtool") + description = ugettext_lazy( + "Graphical statistics about emails traffic using RRDtool" + ) needs_media = True def load(self): @@ -26,27 +28,12 @@ class Stats(ModoExtension): parameters.register( ParametersForm, ugettext_lazy("Graphical statistics") ) + from modoboa.extensions.stats import general_callbacks + if 'modoboa.extensions.stats.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): - events.unregister("AdminMenuDisplay", menu) + events.unregister_extension() + parameters.unregister() exts_pool.register_extension(Stats) - - -@events.observe("UserMenuDisplay") -def menu(target, user): - if target != "top_menu" or user.group == "SimpleUsers": - return [] - return [ - {"name": "stats", - "label": _("Statistics"), - "url": reverse('fullindex')} - ] - - -@events.observe("GetGraphSets") -def get_default_graph_sets(): - from modoboa.extensions.stats.graph_templates import MailTraffic - - gset = MailTraffic() - return {gset.html_id: gset} diff --git a/modoboa/extensions/stats/general_callbacks.py b/modoboa/extensions/stats/general_callbacks.py new file mode 100644 index 000000000..ced60145c --- /dev/null +++ b/modoboa/extensions/stats/general_callbacks.py @@ -0,0 +1,22 @@ +from django.core.urlresolvers import reverse +from django.utils.translation import ugettext as _ +from modoboa.lib import events + + +@events.observe("UserMenuDisplay") +def menu(target, user): + if target != "top_menu" or user.group == "SimpleUsers": + return [] + return [ + {"name": "stats", + "label": _("Statistics"), + "url": reverse('fullindex')} + ] + + +@events.observe("GetGraphSets") +def get_default_graph_sets(): + from modoboa.extensions.stats.graph_templates import MailTraffic + + gset = MailTraffic() + return {gset.html_id: gset} diff --git a/modoboa/extensions/webmail/__init__.py b/modoboa/extensions/webmail/__init__.py index 8b336b8b1..597f85375 100644 --- a/modoboa/extensions/webmail/__init__.py +++ b/modoboa/extensions/webmail/__init__.py @@ -1,4 +1,5 @@ # coding: utf-8 +import sys from django.utils.translation import ugettext as _, ugettext_lazy from django.core.urlresolvers import reverse from modoboa.lib import events, parameters @@ -17,43 +18,12 @@ class Webmail(ModoExtension): parameters.register(ParametersForm, "Webmail") parameters.register(UserSettings, "Webmail") + from modoboa.extensions.webmail import general_callbacks + if 'modoboa.extensions.webmail.general_callbacks' in sys.modules: + reload(general_callbacks) def destroy(self): - events.unregister("UserMenuDisplay", menu) + events.unregister_extension() parameters.unregister() exts_pool.register_extension(Webmail) - - -@events.observe("UserMenuDisplay") -def menu(target, user): - if target != "top_menu": - return [] - if not user.mailbox_set.count(): - return [] - return [ - {"name": "webmail", - "label": _("Webmail"), - "url": reverse("modoboa.extensions.webmail.views.index")}, - ] - - -@events.observe("UserLogout") -def userlogout(request): - from .lib import IMAPconnector - from .exceptions import ImapError - - if not request.user.mailbox_set.count(): - return - try: - m = IMAPconnector(user=request.user.username, - password=request.session["password"]) - except Exception: - # TODO silent exception are bad : we should at least log it - return - - # The following statement may fail under Python 2.6... - try: - m.logout() - except ImapError: - pass diff --git a/modoboa/extensions/webmail/general_callbacks.py b/modoboa/extensions/webmail/general_callbacks.py new file mode 100644 index 000000000..affbcf2bf --- /dev/null +++ b/modoboa/extensions/webmail/general_callbacks.py @@ -0,0 +1,37 @@ +from django.utils.translation import ugettext as _ +from django.core.urlresolvers import reverse +from modoboa.lib import events + + +@events.observe("UserMenuDisplay") +def menu(target, user): + if target != "top_menu": + return [] + if not user.mailbox_set.count(): + return [] + return [ + {"name": "webmail", + "label": _("Webmail"), + "url": reverse("modoboa.extensions.webmail.views.index")}, + ] + + +@events.observe("UserLogout") +def userlogout(request): + from .lib import IMAPconnector + from .exceptions import ImapError + + if not request.user.mailbox_set.count(): + return + try: + m = IMAPconnector(user=request.user.username, + password=request.session["password"]) + except Exception: + # TODO silent exception are bad : we should at least log it + return + + # The following statement may fail under Python 2.6... + try: + m.logout() + except ImapError: + pass