diff --git a/admin/migrations/0006_auto__add_domainalias.py b/admin/migrations/0006_auto__add_domainalias.py new file mode 100644 index 000000000..27c2e9aea --- /dev/null +++ b/admin/migrations/0006_auto__add_domainalias.py @@ -0,0 +1,108 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Adding model 'DomainAlias' + db.create_table('admin_domainalias', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)), + ('target', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['admin.Domain'])), + ('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)), + )) + db.send_create_signal('admin', ['DomainAlias']) + + + def backwards(self, orm): + + # Deleting model 'DomainAlias' + db.delete_table('admin_domainalias') + + + models = { + 'admin.alias': { + 'Meta': {'object_name': 'Alias'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'full_address': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mboxes': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['admin.Mailbox']", 'symmetrical': 'False'}) + }, + 'admin.domain': { + 'Meta': {'object_name': 'Domain'}, + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}) + }, + 'admin.domainalias': { + 'Meta': {'object_name': 'DomainAlias'}, + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}), + 'target': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}) + }, + 'admin.extension': { + 'Meta': {'object_name': 'Extension'}, + 'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'admin.mailbox': { + 'Meta': {'object_name': 'Mailbox'}, + 'address': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['admin.Domain']"}), + 'full_address': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'gid': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'path': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'quota': ('django.db.models.fields.IntegerField', [], {}), + 'uid': ('django.db.models.fields.IntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['admin'] diff --git a/admin/templatetags/admin_extras.py b/admin/templatetags/admin_extras.py index 6b4710905..c0d8a6e08 100644 --- a/admin/templatetags/admin_extras.py +++ b/admin/templatetags/admin_extras.py @@ -121,6 +121,12 @@ def domains_menu(selection, user): "url" : reverse(admin.views.domains), "label" : _("Domains"), "img" : static_url("pics/domains.png")}, + {"name" : "newdomalias", + "url" : reverse(admin.views.newdomalias), + "label" : _("New domain alias"), + "img" : static_url("pics/add.png"), + "class" : "boxed", + "rel" : "{handler:'iframe',size:{x:300,y:200}}"}, {"name" : "domaliases", "url" : reverse(admin.views.domaliases), "label" : _("Domain aliases"), @@ -147,6 +153,70 @@ def permissions_menu(user): return render_to_string('common/menu.html', {"entries" : entries, "user" : user}) +def render_actions(actions): + t = template.Template(""" +{% for a in actions %} + + + +{% endfor %} +""") + return t.render(template.Context({ + "actions" : actions + })) + +@register.simple_tag +def domain_actions(user, domid): + actions = [ + {"name" : "editdomain", + "url" : reverse(admin.views.editdomain, args=[domid]), + "img" : static_url("pics/edit.png"), + "title" : _("Edit domain"), + "class" : "boxed", + "rel" : "{handler:'iframe',size:{x:300,y:180}}"}, + {"name" : "deldomain", + "url" : reverse(admin.views.deldomain, args=[domid]), + "img" : static_url("pics/remove.png"), + "title" : _("Delete domain")}, + {"name" : "domaliases", + "url" : reverse(admin.views.domaliases) + "?domid=%s" % domid, + "img" : static_url("pics/alias.png"), + "title" : _("View aliases of this domain")} + ] + return render_actions(actions) + +@register.simple_tag +def domalias_actions(user, aid): + actions = [ + {"name" : "editalias", + "url" : reverse(admin.views.editdomalias, args=[aid]), + "img" : static_url("pics/edit.png"), + "title" : _("Edit alias"), + "class" : "boxed", + "rel" : "{handler:'iframe',size:{x:300,y:220}}"} + ] + return render_actions(actions) + +@register.simple_tag +def mailbox_actions(user, domid, mid): + actions = [ + {"name" : "editmailbox", + "url" : reverse(admin.views.editmailbox, args=[domid, mid]), + "img" : static_url("pics/edit.png"), + "title" : _("Edit mailbox"), + "class" : "boxed", + "rel" : "{handler:'iframe',size:{x:300,y:280}}"}, + {"name" : "deleteMb", + "url" : reverse(admin.views.delmailbox, args=[domid, mid]), + "img" : static_url("pics/remove.png"), + "title" : _("Delete mailbox")}, + {"name" : "aliases", + "url" : reverse("mbox-aliases", args=[domid, mid]), + "img" : static_url("pics/alias.png"), + "title" : _("View this mailbox aliases")}, + ] + return render_actions(actions) + @register.simple_tag def loadadminextmenu(user): menu = events.raiseQueryEvent("AdminMenuDisplay", target="admin_menu_box", diff --git a/admin/urls.py b/admin/urls.py index ada055539..046b44176 100644 --- a/admin/urls.py +++ b/admin/urls.py @@ -7,8 +7,9 @@ urlpatterns = patterns('modoboa.admin.views', (r'^domains/(?P\d+)/edit/$', 'editdomain'), (r'^domains/(?P\d+)/delete/$', 'deldomain'), - (r'^aliases/$', "domaliases"), - (r'^aliases/new/(?P\d+)/', 'newdomalias'), + (r'^domaliases/$', "domaliases"), + (r'^domaliases/new/', 'newdomalias'), + (r'^domaliases/edit/(?P\d+)/', 'editdomalias'), (r'^domains/(?P\d+)/newmailbox/$', 'newmailbox'), (r'^domains/(?P\d+)/editmailbox/(?P\d+)/$', 'editmailbox'), diff --git a/admin/views.py b/admin/views.py index 1bf7def11..abaab4705 100644 --- a/admin/views.py +++ b/admin/views.py @@ -54,28 +54,36 @@ def domains(request): }) @login_required -def domaliases(request, dom_id=None): - domaliases = DomainAlias.objects.all() +def domaliases(request): + if request.GET.has_key("domid"): + domain = Domain.objects.get(pk=request.GET["domid"]) + domaliases = DomainAlias.objects.filter(target=request.GET["domid"]) + else: + domain = None + domaliases = DomainAlias.objects.all() return _render(request, 'admin/domaliases.html', { - "domaliases" : domaliases + "domaliases" : domaliases, "domain" : domain }) @login_required -def newdomalias(request, dom_id): - domain = Domain.objects.get(pk=dom_id) +def newdomalias(request): if request.method == "POST": form = DomainAliasForm(request.POST) error = None if form.is_valid(): - if DomainAlias.objects.filter(name=request.POST["name"]): - error = _("Alias with this name already exists") + domalias = form.save(commit=False) + if Domain.objects.filter(name=domalias.name): + error = _("A domain with this name already exists") else: - domalias = form.save(commit=False) - domalias.save() - ctx = _ctx_ok(reverse(admin.views.domaliases)) - messages.info(request, _("Domain alias created"), fail_silently=True) - return HttpResponse(simplejson.dumps(ctx), - mimetype="application/json") + try: + domalias.save() + except IntegrityError: + error = _("Alias with this name already exists") + else: + ctx = _ctx_ok(reverse(admin.views.domaliases)) + messages.info(request, _("Domain alias created"), fail_silently=True) + return HttpResponse(simplejson.dumps(ctx), + mimetype="application/json") content = _render_to_string(request, "admin/newdomalias.html", { "form" : form, "error" : error }) @@ -86,6 +94,37 @@ def newdomalias(request, dom_id): "form" : form }) +@login_required +def editdomalias(request, alias_id): + domalias = DomainAlias.objects.get(pk=alias_id) + if request.method == "POST": + form = DomainAliasForm(request.POST, instance=domalias) + error = None + if form.is_valid(): + ndomalias = form.save(commit=False) + if Domain.objects.filter(name=ndomalias.name): + error = _("A domain with this name already exists") + else: + try: + ndomalias.save() + except IntegrityError: + error = _("Alias with this name already exists") + else: + ctx = _ctx_ok(reverse(admin.views.domaliases)) + messages.info(request, _("Domain alias updated"), fail_silently=True) + return HttpResponse(simplejson.dumps(ctx), + mimetype="application/json") + content = _render_to_string(request, "admin/editdomalias.html", { + "form" : form, "error" : error + }) + ctx = getctx("ko", content=content) + return HttpResponse(simplejson.dumps(ctx), mimetype="application/json") + + form = DomainAliasForm(instance=domalias) + return _render(request, 'admin/editdomalias.html', { + "form" : form, "domalias" : domalias + }) + @login_required @permission_required("admin.add_domain") def newdomain(request): diff --git a/templates/admin/domains.html b/templates/admin/domains.html index edd9e56cc..6b298cf35 100644 --- a/templates/admin/domains.html +++ b/templates/admin/domains.html @@ -28,23 +28,7 @@ {% for dom in domains %} - - {% url admin.views.editdomain dom.id as edit_url %} - - - - {% url admin.views.deldomain dom.id as del_url %} - - - - {% url admin.views.newdomalias dom.id as new_url %} - - - - - {% url admin.views.mailboxes dom.id as domurl %} + {% domain_actions user dom.id %} {{ dom.name }} {{ dom.mboxcounter }} {{ dom.quota }} {% trans "MB" %} diff --git a/templates/admin/domaliases.html b/templates/admin/domaliases.html index 53b47326a..a50611fc3 100644 --- a/templates/admin/domaliases.html +++ b/templates/admin/domaliases.html @@ -5,7 +5,9 @@ {% endblock %} -{% block middletitle %}{% trans "Available aliases" %}{% endblock %} +{% block middletitle %} +{% trans "Domain aliases" %}{% if domain %} ({% trans "for" %} {{ domain.name }}){% endif %} +{% endblock %} {% block menu %}{% domains_menu "domaliases" user %}{% endblock %} {% block content %} {% if messages %}{% display_messages messages %}{% endif %} @@ -21,8 +23,8 @@ {% trans "Enabled" %} {% for domalias in domaliases %} - - + + {% domalias_actions user domalias.id %} {{ domalias.name }} {{ domalias.target.name }} {{ domalias.enabled|yesno }} diff --git a/templates/admin/editdomalias.html b/templates/admin/editdomalias.html new file mode 100644 index 000000000..1827d0fa2 --- /dev/null +++ b/templates/admin/editdomalias.html @@ -0,0 +1,17 @@ +{% extends "layout_simple.html" %} +{% load i18n %} +{% block html_head %} + +{% endblock %} +{% block content %} +

{% trans "Edit domain alias" %}

+{% if error %}
{{ error }}
{% endif %} +{% url admin.views.editdomalias domalias.id as box_url %} +
+ {% include "common/genericform.html" %} +
+
+ +
+
+{% endblock %} diff --git a/templates/admin/mailboxes.html b/templates/admin/mailboxes.html index d704b3d34..d3bfcc412 100644 --- a/templates/admin/mailboxes.html +++ b/templates/admin/mailboxes.html @@ -19,27 +19,7 @@ {% for mb in mailboxes %} - - {% url admin.views.editmailbox domain.id mb.id as edit_url %} - - - - {% url admin.views.delmailbox domain.id mb.id as del_url %} - - - - {% url admin.views.newalias domain.id as alias_url %} - - - - {% url mbox-aliases domain.id mb.id as aliases_url %} - - - - + {% mailbox_actions user domain.id mb.id %} {{ mb.name }} {{ mb.address }}@{{ mb.domain.name }} {{ mb.quota }} {% trans "MB" %}