diff --git a/orchestra/contrib/mailboxes/admin.py b/orchestra/contrib/mailboxes/admin.py
index de5da9e3..80482abd 100644
--- a/orchestra/contrib/mailboxes/admin.py
+++ b/orchestra/contrib/mailboxes/admin.py
@@ -17,6 +17,7 @@ from .actions import SendMailboxEmail
from .filters import HasMailboxListFilter, HasForwardListFilter, HasAddressListFilter
from .forms import MailboxCreationForm, MailboxChangeForm, AddressForm
from .models import Mailbox, Address, Autoresponse
+from .widgets import OpenCustomFilteringOnSelect
class AutoresponseInline(admin.StackedInline):
@@ -81,12 +82,17 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
self.actions = ()
return super(MailboxAdmin, self).get_actions(request)
+ def formfield_for_dbfield(self, db_field, **kwargs):
+ if db_field.name == 'filtering':
+ kwargs['widget'] = OpenCustomFilteringOnSelect()
+ return super(MailboxAdmin, self).formfield_for_dbfield(db_field, **kwargs)
+
def get_fieldsets(self, request, obj=None):
fieldsets = super(MailboxAdmin, self).get_fieldsets(request, obj)
if obj and obj.filtering == obj.CUSTOM:
# not collapsed filtering when exists
fieldsets = copy.deepcopy(fieldsets)
- fieldsets[1][1]['classes'] = fieldsets[0][1]['fields'] + ('open',)
+ fieldsets[1][1]['classes'] = fieldsets[0][1]['fields'] + ('collapse', 'open',)
elif '_to_field' in parse_qs(request.META['QUERY_STRING']):
# remove address from popup
fieldsets = list(copy.deepcopy(fieldsets))
diff --git a/orchestra/contrib/mailboxes/backends.py b/orchestra/contrib/mailboxes/backends.py
index bf39d265..c9b1dcd2 100644
--- a/orchestra/contrib/mailboxes/backends.py
+++ b/orchestra/contrib/mailboxes/backends.py
@@ -1,4 +1,5 @@
import logging
+import re
import textwrap
from django.core.exceptions import ObjectDoesNotExist
@@ -19,11 +20,13 @@ from .models import Address
logger = logging.getLogger(__name__)
-class FilteringMixin(object):
+class SieveFilteringMixin(object):
def generate_filter(self, mailbox, context):
name, content = mailbox.get_filtering()
- if name == 'REDIRECT':
- self.append("doveadm mailbox create -u %(user)s Spam" % context)
+ for box in re.findall(r'fileinto\s+"([^"]+)"', content):
+ context['box'] = box
+ # TODO create mailbox without doveadm (not always installed)
+ self.append("doveadm mailbox create -u %(user)s %(box)s" % context)
context['filtering_path'] = settings.MAILBOXES_SIEVE_PATH % context
if content:
context['filtering'] = ('# %(banner)s\n' + filtering) % context
@@ -33,7 +36,7 @@ class FilteringMixin(object):
self.append("echo '' > %(filtering_path)s" % context)
-class UNIXUserMaildirBackend(FilteringMixin, ServiceController):
+class UNIXUserMaildirBackend(SieveFilteringMixin, ServiceController):
"""
Assumes that all system users on this servers all mail accounts.
If you want to have system users AND mailboxes on the same server you should consider using virtual mailboxes
@@ -94,7 +97,7 @@ class UNIXUserMaildirBackend(FilteringMixin, ServiceController):
return replace(context, "'", '"')
-class DovecotPostfixPasswdVirtualUserBackend(FilteringMixin, ServiceController):
+class DovecotPostfixPasswdVirtualUserBackend(SieveFilteringMixin, ServiceController):
"""
WARNING: This backends is not fully implemented
"""
diff --git a/orchestra/contrib/mailboxes/settings.py b/orchestra/contrib/mailboxes/settings.py
index a315719c..91d977e0 100644
--- a/orchestra/contrib/mailboxes/settings.py
+++ b/orchestra/contrib/mailboxes/settings.py
@@ -17,14 +17,14 @@ MAILBOXES_DOMAIN_MODEL = Setting('MAILBOXES_DOMAIN_MODEL', 'domains.Domain',
MAILBOXES_HOME = Setting('MAILBOXES_HOME',
- '/home/%(name)s/',
+ '/home/%(name)s',
help_text="Available fromat names: %s" % ', '.join(_names),
validators=[Setting.string_format_validator(_names)],
)
MAILBOXES_SIEVE_PATH = Setting('MAILBOXES_SIEVE_PATH',
- os.path.join(MAILBOXES_HOME, 'Maildir/sieve/orchestra.sieve'),
+ os.path.join('%(home)s/Maildir/sieve/orchestra.sieve'),
help_text="Available fromat names: %s" % ', '.join(_names),
validators=[Setting.string_format_validator(_backend_names)],
)
diff --git a/orchestra/contrib/mailboxes/widgets.py b/orchestra/contrib/mailboxes/widgets.py
new file mode 100644
index 00000000..ad92adc8
--- /dev/null
+++ b/orchestra/contrib/mailboxes/widgets.py
@@ -0,0 +1,33 @@
+import textwrap
+
+from django import forms
+
+
+class OpenCustomFilteringOnSelect(forms.Select):
+ def __init__(self, *args, **kwargs):
+ collapse = self.get_dynamic_collapse()
+ attrs = kwargs.get('attrs', {})
+ attrs.update({
+ 'onClick': collapse,
+ 'onChange': collapse,
+ })
+ attrs.update(kwargs.get('attrs', {}))
+ kwargs['attrs'] = attrs
+ super(OpenCustomFilteringOnSelect, self).__init__(*args, **kwargs)
+
+ def get_dynamic_collapse(self):
+ return textwrap.dedent("""\
+ value = this.options[this.selectedIndex].value;
+ fieldset = $(this).closest("fieldset");
+ fieldset = $(".collapse");
+ if ( value == 'CUSTOM' ) {
+ if (fieldset.hasClass("collapsed")) {
+ fieldset.removeClass("collapsed").trigger("show.fieldset", [$(this).attr("id")]);
+ }
+ } else {
+ if (! $(this).closest("fieldset").hasClass("collapsed")) {
+ fieldset.addClass("collapsed").trigger("hide.fieldset", [$(this).attr("id")]);
+ }
+ }
+ """
+ )
diff --git a/orchestra/forms/options.py b/orchestra/forms/options.py
index ed908b5e..e81e68da 100644
--- a/orchestra/forms/options.py
+++ b/orchestra/forms/options.py
@@ -87,4 +87,3 @@ class ReadOnlyFormMixin(object):
if hasattr(self, 'instance'):
original = getattr(self.instance, name, original)
field.widget.original = original
-