OpenCustomFilteringOnSelect
This commit is contained in:
parent
f9154a8374
commit
948a4ced8f
|
@ -17,6 +17,7 @@ from .actions import SendMailboxEmail
|
||||||
from .filters import HasMailboxListFilter, HasForwardListFilter, HasAddressListFilter
|
from .filters import HasMailboxListFilter, HasForwardListFilter, HasAddressListFilter
|
||||||
from .forms import MailboxCreationForm, MailboxChangeForm, AddressForm
|
from .forms import MailboxCreationForm, MailboxChangeForm, AddressForm
|
||||||
from .models import Mailbox, Address, Autoresponse
|
from .models import Mailbox, Address, Autoresponse
|
||||||
|
from .widgets import OpenCustomFilteringOnSelect
|
||||||
|
|
||||||
|
|
||||||
class AutoresponseInline(admin.StackedInline):
|
class AutoresponseInline(admin.StackedInline):
|
||||||
|
@ -81,12 +82,17 @@ class MailboxAdmin(ChangePasswordAdminMixin, SelectAccountAdminMixin, ExtendedMo
|
||||||
self.actions = ()
|
self.actions = ()
|
||||||
return super(MailboxAdmin, self).get_actions(request)
|
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):
|
def get_fieldsets(self, request, obj=None):
|
||||||
fieldsets = super(MailboxAdmin, self).get_fieldsets(request, obj)
|
fieldsets = super(MailboxAdmin, self).get_fieldsets(request, obj)
|
||||||
if obj and obj.filtering == obj.CUSTOM:
|
if obj and obj.filtering == obj.CUSTOM:
|
||||||
# not collapsed filtering when exists
|
# not collapsed filtering when exists
|
||||||
fieldsets = copy.deepcopy(fieldsets)
|
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']):
|
elif '_to_field' in parse_qs(request.META['QUERY_STRING']):
|
||||||
# remove address from popup
|
# remove address from popup
|
||||||
fieldsets = list(copy.deepcopy(fieldsets))
|
fieldsets = list(copy.deepcopy(fieldsets))
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
|
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
@ -19,11 +20,13 @@ from .models import Address
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class FilteringMixin(object):
|
class SieveFilteringMixin(object):
|
||||||
def generate_filter(self, mailbox, context):
|
def generate_filter(self, mailbox, context):
|
||||||
name, content = mailbox.get_filtering()
|
name, content = mailbox.get_filtering()
|
||||||
if name == 'REDIRECT':
|
for box in re.findall(r'fileinto\s+"([^"]+)"', content):
|
||||||
self.append("doveadm mailbox create -u %(user)s Spam" % context)
|
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
|
context['filtering_path'] = settings.MAILBOXES_SIEVE_PATH % context
|
||||||
if content:
|
if content:
|
||||||
context['filtering'] = ('# %(banner)s\n' + filtering) % context
|
context['filtering'] = ('# %(banner)s\n' + filtering) % context
|
||||||
|
@ -33,7 +36,7 @@ class FilteringMixin(object):
|
||||||
self.append("echo '' > %(filtering_path)s" % context)
|
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.
|
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
|
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, "'", '"')
|
return replace(context, "'", '"')
|
||||||
|
|
||||||
|
|
||||||
class DovecotPostfixPasswdVirtualUserBackend(FilteringMixin, ServiceController):
|
class DovecotPostfixPasswdVirtualUserBackend(SieveFilteringMixin, ServiceController):
|
||||||
"""
|
"""
|
||||||
WARNING: This backends is not fully implemented
|
WARNING: This backends is not fully implemented
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -17,14 +17,14 @@ MAILBOXES_DOMAIN_MODEL = Setting('MAILBOXES_DOMAIN_MODEL', 'domains.Domain',
|
||||||
|
|
||||||
|
|
||||||
MAILBOXES_HOME = Setting('MAILBOXES_HOME',
|
MAILBOXES_HOME = Setting('MAILBOXES_HOME',
|
||||||
'/home/%(name)s/',
|
'/home/%(name)s',
|
||||||
help_text="Available fromat names: <tt>%s</tt>" % ', '.join(_names),
|
help_text="Available fromat names: <tt>%s</tt>" % ', '.join(_names),
|
||||||
validators=[Setting.string_format_validator(_names)],
|
validators=[Setting.string_format_validator(_names)],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
MAILBOXES_SIEVE_PATH = Setting('MAILBOXES_SIEVE_PATH',
|
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: <tt>%s</tt>" % ', '.join(_names),
|
help_text="Available fromat names: <tt>%s</tt>" % ', '.join(_names),
|
||||||
validators=[Setting.string_format_validator(_backend_names)],
|
validators=[Setting.string_format_validator(_backend_names)],
|
||||||
)
|
)
|
||||||
|
|
33
orchestra/contrib/mailboxes/widgets.py
Normal file
33
orchestra/contrib/mailboxes/widgets.py
Normal file
|
@ -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")]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
)
|
|
@ -87,4 +87,3 @@ class ReadOnlyFormMixin(object):
|
||||||
if hasattr(self, 'instance'):
|
if hasattr(self, 'instance'):
|
||||||
original = getattr(self.instance, name, original)
|
original = getattr(self.instance, name, original)
|
||||||
field.widget.original = original
|
field.widget.original = original
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue