mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
@@ -16,9 +16,9 @@ header_operators = [("contains", _("contains"), "string"),
|
||||
|
||||
class FilterForm(forms.Form):
|
||||
name = forms.CharField(label=_("Name"))
|
||||
match_type = forms.ChoiceField(choices=[("allof", _("Match all of the following")),
|
||||
("anyof", _("Match any of the following")),
|
||||
("all", _("Match all messages"))],
|
||||
match_type = forms.ChoiceField(choices=[("allof", _("All of the following")),
|
||||
("anyof", _("Any of the following")),
|
||||
("all", _("All messages"))],
|
||||
initial="anyof",
|
||||
widget=forms.RadioSelect)
|
||||
|
||||
@@ -158,19 +158,20 @@ def build_filter_form_from_qdict(request):
|
||||
qdict["match_type"] = request.POST["match_type"]
|
||||
cpt = 0
|
||||
i = 0
|
||||
while True:
|
||||
if cpt == int(request.POST["conds"]):
|
||||
break
|
||||
if request.POST.has_key("cond_target_%d" % i):
|
||||
qdict["cond_target_%d" % cpt] = request.POST["cond_target_%d" % i]
|
||||
qdict["cond_operator_%d" % cpt] = request.POST["cond_operator_%d" % i]
|
||||
qdict["cond_value_%d" % cpt] = request.POST["cond_value_%d" % i]
|
||||
condtarget = request.POST["cond_target_%d" % i]
|
||||
condop = request.POST["cond_operator_%d" % i]
|
||||
condvalue = request.POST["cond_value_%d" % i]
|
||||
conditions += [(condtarget, condop, condvalue)]
|
||||
cpt += 1
|
||||
i += 1
|
||||
if qdict["match_type"] != "all":
|
||||
while True:
|
||||
if cpt == int(request.POST["conds"]):
|
||||
break
|
||||
if request.POST.has_key("cond_target_%d" % i):
|
||||
qdict["cond_target_%d" % cpt] = request.POST["cond_target_%d" % i]
|
||||
qdict["cond_operator_%d" % cpt] = request.POST["cond_operator_%d" % i]
|
||||
qdict["cond_value_%d" % cpt] = request.POST["cond_value_%d" % i]
|
||||
condtarget = request.POST["cond_target_%d" % i]
|
||||
condop = request.POST["cond_operator_%d" % i]
|
||||
condvalue = request.POST["cond_value_%d" % i]
|
||||
conditions += [(condtarget, condop, condvalue)]
|
||||
cpt += 1
|
||||
i += 1
|
||||
cpt = 0
|
||||
i = 0
|
||||
while True:
|
||||
@@ -197,12 +198,16 @@ def build_filter_form_from_qdict(request):
|
||||
return FilterForm(conditions, actions, request, qdict)
|
||||
|
||||
def build_filter_form_from_filter(request, name, fobj):
|
||||
from sievelib.commands import SizeCommand
|
||||
from sievelib.commands import SizeCommand, TrueCommand
|
||||
|
||||
match_type = fobj["test"].name
|
||||
conditions = []
|
||||
for t in fobj["test"]["tests"]:
|
||||
if isinstance(t, SizeCommand):
|
||||
if isinstance(t, TrueCommand):
|
||||
match_type = "all"
|
||||
conditions += [("Subject", "contains", "")]
|
||||
break
|
||||
elif isinstance(t, SizeCommand):
|
||||
conditions += [("size", t["comparator"][1:], t["limit"])]
|
||||
else:
|
||||
conditions += [(t["header-names"].strip('"'),
|
||||
|
||||
@@ -26,7 +26,9 @@ class SieveClient(object):
|
||||
authmech = parameters.get_admin("AUTHENTICATION_MECH")
|
||||
if authmech == "AUTO":
|
||||
authmech = None
|
||||
if not self.msc.connect(user, password, use_starttls, authmech):
|
||||
try:
|
||||
ret = self.msc.connect(user, password, use_starttls, authmech)
|
||||
except Error, e:
|
||||
return False, _("Connection to MANAGESIEVE server failed, check your configuration")
|
||||
return True, None
|
||||
|
||||
@@ -37,7 +39,10 @@ class SieveClient(object):
|
||||
pass
|
||||
else:
|
||||
return
|
||||
ret, msg = self.login(user, password)
|
||||
try:
|
||||
ret, msg = self.login(user, password)
|
||||
except Error, e:
|
||||
raise ConnectionError(e)
|
||||
if not ret:
|
||||
raise ConnectionError(msg)
|
||||
|
||||
@@ -52,6 +57,7 @@ class SieveClient(object):
|
||||
return content
|
||||
p = Parser()
|
||||
if not p.parse(content):
|
||||
print "Parse error????"
|
||||
return None
|
||||
fs = FiltersSet(name)
|
||||
fs.from_parser_result(p)
|
||||
|
||||
@@ -102,7 +102,8 @@
|
||||
|
||||
#actionlist {
|
||||
border: 1px solid #CCC;
|
||||
padding-top: 10px;
|
||||
padding: 5px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
#condlist ul {
|
||||
@@ -120,6 +121,8 @@
|
||||
|
||||
#matchtype {
|
||||
margin-bottom: 10px;
|
||||
margin-left: 7px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
#submit {
|
||||
@@ -129,6 +132,11 @@
|
||||
div.item {
|
||||
margin-bottom: 10px;
|
||||
margin-left: 5px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.item input[type=text], div.item select {
|
||||
width: 190px;
|
||||
}
|
||||
|
||||
div.item input, div.item select {
|
||||
@@ -149,7 +157,8 @@ ul.errors {
|
||||
|
||||
.errors li {
|
||||
color: red;
|
||||
font-style: bold;
|
||||
font-weight: bold;
|
||||
font-size: 0.9em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
@@ -191,4 +200,16 @@ ul.errors {
|
||||
.leftbox img {
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a.green {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: green;
|
||||
}
|
||||
|
||||
a.red {
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
color: red;
|
||||
}
|
||||
@@ -181,7 +181,9 @@ function toggle_filter_state(event) {
|
||||
url: this.get("href"),
|
||||
onSuccess: function(response) {
|
||||
if (response.status == "ok") {
|
||||
this.set("html", response.respmsg);
|
||||
this.set("html", response.label);
|
||||
this.set("class", "");
|
||||
this.addClass(response.color);
|
||||
} else {
|
||||
infobox.error(respmsg.respmsg);
|
||||
}
|
||||
|
||||
@@ -13,12 +13,22 @@ var action_templates = null;
|
||||
var da = null;
|
||||
var dc = null;
|
||||
|
||||
function matchtype_cb(event) {
|
||||
if (this.get("value") == "all") {
|
||||
$$("#condlist div[class=item]").slide("out");
|
||||
} else {
|
||||
$("hide").setStyle("display", "block");
|
||||
$$("#condlist div[class=item]").slide("in");
|
||||
}
|
||||
}
|
||||
|
||||
function initform() {
|
||||
var clist = $$("select[name*=cond_target_]");
|
||||
var alist = $$("select[name*=action_name_]");
|
||||
|
||||
dc = new DynamicCondition(clist, {
|
||||
templates: cond_templates
|
||||
templates: cond_templates,
|
||||
parentContainer: $("condlist")
|
||||
});
|
||||
da = new DynamicAction(alist, {
|
||||
templates: action_templates,
|
||||
@@ -27,6 +37,8 @@ function initform() {
|
||||
|
||||
clist.addEvent("change", dc.onTargetChange.bind(dc));
|
||||
alist.addEvent("change", da.onNameChange.bind(da));
|
||||
|
||||
$$("input[name=match_type]").addEvent("click", matchtype_cb);
|
||||
}
|
||||
|
||||
$(document).addEvent("domready", function() {
|
||||
@@ -60,13 +72,16 @@ $(document).addEvent("domready", function() {
|
||||
<h2>{% trans "Conditions" %}</h2>
|
||||
<div id="condlist">
|
||||
<div id="matchtype">
|
||||
<label>{% trans "Match type" %}:</label>
|
||||
{{ form.match_type }}{% display_errors form.match_type.errors %}
|
||||
<div class="spacer"></div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
{% if hideconds %}<div id="hide" style="display:none">{% endif %}
|
||||
{% for ec in conds_nb %}
|
||||
{% display_condition form ec %}
|
||||
{% endfor %}
|
||||
{% if hideconds %}</div>{% endif %}
|
||||
</div>
|
||||
<h2>{% trans "Actions" %}</h2>
|
||||
<div id="actionlist">
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<td>{{ filter.name }}</td>
|
||||
<td>
|
||||
<a name="togglestate"
|
||||
class={% if filter.enabled %}"green"{% else %}"red"{% endif %}
|
||||
href="{% url extensions.sievefilters.views.toggle_filter_state fs.name filter.name %}">
|
||||
{{ filter.enabled|yesno }}
|
||||
</a>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<script type="text/javascript" src="{{ MEDIA_URL }}sievefilters/js/lib.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}sievefilters/css/style.css" />
|
||||
<script type="text/javascript">
|
||||
var current_anchor = new AnchorNavigation("{{ active_script }}", {
|
||||
var current_anchor = new AnchorNavigation("{{ default_script }}", {
|
||||
defcallback: loadfs
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ $(document).addEvent("domready", function() {
|
||||
<label>{% trans "Filters sets" %}</label>
|
||||
<select id="curfset">
|
||||
{% if active_script %}
|
||||
<option value="{{ active_script }}">{{ active_script }} (active)</option>
|
||||
<option value="{{ active_script }}">{{ active_script }} ({% trans "active" %})</option>
|
||||
{% endif %}
|
||||
{% for script in scripts %}
|
||||
<option value="{{ script }}">{{ script }}</option>
|
||||
|
||||
@@ -34,7 +34,7 @@ def fset_menu(mode, setname):
|
||||
"label" : _("New filter"),
|
||||
"url" : reverse(views.newfilter, args=[setname]),
|
||||
"class" : "boxed",
|
||||
"rel" : "{handler:'iframe',size:{x:650,y:400}}"},
|
||||
"rel" : "{handler:'iframe',size:{x:700,y:400}}"},
|
||||
|
||||
]
|
||||
if mode == "raw":
|
||||
@@ -130,18 +130,21 @@ def display_action(form, cnt):
|
||||
action = form["action_name_%d" % cnt]
|
||||
values = []
|
||||
acnt = 0
|
||||
verrors = []
|
||||
while True:
|
||||
try:
|
||||
values += [form["action_arg_%d_%d" % (cnt, acnt)]]
|
||||
print display_errors(form["action_arg_%d_%d" % (cnt, acnt)].errors)
|
||||
if len(form["action_arg_%d_%d" % (cnt, acnt)].errors):
|
||||
verrors += form["action_arg_%d_%d" % (cnt, acnt)].errors
|
||||
acnt += 1
|
||||
except KeyError:
|
||||
break
|
||||
t = template.Template("""
|
||||
<div class="item">
|
||||
{{ afield }}{% for v in values %}{{ v }}{% endfor %}
|
||||
{{ afield }}{% for v in values %}{{ v }}{% endfor %}{{ verrors }}
|
||||
</div>
|
||||
""")
|
||||
return t.render(template.Context({
|
||||
"afield" : action, "values" : values
|
||||
"afield" : action, "values" : values,
|
||||
"verrors" : display_errors(verrors)
|
||||
}))
|
||||
|
||||
@@ -4,21 +4,30 @@ from django.http import HttpResponse
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.core.urlresolvers import reverse
|
||||
from modoboa.lib import _render, _render_to_string, \
|
||||
from modoboa.lib import _render, _render_to_string, _render_error, \
|
||||
ajax_response, ajax_simple_response, parameters
|
||||
from modoboa.lib.connections import ConnectionError
|
||||
from modoboa.auth.lib import get_password
|
||||
from lib import *
|
||||
from forms import *
|
||||
|
||||
@login_required
|
||||
def index(request, tplname="sievefilters/index.html"):
|
||||
sc = SieveClient(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
try:
|
||||
sc = SieveClient(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
except ConnectionError, e:
|
||||
return _render_error(request, user_context={"error" : e})
|
||||
|
||||
active_script, scripts = sc.listscripts()
|
||||
if active_script is None:
|
||||
active_script = ""
|
||||
default_script = scripts[0] if len(scripts) else ""
|
||||
else:
|
||||
default_script = active_script
|
||||
return _render(request, tplname, {
|
||||
"active_script" : active_script,
|
||||
"default_script" : default_script,
|
||||
"scripts" : sorted(scripts),
|
||||
})
|
||||
|
||||
@@ -42,10 +51,17 @@ def getfs(request, name):
|
||||
sc = SieveClient(user=request.user.username,
|
||||
password=request.session["password"])
|
||||
editormode = parameters.get_user(request.user, "EDITOR_MODE")
|
||||
error = None
|
||||
try:
|
||||
content = sc.getscript(name, format=editormode)
|
||||
except SieveClientError, e:
|
||||
return ajax_response(request, "ko", respmsg=str(e))
|
||||
error = str(e)
|
||||
else:
|
||||
if content is None:
|
||||
error = _("Failed to retrieve filters set")
|
||||
|
||||
if error is not None:
|
||||
return ajax_response(request, "ko", respmsg=error)
|
||||
|
||||
if editormode == "raw":
|
||||
return ajax_response(request, template="sievefilters/rawfilter.html",
|
||||
@@ -67,13 +83,17 @@ def submitfilter(request, setname, okmsg, tplname, tplctx, update=False, sc=None
|
||||
password=request.session["password"])
|
||||
fset = sc.getscript(setname, format="fset")
|
||||
conditions, actions = form.tofilter()
|
||||
match_type = form.cleaned_data["match_type"]
|
||||
if match_type == "all":
|
||||
match_type = "anyof"
|
||||
conditions = [("true",)]
|
||||
if not update:
|
||||
fset.addfilter(form.cleaned_data["name"], conditions, actions,
|
||||
form.cleaned_data["match_type"])
|
||||
match_type)
|
||||
else:
|
||||
fset.updatefilter(request.POST["oldname"],
|
||||
form.cleaned_data["name"], conditions, actions,
|
||||
form.cleaned_data["match_type"])
|
||||
match_type)
|
||||
sc.pushscript(fset.name, str(fset))
|
||||
return ajax_response(request, respmsg=okmsg, ajaxnav=True)
|
||||
tplctx = build_filter_ctx(tplctx, form)
|
||||
@@ -107,6 +127,8 @@ def editfilter(request, setname, fname, tplname="sievefilters/filter.html"):
|
||||
form = build_filter_form_from_filter(request, fname, f)
|
||||
ctx = build_filter_ctx(ctx, form)
|
||||
ctx["oldname"] = fname
|
||||
if form.fields["match_type"].initial == "all":
|
||||
ctx["hideconds"] = True
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@@ -206,16 +228,22 @@ def toggle_filter_state(request, setname, fname):
|
||||
if fset.is_filter_disabled(fname):
|
||||
ret = fset.enablefilter(fname)
|
||||
newstate = _("yes")
|
||||
color = "green"
|
||||
else:
|
||||
ret = fset.disablefilter(fname)
|
||||
newstate = _("no")
|
||||
color = "red"
|
||||
if not ret:
|
||||
pass
|
||||
sc.pushscript(setname, str(fset))
|
||||
except SieveClientError, e:
|
||||
return ajax_response(request, "ko", respmsg=str(e))
|
||||
|
||||
return ajax_response(request, respmsg=newstate)
|
||||
return ajax_simple_response({
|
||||
"status" : "ok",
|
||||
"label" : newstate,
|
||||
"color" : color
|
||||
})
|
||||
|
||||
def move_filter(request, setname, fname, direction):
|
||||
sc = SieveClient(user=request.user.username,
|
||||
|
||||
@@ -3,7 +3,7 @@ var DynamicTextInput = new Class({
|
||||
Implements: [Options],
|
||||
|
||||
options: {
|
||||
|
||||
parentContainer: null
|
||||
},
|
||||
|
||||
initialize: function(targets, options) {
|
||||
@@ -62,13 +62,16 @@ var DynamicTextInput = new Class({
|
||||
id: "delbtn_" + this.nextid,
|
||||
src: parent.static_url("pics/remove.png")
|
||||
});
|
||||
|
||||
this.nextid += 1;
|
||||
delbtn.setStyles({
|
||||
"float" : "right",
|
||||
"margin-top": "2px"
|
||||
});
|
||||
field[0].inject(this.target.getParent(), "after");
|
||||
if (!this.options.parentContainer) {
|
||||
field[0].inject(this.target.getParent(), "after");
|
||||
} else {
|
||||
field[0].inject(this.options.parentContainer);
|
||||
}
|
||||
delbtn.inject(field[1], "after");
|
||||
delbtn.addEvent("click", this.removeelement.bind(this));
|
||||
this.target.set("value", "");
|
||||
|
||||
Reference in New Issue
Block a user