diff --git a/modoboa/admin/app_settings.py b/modoboa/admin/app_settings.py index 9f530be27..3bbd13b5d 100644 --- a/modoboa/admin/app_settings.py +++ b/modoboa/admin/app_settings.py @@ -1,4 +1,4 @@ -"""Modoboa admin settings and events.""" +"""Modoboa admin settings.""" import os @@ -10,43 +10,6 @@ from modoboa.lib.form_utils import YesNoField, SeparatorField from modoboa.lib.sysutils import exec_cmd from modoboa.parameters import forms as param_forms -from ..lib import events - -ADMIN_EVENTS = [ - "DomainCreated", - "DomainModified", - "DomainDeleted", - "DomainOwnershipRemoved", - "GetTagsForDomain", - - "ExtraDomainFilters", - "ExtraDomainQsetFilters", - "ExtraDomainTypes", - "ExtraDomainWizardSteps", - "GetDomainModifyLink", - "CheckDomainName", - - "DomainAliasCreated", - "DomainAliasDeleted", - - "MailboxCreated", - "MailboxDeleted", - "MailboxModified", - - "MailboxAliasCreated", - "MailboxAliasDeleted", - - "ExtraDomainForm", - "FillDomainInstances", - - "ExtraAccountForm", - "CheckExtraAccountForm", - "FillAccountInstances", - - "ExtraDomainImportHelp", - "ImportObject" -] - class AdminParametersForm(param_forms.AdminParametersForm): app = "admin" @@ -178,5 +141,3 @@ def load_admin_settings(): param_tools.registry.add( "global", AdminParametersForm, ugettext_lazy("Administration")) - events.declare(ADMIN_EVENTS) - from . import callbacks diff --git a/modoboa/admin/callbacks.py b/modoboa/admin/callbacks.py deleted file mode 100644 index b092c2516..000000000 --- a/modoboa/admin/callbacks.py +++ /dev/null @@ -1,7 +0,0 @@ -"""Event callbacks for modoboa admin.""" - -from modoboa.lib import events - -from .models import ( - Domain, DomainAlias, Mailbox, Alias -) diff --git a/modoboa/admin/forms/account.py b/modoboa/admin/forms/account.py index 19afd9871..417a293ed 100644 --- a/modoboa/admin/forms/account.py +++ b/modoboa/admin/forms/account.py @@ -11,7 +11,6 @@ from passwords.fields import PasswordField from modoboa.core import signals as core_signals from modoboa.core.models import User -from modoboa.lib import events from modoboa.lib.email_utils import split_mailbox from modoboa.lib import exceptions as lib_exceptions from modoboa.lib import fields as lib_fields @@ -24,6 +23,7 @@ from modoboa.lib.web_utils import render_to_json_response from modoboa.parameters import tools as param_tools from .. import models +from .. import signals class AccountFormGeneral(forms.ModelForm): @@ -460,11 +460,13 @@ class AccountForm(TabForms): "formtpl": "admin/permsform.html", "cls": AccountPermissionsForm} ] - cbargs = [self.user] + cbargs = {"user": self.user} if "instances" in kwargs: - cbargs += [kwargs["instances"]["general"]] - self.forms += events.raiseQueryEvent("ExtraAccountForm", *cbargs) - + cbargs["account"] = kwargs["instances"]["general"] + results = signals.extra_account_forms.send( + sender=self.__class__, **cbargs) + self.forms += reduce( + lambda a, b: a + b, [result[1] for result in results]) super(AccountForm, self).__init__(request, *args, **kwargs) def extra_context(self, context): @@ -493,9 +495,10 @@ class AccountForm(TabForms): return False return True - extra_forms = events.raiseQueryEvent( - "CheckExtraAccountForm", self.account, form) - if False in extra_forms: + results = signals.check_extra_account_form.send( + sender=self.__class__, account=self.account, form=form) + results = [result[1] for result in results] + if False in results: return False return True @@ -513,9 +516,6 @@ class AccountForm(TabForms): As forms interact with each other, it is simpler to make custom code to save them. """ - events.raiseEvent( - "AccountModified", self.instances["general"], self.account - ) self.forms[1]["instance"].save(self.user, self.account) if len(self.forms) <= 2: return diff --git a/modoboa/admin/forms/domain.py b/modoboa/admin/forms/domain.py index 445986f1e..785ac346c 100644 --- a/modoboa/admin/forms/domain.py +++ b/modoboa/admin/forms/domain.py @@ -7,7 +7,6 @@ from django.utils.translation import ugettext as _, ugettext_lazy from modoboa.core import signals as core_signals from modoboa.core.models import User -from modoboa.lib import events from modoboa.lib.exceptions import Conflict from modoboa.lib.fields import DomainNameField from modoboa.lib.form_utils import ( @@ -16,11 +15,13 @@ from modoboa.lib.form_utils import ( from modoboa.lib.web_utils import render_to_json_response from modoboa.parameters import tools as param_tools +from .. import signals from ..lib import check_if_domain_exists from ..models import ( Domain, DomainAlias, Mailbox, Alias ) + DOMAIN_TYPES = [ ("domain", _("Domain")), ] @@ -60,9 +61,12 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): self.oldname = kwargs["instance"].name super(DomainFormGeneral, self).__init__(*args, **kwargs) - self.fields["type"].choices = ( - DOMAIN_TYPES + events.raiseQueryEvent("ExtraDomainTypes")) - + extra_domain_types = reduce( + lambda a, b: a + b, + [result[1] for result in signals.extra_domain_types.send( + sender=self.__class__)] + ) + self.fields["type"].choices = DOMAIN_TYPES + extra_domain_types self.field_widths = { "quota": 3 } @@ -87,8 +91,7 @@ class DomainFormGeneral(forms.ModelForm, DynamicForm): """Custom fields validation. We want to prevent duplicate names between domains and domain - aliases. Extensions have the possibility to declare other - objects (see *CheckDomainName* event). + aliases. The validation way is not very smart... """ @@ -279,11 +282,14 @@ class DomainForm(TabForms): "mandatory": True }) - cbargs = [self.user] + cbargs = {"user": self.user} if "instances" in kwargs: self.domain = kwargs["instances"]["general"] - cbargs += [self.domain] - self.forms += events.raiseQueryEvent("ExtraDomainForm", *cbargs) + cbargs["domain"] = self.domain + results = signals.extra_domain_forms.send( + sender=self.__class__, **cbargs) + self.forms += reduce( + lambda a, b: a + b, [result[1] for result in results]) if not self.forms: self.active_id = "admins" super(DomainForm, self).__init__(request, *args, **kwargs) @@ -326,8 +332,6 @@ class DomainForm(TabForms): f["instance"].save(self.request.user) def done(self): - if "general" in self.instances: - events.raiseEvent("DomainModified", self.instances["general"]) return render_to_json_response(_("Domain modified")) @@ -343,9 +347,10 @@ class DomainWizard(WizardForm): "admin/domain_general_form.html" ) ) - steps = events.raiseQueryEvent("ExtraDomainWizardSteps") - for step in steps: - self.add_step(step) + results = signals.extra_domain_wizard_steps.send(sender=self.__class__) + for result in results: + for step in result[1]: + self.add_step(step) self.add_step( WizardStep( "options", DomainFormOptions, _("Options"), diff --git a/modoboa/admin/handlers.py b/modoboa/admin/handlers.py index 89bc051b6..4da7e6304 100644 --- a/modoboa/admin/handlers.py +++ b/modoboa/admin/handlers.py @@ -94,11 +94,9 @@ def mailbox_deleted_handler(sender, **kwargs): It manually removes the mailbox from the aliases it is linked to and then remove all empty aliases. """ - from modoboa.lib import events from modoboa.lib.permissions import ungrant_access_to_object mb = kwargs["instance"] - events.raiseEvent("MailboxDeleted", mb) ungrant_access_to_object(mb) for ralias in mb.aliasrecipient_set.select_related("alias"): alias = ralias.alias diff --git a/modoboa/admin/lib.py b/modoboa/admin/lib.py index 932a1504e..1888f0826 100644 --- a/modoboa/admin/lib.py +++ b/modoboa/admin/lib.py @@ -11,11 +11,12 @@ from django.utils.translation import ugettext as _ from modoboa.core.models import User from modoboa.core import signals as core_signals -from modoboa.lib import events from modoboa.lib.exceptions import PermDeniedException from .models import Domain, DomainAlias, Alias +from . import signals + def needs_mailbox(): """Check if the current user owns at least one mailbox @@ -92,24 +93,23 @@ def get_domains(user, domfilter=None, searchquery=None, **extrafilters): q = Q(name__contains=searchquery) q |= Q(domainalias__name__contains=searchquery) domains = domains.filter(q).distinct() - qset_filters = events.raiseDictEvent( - "ExtraDomainQsetFilters", domfilter, extrafilters - ) - if qset_filters: + results = signals.extra_domain_qset_filters.send( + sender="get_domains", domfilter=domfilter, extrafilters=extrafilters) + if results: + qset_filters = {} + for result in results: + qset_filters.update(result[1]) domains = domains.filter(**qset_filters) return domains -def check_if_domain_exists(name, extra_checks=None): +def check_if_domain_exists(name, dtypes): """Check if a domain already exists. We not only look for domains, we also look for every object that could conflict with a domain (domain alias, etc.) """ - dtypes = events.raiseQueryEvent('CheckDomainName') - if extra_checks is not None: - dtypes = extra_checks + dtypes for dtype, label in dtypes: if dtype.objects.filter(name=name).exists(): return label diff --git a/modoboa/admin/management/commands/subcommands/_import.py b/modoboa/admin/management/commands/subcommands/_import.py index 83eecd522..b5fb3c49c 100644 --- a/modoboa/admin/management/commands/subcommands/_import.py +++ b/modoboa/admin/management/commands/subcommands/_import.py @@ -9,10 +9,10 @@ from django.core.management.base import BaseCommand, CommandError from modoboa.core import models as core_models from modoboa.core.extensions import exts_pool -from modoboa.lib import events from modoboa.lib.exceptions import Conflict from .... import lib +from .... import signals class ImportCommand(BaseCommand): @@ -59,11 +59,11 @@ class ImportCommand(BaseCommand): try: fct = getattr(lib, "import_%s" % row[0].strip()) except AttributeError: - fct = events.raiseQueryEvent( - "ImportObject", row[0].strip()) + fct = signals.import_object.send( + sender=self.__class__, objtype=row[0].strip()) if not fct: continue - fct = fct[0] + fct = fct[0][1] try: fct(superadmin, row, options) except Conflict: diff --git a/modoboa/admin/models/base.py b/modoboa/admin/models/base.py index 9e55e8533..7b1e7c5e7 100644 --- a/modoboa/admin/models/base.py +++ b/modoboa/admin/models/base.py @@ -3,7 +3,6 @@ from django.db import models from django.utils import timezone -from modoboa.lib import events from modoboa.lib.permissions import ( grant_access_to_object, ungrant_access_to_object ) @@ -32,7 +31,6 @@ class AdminObject(models.Model): def post_create(self, creator): grant_access_to_object(creator, self, is_owner=True) - events.raiseEvent("%sCreated" % self.objectname, creator, self) def save(self, *args, **kwargs): creator = kwargs.pop("creator", None) @@ -41,6 +39,5 @@ class AdminObject(models.Model): self.post_create(creator) def delete(self): - events.raiseEvent("%sDeleted" % self.objectname, self) ungrant_access_to_object(self) super(AdminObject, self).delete() diff --git a/modoboa/admin/models/domain.py b/modoboa/admin/models/domain.py index c4b233c5c..c17e87bcf 100644 --- a/modoboa/admin/models/domain.py +++ b/modoboa/admin/models/domain.py @@ -15,10 +15,10 @@ from reversion import revisions as reversion from modoboa.core import signals as core_signals from modoboa.core.models import User, ObjectAccess -from modoboa.lib import events from modoboa.lib.exceptions import BadRequest, Conflict from modoboa.parameters import tools as param_tools +from .. import signals from .base import AdminObject @@ -89,7 +89,9 @@ class Domain(AdminObject): def tags(self): if self.type == "domain": return [{"name": "domain", "label": _("Domain"), "type": "dom"}] - return events.raiseQueryEvent("GetTagsForDomain", self) + results = signals.get_domain_tags.send( + sender=self.__class__, domain=self) + return reduce(lambda a, b: a + b, [result[1] for result in results]) @property def admins(self): @@ -153,11 +155,8 @@ class Domain(AdminObject): :param User account: administrator to remove """ - from modoboa.lib.permissions import \ - ungrant_access_to_object, get_object_owner + from modoboa.lib.permissions import ungrant_access_to_object - if get_object_owner(self) == account: - events.raiseEvent('DomainOwnershipRemoved', account, self) ungrant_access_to_object(self, account) for mb in self.mailbox_set.all(): if mb.user.has_perm("admin.add_domain"): @@ -181,17 +180,14 @@ class Domain(AdminObject): from .mailbox import Quota if self.domainalias_set.count(): - events.raiseEvent("DomainAliasDeleted", self.domainalias_set.all()) ungrant_access_to_objects(self.domainalias_set.all()) if self.alias_set.count(): - events.raiseEvent("MailboxAliasDeleted", self.alias_set.all()) ungrant_access_to_objects(self.alias_set.all()) if param_tools.get_global_parameter("auto_account_removal"): for account in User.objects.filter(mailbox__domain=self): account.delete(fromuser, keepdir) elif self.mailbox_set.count(): Quota.objects.filter(username__contains="@%s" % self.name).delete() - events.raiseEvent("MailboxDeleted", self.mailbox_set.all()) ungrant_access_to_objects(self.mailbox_set.all()) super(Domain, self).delete() diff --git a/modoboa/admin/models/mailbox.py b/modoboa/admin/models/mailbox.py index 14bc1d18e..9605fc77a 100644 --- a/modoboa/admin/models/mailbox.py +++ b/modoboa/admin/models/mailbox.py @@ -13,7 +13,6 @@ from django.utils.translation import ugettext as _, ugettext_lazy from reversion import revisions as reversion from modoboa.core.models import User -from modoboa.lib import events from modoboa.lib import exceptions as lib_exceptions from modoboa.lib.email_utils import split_mailbox from modoboa.lib.sysutils import exec_cmd @@ -305,7 +304,6 @@ class Mailbox(AdminObject): if newaddress: self.rename(local_part, domain) self.save() - events.raiseEvent("MailboxModified", self) def save(self, *args, **kwargs): """Custom save. diff --git a/modoboa/admin/signals.py b/modoboa/admin/signals.py index dae12a7e0..f145c5bd6 100644 --- a/modoboa/admin/signals.py +++ b/modoboa/admin/signals.py @@ -2,14 +2,30 @@ import django.dispatch +check_extra_account_form = django.dispatch.Signal( + providing_args=["account", "form"]) +extra_account_dashboard_widgets = django.dispatch.Signal( + providing_args=["user", "account"]) +extra_account_forms = django.dispatch.Signal( + providing_args=["user", "account"]) extra_admin_content = django.dispatch.Signal( providing_args=["user", "location", "currentpage"]) extra_domain_actions = django.dispatch.Signal( providing_args=["user", "domain"]) extra_domain_dashboard_widgets = django.dispatch.Signal( providing_args=["user", "domain"]) -extra_domain_menu_entries = django.dispatch.Signal( - providing_args=["user"]) -extra_account_dashboard_widgets = django.dispatch.Signal( +extra_domain_filters = django.dispatch.Signal() +extra_domain_forms = django.dispatch.Signal(providing_args=["user", "domain"]) +extra_domain_import_help = django.dispatch.Signal() +extra_domain_menu_entries = django.dispatch.Signal(providing_args=["user"]) +extra_domain_qset_filters = django.dispatch.Signal( + providing_args=["domfilter", "extrafilters"]) +extra_domain_types = django.dispatch.Signal() +extra_domain_wizard_steps = django.dispatch.Signal() +get_account_form_instances = django.dispatch.Signal( providing_args=["user", "account"]) +get_domain_form_instances = django.dispatch.Signal( + providing_args=["user", "domain"]) +get_domain_tags = django.dispatch.Signal(providing_args=["domain"]) +import_object = django.dispatch.Signal(providing_args=["objtype"]) use_external_recipients = django.dispatch.Signal(providing_args=["recipients"]) diff --git a/modoboa/admin/views/domain.py b/modoboa/admin/views/domain.py index 3c2b2dea5..b4f33452e 100644 --- a/modoboa/admin/views/domain.py +++ b/modoboa/admin/views/domain.py @@ -16,7 +16,6 @@ from reversion import revisions as reversion from modoboa.core.models import User from modoboa.core import signals as core_signals -from modoboa.lib import events from modoboa.lib.web_utils import ( _render_to_string, render_to_json_response ) @@ -45,10 +44,13 @@ def index(request): ) def _domains(request): sort_order, sort_dir = get_sort_order(request.GET, "name") + extra_filters = reduce( + lambda a, b: a + b, + [result for result in signals.extra_domain_filters(sender="_domains")] + ) filters = dict( (flt, request.GET.get(flt, None)) - for flt in ['domfilter', 'searchquery'] + - events.raiseQueryEvent('ExtraDomainFilters') + for flt in ["domfilter", "searchquery"] + extra_filters ) request.session['domains_filters'] = filters domainlist = get_domains(request.user, **filters) @@ -126,7 +128,10 @@ def editdomain(request, dom_id): raise PermDeniedException instances = dict(general=domain) - events.raiseEvent("FillDomainInstances", request.user, domain, instances) + results = signals.get_domain_form_instances.send( + sender="editdomain", user=request.user, domain=domain) + for result in results: + instances.update(result[1]) return DomainForm(request, instances=instances).process() diff --git a/modoboa/admin/views/identity.py b/modoboa/admin/views/identity.py index f2401bceb..605df0ea4 100644 --- a/modoboa/admin/views/identity.py +++ b/modoboa/admin/views/identity.py @@ -13,7 +13,6 @@ from django.contrib.auth.decorators import ( from reversion import revisions as reversion from modoboa.core.models import User -from modoboa.lib import events from modoboa.lib.exceptions import ( PermDeniedException, BadRequest ) @@ -181,7 +180,10 @@ def editaccount(request, pk): mb = account.mailbox if hasattr(account, "mailbox") else None instances = dict(general=account, mail=mb, perms=account) - events.raiseEvent("FillAccountInstances", request.user, account, instances) + results = signals.get_account_form_instances.send( + sender="editaccount", user=request.user, account=account) + for result in results: + instances.update(result[1]) return AccountForm(request, instances=instances).process() diff --git a/modoboa/admin/views/import_.py b/modoboa/admin/views/import_.py index 4be0fa67f..f29b72cb9 100644 --- a/modoboa/admin/views/import_.py +++ b/modoboa/admin/views/import_.py @@ -12,11 +12,11 @@ from django.utils.translation import ugettext as _ from reversion import revisions as reversion -from modoboa.lib import events from modoboa.lib.exceptions import ModoboaException, Conflict from ..forms import ImportIdentitiesForm, ImportDataForm from .. import lib +from .. import signals @reversion.create_revision() @@ -48,12 +48,11 @@ def importdata(request, formclass=ImportDataForm): try: fct = getattr(lib, "import_%s" % row[0].strip()) except AttributeError: - fct = events.raiseQueryEvent( - 'ImportObject', row[0].strip() - ) + fct = signals.import_object.send( + sender="importdata", objtype=row[0].strip()) if not fct: continue - fct = fct[0] + fct = fct[0][1] with transaction.atomic(): try: fct(request.user, row, form.cleaned_data) @@ -83,6 +82,8 @@ def import_domains(request): if request.method == "POST": return importdata(request) + results = signals.extra_domain_import_help.send(sender="import_domains") + extra_help = reduce(lambda a, b: a + b, [result[1] for result in results]) helptext = _("""Provide a CSV file where lines respect one of the following formats:
The first element of each line is mandatory and must be equal to one of the previous values.
You can use a different character as separator.
-""" % ''.join([unicode(hlp) for hlp in - events.raiseQueryEvent('ExtraDomainImportHelp')])) +""") % "".join(extra_help) ctx = dict( title=_("Import domains"), diff --git a/modoboa/core/apps.py b/modoboa/core/apps.py index 0dca0a28f..a3d6e5dab 100644 --- a/modoboa/core/apps.py +++ b/modoboa/core/apps.py @@ -4,12 +4,6 @@ from django.apps import AppConfig from django.db.models import signals from django.utils.translation import ugettext_lazy -BASE_EVENTS = [ - "AccountCreated", - - "AccountModified", -] - def load_core_settings(): """Load core settings. @@ -17,13 +11,11 @@ def load_core_settings(): This function must be manually called (see :file:`urls.py`) in order to load base settings. """ - from modoboa.lib import events from modoboa.parameters import tools as param_tools from .app_settings import GeneralParametersForm param_tools.registry.add( "global", GeneralParametersForm, ugettext_lazy("General")) - events.declare(BASE_EVENTS) class CoreConfig(AppConfig): diff --git a/modoboa/core/models.py b/modoboa/core/models.py index 29617c4ed..5a987623e 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -20,7 +20,6 @@ import jsonfield from reversion import revisions as reversion from modoboa.core.password_hashers import get_password_hasher -from modoboa.lib import events from modoboa.lib.exceptions import ( PermDeniedException, InternalError, BadRequest, Conflict ) @@ -330,7 +329,6 @@ class User(PermissionsMixin): """Grant permission on this user to creator.""" from modoboa.lib.permissions import grant_access_to_object grant_access_to_object(creator, self, is_owner=True) - events.raiseEvent("AccountCreated", self) def save(self, *args, **kwargs): creator = kwargs.pop("creator", None) diff --git a/modoboa/core/signals.py b/modoboa/core/signals.py index c6d406739..0a215c8a1 100644 --- a/modoboa/core/signals.py +++ b/modoboa/core/signals.py @@ -36,3 +36,4 @@ user_can_set_role = django.dispatch.Signal( providing_args=["user", "role", "account"]) user_login = django.dispatch.Signal( providing_args=["username", "password"]) +user_logout = django.dispatch.Signal() diff --git a/modoboa/core/views/auth.py b/modoboa/core/views/auth.py index 9ed5dce65..474c353a0 100644 --- a/modoboa/core/views/auth.py +++ b/modoboa/core/views/auth.py @@ -12,7 +12,6 @@ from django.views.decorators.cache import never_cache from django.contrib.auth import authenticate, login, logout from modoboa.core.forms import LoginForm -from modoboa.lib import events from modoboa.lib.web_utils import _render_to_string from .base import find_nextlocation diff --git a/modoboa/lib/events.py b/modoboa/lib/events.py deleted file mode 100644 index 57996db07..000000000 --- a/modoboa/lib/events.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -:mod:`EVENTS` --- simple EVENTS handling ----------------------------------------- - -This module provides a simple way of managing EVENTS between Modoboa -core application and additional components. - -""" - -EVENTS = [] -CALLBACKS = {} - - -def declare(nevents): - """Declare new events. - - :param list nevents: a list of event names - """ - for evt in nevents: - if evt not in EVENTS: - EVENTS.append(evt) - - -def register(event, callback): - """Register a plugin callback for a specific event - - The event must be declared in this module. - - :param event: the event to listen to - :param callback: a function to execute when the event is raised - """ - # if not event in EVENTS: - # print "Event %s not registered" % event - # return 0 - if event not in CALLBACKS.keys(): - CALLBACKS[event] = {} - fullname = "%s.%s" % (callback.__module__, callback.__name__) - if fullname not in CALLBACKS[event]: - CALLBACKS[event][fullname] = callback - return 1 - - -class observe(object): - """Event observing decorator. - - Automatically register the decorated function to observe the given - event. - - :param evtnames: a list of event names - """ - def __init__(self, *evtnames, **kwargs): - self.evtnames = evtnames - - def __call__(self, f): - for evt in self.evtnames: - register(evt, f) - return f - - -def unregister(event, callback): - """Unregister a callback for a specific event - - :param event: the targeted event - :param callback: the callback to remove - """ - if event not in EVENTS: - return False - if event not in CALLBACKS: - return False - fullname = "%s.%s" % (callback.__module__, callback.__name__) - try: - del CALLBACKS[event][fullname] - except KeyError: - pass - - -def raiseEvent(event, *args, **kwargs): - """Raise a specific event - - Any additional keyword argument will be passed to registered - CALLBACKS. - - :param event: the event to raise - """ - if event not in EVENTS or event not in CALLBACKS: - return 0 - for callback in CALLBACKS[event].values(): - callback(*args, **kwargs) - return 1 - - -def raiseQueryEvent(event, *args, **kwargs): - """Raise a specific event and wait for answers from CALLBACKS - - Any additional keyword argument will be passed to registered - CALLBACKS. Callback answers are returned as a list. - - :param event: the event to raise - """ - result = [] - if event not in EVENTS or event not in CALLBACKS: - return result - for callback in CALLBACKS[event].values(): - tmp = callback(*args, **kwargs) - if tmp is None: - # Callback is registered but associated extension is - # disabled. - continue - result += tmp - return result - - -def raiseDictEvent(event, *args): - """Raise a specific event and return result as a dictionnary - - Any additional keyword argument will be passed to registered - CALLBACKS. Callback answers must be dictionnaries. - - :param event: the event to raise - :return: a dictionnary - """ - result = {} - if event not in EVENTS or event not in CALLBACKS: - return result - for callback in CALLBACKS[event].values(): - tmp = callback(*args) - if tmp is None: - # Callback is registered but associated extension is - # disabled. - continue - for k, v in tmp.iteritems(): - result[k] = v - return result diff --git a/modoboa/limits/apps.py b/modoboa/limits/apps.py index 117c92a5f..f91abd69a 100644 --- a/modoboa/limits/apps.py +++ b/modoboa/limits/apps.py @@ -3,20 +3,13 @@ from django.apps import AppConfig from django.utils.translation import ugettext as _ -EVENTS = [ - "GetExtraLimitTemplates" -] - def load_limits_settings(): """Load settings.""" - from modoboa.lib import events from modoboa.parameters import tools as param_tools from .app_settings import ParametersForm param_tools.registry.add("global", ParametersForm, _("Limits")) - events.declare(EVENTS) - from . import general_callbacks class LimitsConfig(AppConfig): diff --git a/modoboa/limits/general_callbacks.py b/modoboa/limits/general_callbacks.py deleted file mode 100644 index e17fd2cc3..000000000 --- a/modoboa/limits/general_callbacks.py +++ /dev/null @@ -1,75 +0,0 @@ -"""General event callbacks.""" - -from django.template.loader import render_to_string -from django.utils.translation import ugettext as _ - -from modoboa.lib import events -from modoboa.parameters import tools as param_tools - -from . import forms -from . import utils - - -@events.observe("ExtraAccountForm") -def extra_account_form(user, account=None): - if not param_tools.get_global_parameter("enable_admin_limits"): - return [] - if user.role not in ["SuperAdmins", "Resellers"]: - return [] - condition = ( - (account is not None and - account.role not in ["Resellers", "DomainAdmins"]) or - user == account - ) - if condition: - return [] - - return [{ - "id": "resources", "title": _("Resources"), - "cls": forms.ResourcePoolForm - }] - - -@events.observe("ExtraDomainForm") -def extra_domain_form(user, domain): - """Include domain limits form.""" - if not param_tools.get_global_parameter("enable_domain_limits"): - return [] - if not user.has_perm("admin.change_domain"): - return [] - return [{ - "id": "resources", "title": _("Resources"), - "cls": forms.DomainLimitsForm - }] - - -@events.observe("FillDomainInstances") -def fill_domain_instances(user, domain, instances): - """Set domain instance for resources form.""" - if not param_tools.get_global_parameter("enable_domain_limits"): - return - if not user.has_perm("admin.change_domain"): - return - instances["resources"] = domain - - -@events.observe("CheckExtraAccountForm") -def check_form_access(account, form): - if form["id"] != "resources": - return [True] - if account.role not in ["Resellers", "DomainAdmins"]: - return [False] - return [True] - - -@events.observe("FillAccountInstances") -def fill_account_instances(user, account, instances): - condition = ( - not param_tools.get_global_parameter("enable_admin_limits") or - (not user.is_superuser and user.role != "Resellers") - ) - if condition: - return - if account.role not in ["Resellers", "DomainAdmins"]: - return - instances["resources"] = account diff --git a/modoboa/limits/handlers.py b/modoboa/limits/handlers.py index 75657ed29..9e7d8ef2f 100644 --- a/modoboa/limits/handlers.py +++ b/modoboa/limits/handlers.py @@ -5,6 +5,7 @@ from django.dispatch import receiver from django.template.loader import render_to_string from django.contrib.contenttypes.models import ContentType +from django.utils.translation import ugettext as _ from modoboa.admin import models as admin_models from modoboa.admin import signals as admin_signals @@ -14,6 +15,7 @@ from modoboa.lib import signals as lib_signals from modoboa.lib import permissions from modoboa.parameters import tools as param_tools +from . import forms from . import lib from . import models from . import utils @@ -103,6 +105,74 @@ def display_admin_limits(sender, user, account, **kwargs): }] +@receiver(admin_signals.extra_account_forms) +def extra_account_form(sender, user, account=None, **kwargs): + """Add limits form.""" + if not param_tools.get_global_parameter("enable_admin_limits"): + return [] + if user.role not in ["SuperAdmins", "Resellers"]: + return [] + condition = ( + (account is not None and + account.role not in ["Resellers", "DomainAdmins"]) or + user == account + ) + if condition: + return [] + return [{ + "id": "resources", "title": _("Resources"), + "cls": forms.ResourcePoolForm + }] + + +@receiver(admin_signals.check_extra_account_form) +def check_form_access(sender, account, form, **kwargs): + """Check if form must be used for account.""" + if form["id"] != "resources": + return True + if account.role not in ["Resellers", "DomainAdmins"]: + return False + return True + + +@receiver(admin_signals.get_account_form_instances) +def fill_account_instances(sender, user, account, **kwargs): + """Set account instance for resources form.""" + condition = ( + not param_tools.get_global_parameter("enable_admin_limits") or + (not user.is_superuser and user.role != "Resellers") or + account.role not in ["Resellers", "DomainAdmins"] + ) + if condition: + return {} + return {"resources": account} + + +@receiver(admin_signals.extra_domain_forms) +def extra_domain_form(sender, user, domain, **kwargs): + """Include domain limits form.""" + if not param_tools.get_global_parameter("enable_domain_limits"): + return [] + if not user.has_perm("admin.change_domain"): + return [] + return [{ + "id": "resources", "title": _("Resources"), + "cls": forms.DomainLimitsForm + }] + + +@receiver(admin_signals.get_domain_form_instances) +def fill_domain_instances(sender, user, domain, **kwargs): + """Set domain instance for resources form.""" + condition = ( + not param_tools.get_global_parameter("enable_domain_limits") or + not user.has_perm("admin.change_domain") + ) + if condition: + return {} + return {"resources": domain} + + @receiver(core_signals.account_deleted) def move_resource(sender, user, **kwargs): """Move remaining resource to another user.""" diff --git a/modoboa/limits/utils.py b/modoboa/limits/utils.py index 25cb45629..64b3358ba 100644 --- a/modoboa/limits/utils.py +++ b/modoboa/limits/utils.py @@ -5,7 +5,6 @@ from . import constants def get_user_limit_templates(): """Return defined templates.""" - # FIXME: change GetExtraLimitTemplates return constants.DEFAULT_USER_LIMITS.items() diff --git a/modoboa/relaydomains/apps.py b/modoboa/relaydomains/apps.py index 433f5d770..34b229a03 100644 --- a/modoboa/relaydomains/apps.py +++ b/modoboa/relaydomains/apps.py @@ -3,26 +3,13 @@ from django.apps import AppConfig from django.utils.translation import ugettext as _ -EVENTS = [ - "RelayDomainCreated", - "RelayDomainDeleted", - "RelayDomainModified", - "RelayDomainAliasCreated", - "RelayDomainAliasDeleted", - "ExtraRelayDomainForm", - "FillRelayDomainInstances" -] - def load_relaydomains_settings(): """Load application settings.""" from modoboa.parameters import tools as param_tools - from modoboa.lib import events from .app_settings import AdminParametersForm param_tools.registry.add("global", AdminParametersForm, _("Relay domains")) - events.declare(EVENTS) - from . import general_callbacks class RelayDomainsConfig(AppConfig): diff --git a/modoboa/relaydomains/general_callbacks.py b/modoboa/relaydomains/general_callbacks.py deleted file mode 100644 index 56f3e7de3..000000000 --- a/modoboa/relaydomains/general_callbacks.py +++ /dev/null @@ -1,85 +0,0 @@ -"""General event callbacks.""" - -from django.utils.translation import ugettext_lazy, ugettext as _ - -from modoboa.lib import events - -from .forms import RelayDomainWizardStep, RelayDomainFormGeneral - - -@events.observe('ExtraDomainFilters') -def extra_domain_filters(): - return ['srvfilter'] - - -@events.observe("ExtraDomainTypes") -def extra_domain_types(): - """Declare the relay domain type.""" - return [("relaydomain", _("Relay domain"))] - - -@events.observe("ExtraDomainWizardSteps") -def extra_wizard_step(): - """Return a step to configure the relay settings.""" - return [RelayDomainWizardStep( - "relay", RelayDomainFormGeneral, _("Relay domain"), - "relaydomains/relaydomain_form.html" - )] - - -@events.observe("ExtraDomainForm") -def extra_domain_form(user, domain): - """Return relay settings for domain edition.""" - if not user.has_perm("relaydomains.change_relaydomain"): - return [] - if domain.type != "relaydomain": - return [] - return [{ - "id": "relaydomain", "title": _("Relay settings"), - "cls": RelayDomainFormGeneral, - "formtpl": "relaydomains/relaydomain_form.html" - }] - - -@events.observe("FillDomainInstances") -def fill_domain_instances(user, domain, instances): - """Fill the relaydomain form with the right instance.""" - if not user.has_perm("relaydomains.change_relaydomain"): - return - if domain.type != "relaydomain": - return - instances["relaydomain"] = domain.relaydomain - - -@events.observe("ExtraDomainQsetFilters") -def extra_domain_entries(domfilter, extrafilters): - """Return extra queryset filters.""" - if domfilter is not None and domfilter and domfilter != 'relaydomain': - return {} - if "srvfilter" in extrafilters and extrafilters["srvfilter"]: - return {"relaydomain__service__name": extrafilters["srvfilter"]} - return {} - - -@events.observe("GetTagsForDomain") -def get_tags_for_domain(domain): - """Return relay domain custom tags.""" - if domain.type != "relaydomain": - return [] - return domain.relaydomain.tags - - -@events.observe('ExtraDomainImportHelp') -def extra_domain_import_help(): - return [ugettext_lazy(""" -