New layout. Not the prettiest one but we need to release something :p

We'll do better for a future version.

see #260
This commit is contained in:
Antoine Nguyen
2012-07-04 10:16:14 +02:00
parent 910b336dc7
commit 69440e512f
7 changed files with 114 additions and 100 deletions
+12
View File
@@ -200,6 +200,18 @@ Raised when an existing domain alias is about to be deleted.
* ``domain_alias`` is a ``DomainAlias`` instance
DomainModified
==============
Raised when a domain has been modified.
*Callback prototype*::
def callback(domain): pass
* ``domain`` is the modified ``Domain`` instance, it contains an extra
``oldname`` field which contains the old domain name
ExtDisabled
===========
+5 -1
View File
@@ -114,9 +114,13 @@ def editdomain(request, dom_id, tplname="admin/editdomainform.html"):
"formid" : "domform",
"domain" : domain}
if request.method == "POST":
def editdomain_cb(user, newdomain):
events.raiseEvent("DomainModified", domain)
domain.oldname = domain.name
form = DomainForm(request.user, request.POST, instances=instances)
return _validate_domain(request, form, _("Domain modified"), commonctx, tplname,
tpl_form_name="tabs")
tpl_form_name="tabs", callback=editdomain_cb)
commonctx["tabs"] = DomainForm(request.user, instances=instances)
commonctx["domadmins"] = domadmins
+35 -52
View File
@@ -1,6 +1,11 @@
# coding: utf-8
"""
Amavis quarantine manager (SQL based)
Amavis management frontend.
Provides:
* SQL quarantine management
* Per-domain settings
"""
from django.utils.translation import ugettext as _, ugettext_lazy
@@ -20,22 +25,18 @@ class Amavis(ModoExtension):
"""Init function
Only run once, when the extension is enabled. We create records
for existing mailboxes in order Amavis considers them local.
for existing domains to let Amavis consider them local.
"""
from modoboa.admin.models import Mailbox
from models import Users
from modoboa.admin.models import Domain
from models import Users, Policy
for mb in Mailbox.objects.all():
for dom in Domain.objects.all():
try:
u = Users.objects.get(email=mb.full_address)
u = Users.objects.get(email="@%s" % dom.name)
except Users.DoesNotExist:
u = Users()
u.email = mb.full_address
u.fullname = mb.user.fullname
u.local = "1"
u.priority = 7
u.policy_id = 1
u.save()
p = Policy.objects.create(policy_name=dom.name)
Users.objects.create(email="@%s" % dom.name, fullname=dom.name,
local="1", priority=7, policy=p)
def load(self):
parameters.register_admin(
@@ -76,9 +77,9 @@ class Amavis(ModoExtension):
help=ugettext_lazy("Sets the maximum number of messages displayed in a page")
)
def destroy(self):
events.unregister("UserMenuDisplay", menu)
parameters.unregister_app("amavis")
def destroy(self):
events.unregister("UserMenuDisplay", menu)
parameters.unregister_app("amavis")
exts_pool.register_extension(Amavis)
@@ -94,6 +95,24 @@ def menu(target, user):
]
return []
@events.observe("CreateDomain")
def on_create_domain(user, domain):
from models import Users, Policy
p = Policy.objects.create(policy_name=domain.name)
Users.objects.create(email="@%s" % domain.name, fullname=domain.name,
local="1", priority=7, policy=p)
@events.observe("DomainModified")
def on_domain_modified(domain):
if domain.oldname != domain.name:
from models import Users
u = Users.objects.get(email="@%s" % domain.oldname)
u.email = "@%s" % domain.name
u.fullname = domain.name
u.policy.policy_name = domain.name
u.policy.save()
u.save()
@events.observe("DeleteDomain")
def on_delete_domain(domain):
from models import Users
@@ -105,42 +124,6 @@ def on_delete_domain(domain):
u.policy.delete()
u.delete()
@events.observe("CreateMailbox")
def create_user_record(user, mailbox):
from models import Users
try:
Users.objects.get(email=mailbox.full_address)
except Users.DoesNotExist:
u = Users()
u.email = mailbox.full_address
u.fullname = mailbox.user.fullname
u.local = "1"
u.priority = 7
u.policy_id = 1
u.save()
@events.observe("ModifyMailbox")
def modify_user_record(mailbox, oldmailbox):
if mailbox.full_address == oldmailbox.full_address:
return
u = Users.objects.get(email=oldmailbox.full_address)
u.email = mailbox.full_address
u.save()
@events.observe("DeleteMailbox")
def remove_user_record(mailboxes):
from models import Users
from modoboa.admin.models import Mailbox
if isinstance(mailboxes, Mailbox):
mailboxes = [mailboxes]
for mailbox in mailboxes:
try:
Users.objects.get(email=mailbox.full_address).delete()
except Users.DoesNotExist:
pass
@events.observe("GetStaticContent")
def extra_static_content(user):
if parameters.get_admin("USER_CAN_RELEASE") == "yes" \
+33 -38
View File
@@ -3,38 +3,32 @@
from django import forms
from models import Policy, Users
from django.utils.translation import ugettext_lazy
from django.forms.widgets import RadioSelect, RadioInput
from django.utils.html import conditional_escape
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
def is_yes(v): return v == 'Y'
class CustomRadioInput(RadioInput):
def __unicode__(self):
if 'id' in self.attrs:
label_for = ' for="%s_%s"' % (self.attrs['id'], self.index)
else:
label_for = ''
choice_label = conditional_escape(force_unicode(self.choice_label))
return mark_safe(u'<label class="radio inline" %s>%s %s</label>' % (label_for, self.tag(), choice_label))
class CustomInputField(forms.CharField):
"""Custom <input> field
class InlineRadioRenderer(RadioSelect.renderer):
def __iter__(self):
for i, choice in enumerate(self.choices):
yield CustomRadioInput(self.name, self.value, self.attrs.copy(), choice, i)
Most of the columns defined by amavis use the *char* type even if
they only support 2 values (Y/N). As we want to display them using
checkboxes, we need to make some modifications in order that
values are correctly interpreted.
"""
def validate(self, value):
value = "N" if not value else "Y"
super(CustomInputField, self).validate(value)
def render(self):
return mark_safe(u'\n'.join([u'%s\n' % force_unicode(w) for w in self]))
def clean(self, value):
value = "N" if not value else "Y"
return super(CustomInputField, self).clean(value)
class InlineRadioSelect(RadioSelect):
renderer = InlineRadioRenderer
class DomainPolicyForm(forms.ModelForm):
bypass_spam_checks = CustomInputField(label=ugettext_lazy("Spam filter"),
widget=forms.CheckboxInput(check_test=is_yes),
help_text=ugettext_lazy("enabled"))
bypass_virus_checks = CustomInputField(label=ugettext_lazy("Virus filter"),
widget=forms.CheckboxInput(check_test=is_yes),
help_text=ugettext_lazy("enabled"))
bypass_banned_checks = CustomInputField(label=ugettext_lazy("Banned filter"),
widget=forms.CheckboxInput(check_test=is_yes),
help_text=ugettext_lazy("enabled"))
spam_modifies_subj = CustomInputField(label=ugettext_lazy("Spam marker"),
widget=forms.CheckboxInput(check_test=is_yes),
help_text=ugettext_lazy("tag subject"))
class Meta:
model = Policy
@@ -42,8 +36,12 @@ class DomainPolicyForm(forms.ModelForm):
'spam_tag2_level', 'spam_modifies_subj',
'spam_kill_level', 'bypass_banned_checks')
widgets = {
'bypass_virus_checks' : InlineRadioSelect(),
'bypass_spam_checks' : InlineRadioSelect(),
'spam_tag2_level' : forms.TextInput(attrs={'class' : 'span1'}),
'spam_modifies_subj' : InlineRadioSelect(),
'spam_kill_level' : forms.TextInput(attrs={'class' : 'span1'}),
'bypass_banned_checks' : InlineRadioSelect(),
}
def __init__(self, *args, **kwargs):
@@ -55,20 +53,17 @@ class DomainPolicyForm(forms.ModelForm):
except (Users.DoesNotExist, Policy.DoesNotExist), e:
del kwargs["instance"]
super(DomainPolicyForm, self).__init__(*args, **kwargs)
for f in self.fields.keys():
self.fields[f].required = False
def save(self, user, commit=True):
p = super(DomainPolicyForm, self).save(commit=False)
if commit:
p.save()
try:
u = Users.objects.get(policy__id=p.id)
except Users.DoesNotExist:
u = Users()
u.email = "@%s" % self.domain.name
u.fullname = self.domain.name
u.policy = p
u.local = "1"
u.priority = 7
u.save()
p.save()
try:
u = Users.objects.get(policy=p)
except Users.DoesNotExist:
u = Users.objects.get(email="@%s" % self.domain.name)
u.policy = p
p.save()
return p
+24 -5
View File
@@ -69,17 +69,36 @@ class Msgrcpt(models.Model):
unique_together = ("mail", "rid")
class Policy(models.Model):
id = models.AutoField(primary_key=True)
policy_name = models.CharField(max_length=96, blank=True)
virus_lover = models.CharField(max_length=3, blank=True)
spam_lover = models.CharField(max_length=3, blank=True)
banned_files_lover = models.CharField(max_length=3, blank=True)
bad_header_lover = models.CharField(max_length=3, blank=True)
bypass_virus_checks = models.CharField(max_length=3, blank=True)
bypass_spam_checks = models.CharField(max_length=3, blank=True)
bypass_banned_checks = models.CharField(max_length=3, blank=True)
bypass_virus_checks = models.CharField(
ugettext_lazy("Virus filter"), default='',
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
max_length=3,
help_text=ugettext_lazy("Bypass virus checks or not. Choose 'default' to use global settings.")
)
bypass_spam_checks = models.CharField(
ugettext_lazy("Spam filter"), default='',
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
max_length=3,
help_text=ugettext_lazy("Bypass spam checks or not. Choose 'default' to use global settings.")
)
bypass_banned_checks = models.CharField(
ugettext_lazy("Banned filter"), default='',
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
max_length=3,
help_text=ugettext_lazy("Bypass banned checks or not. Choose 'default' to use global settings.")
)
bypass_header_checks = models.CharField(max_length=3, blank=True)
spam_modifies_subj = models.CharField(max_length=3, blank=True)
spam_modifies_subj = models.CharField(
ugettext_lazy("Spam marker"), default='',
choices=(('Y', 'yes'), ('N', 'no'), ('', 'default')),
max_length=3,
help_text=ugettext_lazy("Modify spam subject or not. Choose 'default' to use global settings.")
)
virus_quarantine_to = models.CharField(max_length=192, blank=True)
spam_quarantine_to = models.CharField(max_length=192, blank=True)
banned_quarantine_to = models.CharField(max_length=192, blank=True)
@@ -1,6 +1,6 @@
{% load i18n libextras %}
{% render_field form.bypass_virus_checks "inline" %}
{% render_field form.bypass_spam_checks "inline" %}
{% render_field form.bypass_virus_checks %}
{% render_field form.bypass_spam_checks %}
<div class="control-group">
<label class="control-label">{% trans "Thresholds" %}</label>
<div class="controls spaced">
@@ -8,5 +8,5 @@
{{ form.spam_kill_level }} <span class="help-inline">{% trans "or more throw spam message away" %}</span>
</div>
</div>
{% render_field form.spam_modifies_subj "inline" %}
{% render_field form.bypass_banned_checks "inline" %}
{% render_field form.spam_modifies_subj %}
{% render_field form.bypass_banned_checks %}
+1
View File
@@ -17,6 +17,7 @@ events = [
"CanCreate",
"CreateDomain",
"DomainModified",
"DeleteDomain",
"DomainAliasCreated",