From 9239dc0447f80deddba87f29f7d49917efd37050 Mon Sep 17 00:00:00 2001 From: Antoine Nguyen Date: Tue, 10 Apr 2012 11:12:53 +0200 Subject: [PATCH] * Added help text to all import forms (fixes #218) * Added support for importing all kind of objects (fixes #237) --- admin/models.py | 57 ++++++++++++++++++++++++++++---- admin/views.py | 58 +++++++++++++++++++++++++-------- static/js/admin.js | 11 ++++--- templates/admin/importform.html | 5 ++- 4 files changed, 106 insertions(+), 25 deletions(-) diff --git a/admin/models.py b/admin/models.py index 7142fe0fb..708f6d284 100644 --- a/admin/models.py +++ b/admin/models.py @@ -430,6 +430,14 @@ class Domain(DatesAware): def __str__(self): return self.name + def create_from_csv(self, user, row): + if len(row) < 3: + raise AdminError(_("Invalid line")) + self.name = row[1].strip() + self.quota = int(row[2].strip()) + self.enabled = True + self.save() + class DomainAlias(DatesAware): name = models.CharField(ugettext_noop("name"), max_length=100, unique=True, help_text=ugettext_noop("The alias name")) @@ -546,7 +554,11 @@ class Mailbox(DatesAware): user = getattr(self, "user") except User.DoesNotExist: user = User() - user.username = user.email = "%s@%s" % (self.address, self.domain.name) + user.email = "%s@%s" % (self.address, self.domain.name) + if kwargs.has_key("username"): + user.username = kwargs["username"] + else: + user.username = user.email if kwargs.has_key("enabled"): user.is_active = kwargs["enabled"] if kwargs.has_key("name"): @@ -587,7 +599,7 @@ class Mailbox(DatesAware): self.quota = kwargs["quota"] else: self.quota = self.domain.quota - for kw in ["name", "enabled", "password", "quota"]: + for kw in ["username", "name", "enabled", "password", "quota"]: try: del kwargs[kw] except KeyError: @@ -630,19 +642,20 @@ class Mailbox(DatesAware): :param line: a list containing the expected information """ - if len(line) < 4: + if len(line) < 6: raise AdminError(_("Invalid line")) - mailbox, domname = split_mailbox(line[0]) + mailbox, domname = split_mailbox(line[5].strip()) self.address = mailbox try: self.domain = Domain.objects.get(name=domname) except Domain.DoesNotExist: raise AdminError(_("Cannot import this mailbox because the associated domain does not exist")) - if not user.is_owner(self.domain): + if not user.can_access(self.domain): raise PermDeniedException(_("You don't have access to this domain")) - name = "%s %s" % (line[2], line[3]) - self.save(name=name, password=line[1], enabled=True) + name = "%s %s" % (line[3].strip(), line[4].strip()) + self.save(username=line[1].strip(), name=name, + password=line[2].strip(), enabled=True) def delete(self, *args, **kwargs): keepdir = False @@ -722,6 +735,36 @@ class Alias(DatesAware): return True return False + def create_from_csv(self, user, row): + if len(row) < 4: + raise AdminError(_("Invalid line")) + localpart, domname = split_mailbox(row[1].strip()) + try: + domain = Domain.objects.get(name=domname) + except Domain.DoesNotExist: + raise AdminError(_("Domain does not exist")) + if not user.can_access(domain): + raise PermDeniedException(_("You can't access this domain")) + self.address = localpart + self.domain = domain + self.enabled = True + int_rcpts = [] + ext_rcpts = [] + for rcpt in row[2:]: + rcpt = rcpt.strip() + localpart, domname = split_mailbox(rcpt) + try: + Domain.objects.get(name=domname) + except Domain.DoesNotExist: + ext_rcpts += [rcpt] + continue + try: + int_rcpts += [Mailbox.objects.get(address=localpart, + domain__name=domname)] + except Mailbox.DoesNotExist: + raise AdminError(_("Mailbox %s does not exist" % rcpt)) + self.save(int_rcpts, ext_rcpts) + class Extension(models.Model): name = models.CharField(max_length=150) enabled = models.BooleanField( diff --git a/admin/views.py b/admin/views.py index 201e0ba0c..a20c905c1 100644 --- a/admin/views.py +++ b/admin/views.py @@ -127,8 +127,10 @@ def deldomain(request): if mb and mb.domain == dom: raise AdminError(_("You can't delete your own domain")) - events.raiseEvent("DomainAliasDeleted", dom.domainalias_set.all()) - events.raiseEvent("DeleteMailbox", dom.mailbox_set.all()) + if len(dom.domainalias_set.all()): + events.raiseEvent("DomainAliasDeleted", dom.domainalias_set.all()) + if len(dom.mailbox_set.all()): + events.raiseEvent("DeleteMailbox", dom.mailbox_set.all()) events.raiseEvent("DeleteDomain", dom) ungrant_access_to_object(dom) dom.delete(keepdir=keepdir) @@ -481,18 +483,29 @@ def saveextensions(request): )) def import_domain(user, row): - pass + """Specific code for domains import""" + dom = Domain() + dom.create_from_csv(user, row) + grant_access_to_object(user, dom, is_owner=True) + events.raiseEvent("CreateDomain", user, dom) def import_account(user, row): """Specific code for accounts import""" mb = Mailbox() mb.create_from_csv(user, row) - events.raiseEvent("AccountCreated", user, mb.user) + grant_access_to_object(user, mb.user, is_owner=True) + grant_access_to_object(user, mb, is_owner=True) + events.raiseEvent("AccountCreated", mb.user) events.raiseEvent("CreateMailbox", user, mb) - grant_access_to_object(user, mb.user) - grant_access_to_object(user, mb) -def importdata(request, typ): +def import_dlist(user, row): + """Specific code for distribution lists import""" + dlist = Alias() + dlist.create_from_csv(user, row) + grant_access_to_object(user, dlist, is_owner=True) + events.raiseEvent("MailboxAliasCreated", user, dlist) + +def importdata(request): """Generic import function As the process of importing data from a CSV file is the same @@ -514,18 +527,22 @@ def importdata(request, typ): error = str(e) if error is None: - fct = globals()["import_%s" % typ] try: cpt = 0 for row in reader: + try: + fct = globals()["import_%s" % row[0].strip()] + except KeyError: + continue fct(request.user, row) cpt += 1 - messages.info(request, _("%d %s imported successfully" % (cpt, typ))) + messages.info(request, _("%d objects imported successfully" % cpt)) return _render(request, "admin/import_done.html", { "status" : "ok", "msg" : "" }) - except ModoboaException, e: + except (IntegrityError, ModoboaException), e: error = str(e) + print error return _render(request, "admin/import_done.html", { "status" : "ko", "msg" : error @@ -536,8 +553,15 @@ def importdata(request, typ): @transaction.commit_on_success def import_identities(request): if request.method == "POST": - return importdata(request, "account") + return importdata(request) + helptext = _("""Provide a CSV file where lines respect one of the following format: + +You can use a different character as separator. +""") ctx = dict( title=_("Import identities"), action_label=_("Import"), @@ -546,7 +570,8 @@ def import_identities(request): formid="importform", enctype="multipart/form-data", target="import_target", - form=ImportDataForm() + form=ImportDataForm(), + helptext=helptext ) return _render(request, "admin/importform.html", ctx) @@ -555,7 +580,13 @@ def import_identities(request): @transaction.commit_on_success def import_domains(request): if request.method == "POST": - return importdata(request, "domain") + return importdata(request) + + helptext = _("""Provide a CSV file where lines respect the following format:
+domain; name; quota
+ +You can use a different character as separator. +""") ctx = dict( title=_("Import domains"), @@ -565,6 +596,7 @@ def import_domains(request): formid="importform", enctype="multipart/form-data", target="import_target", + helptext=helptext, form=ImportDataForm() ) return _render(request, "admin/importform.html", ctx) diff --git a/static/js/admin.js b/static/js/admin.js index 5d76beb1e..1fa65fb48 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -2,7 +2,9 @@ function domainform_cb() { $('input:text:visible:first').focus(); $("#id_aliases").dynamic_input(); $(".submit").one('click', function(e) { - simple_ajax_form_post(e, domainform_cb); + simple_ajax_form_post(e, { + error_cb: domainform_cb + }); }); } @@ -54,6 +56,7 @@ function importform_cb() { return; } $("#import_status").css("display", "block"); + $("#import_result").html("").removeClass("alert alert-error"); $("form").submit(); }); } @@ -64,8 +67,8 @@ function importdone(status, msg) { $("#modalbox").modal('hide'); window.location.reload(); } else { - $("#import_result").html(""); - $(".modal-header").notify({top_position: 10}); - $(".modal-header").notify('error', msg); + $("#import_result").addClass("alert alert-error"); + $("#import_result").html(msg); + importform_cb(); } } \ No newline at end of file diff --git a/templates/admin/importform.html b/templates/admin/importform.html index 890fc231f..f6db2faac 100644 --- a/templates/admin/importform.html +++ b/templates/admin/importform.html @@ -1,7 +1,10 @@ {% extends "common/generic_modal_form.html" %} {% load libextras i18n %} {% block formbody %} - +
+

{% trans "Help" %}

+ {{ helptext|safe }} +
{% render_form form %}