Simple way to display IMAP errors:

* raise a specific exception in the imap connector,
 * Add a simple middleware to catch this exception and return a specific response that will be correctly displayed by the webmail.

see #127
This commit is contained in:
Antoine Nguyen
2011-03-28 17:12:12 +02:00
parent 2535bca0fc
commit 53f1cb5899
7 changed files with 68 additions and 28 deletions
+16 -3
View File
@@ -18,6 +18,19 @@ from modoboa.lib import decode, tables, imap_utf7, Singleton
from modoboa.lib.email_listing import MBconnector, EmailListing, Email
from modoboa.lib import tables, imap_utf7, parameters, static_url, u2u_decode
class WebmailError(Exception):
errorexpr = re.compile("\[([^\]]+)\]\s*([^\.]+)")
def __init__(self, reason, ajax=False):
m = WebmailError.errorexpr.match(reason)
if m is None:
self.reason = reason
else:
self.reason = "%s: %s" % (_("Server response"), m.group(2))
self.ajax = ajax
def __str__(self):
return self.reason
class WMtable(tables.Table):
tableid = "emails"
@@ -315,20 +328,20 @@ class IMAPconnector(object):
name = "%s.%s" % (parent, name)
typ, data = self.m.create(self._encodefolder(name))
if typ == "NO":
return False
raise WebmailError(data[0])
return True
def rename_folder(self, oldname, newname):
typ, data = self.m.rename(self._encodefolder(oldname),
self._encodefolder(newname))
if typ == "NO":
return False
raise WebmailError(data[0], ajax=True)
return True
def delete_folder(self, name):
typ, data = self.m.delete(self._encodefolder(name))
if typ == "NO":
return False
raise WebmailError(data[0])
return True
def getquota(self, folder):
+11
View File
@@ -0,0 +1,11 @@
# coding: utf-8
from modoboa.lib import ajax_response
from modoboa.extensions.webmail.lib import WebmailError
class WebmailErrorMiddleware(object):
def process_exception(self, request, exception):
if not isinstance(exception, WebmailError):
return None
return ajax_response(request, status="ko",
error=str(exception), norefresh=True)
+17 -10
View File
@@ -59,14 +59,8 @@ function viewmail_cb(resp) {
$$("a[name=forward]").addEvent("click", forward_loader);
$$("a[name=delete]").addEvent("click", function(event) {
var lnk = event.target;
event.stop();
new Request.JSON({
url: lnk.get("href"), onSuccess: function(resp) {
current_anchor.parse_string(resp.next).update();
select_folder($$("a[href=" + current_anchor.getbaseurl() + "]"));
}
}).get();
simple_request(lnk.get("href"));
});
$$("a[name=activate_links]").addEvent("click", function(evt) {
evt.stop();
@@ -219,9 +213,22 @@ function simple_request(url, params) {
new Request.JSON({
url : url,
onSuccess : function(response) {
get_callback("folder")(response);
infobox.info(gettext("Done"));
infobox.hide(1);
if (response.status == "ok") {
if (!$defined(response.next)) {
get_callback("folder")(response);
}
infobox.info(gettext("Done"));
if ($defined(response.next)) {
(function(response) {
current_anchor.parse_string(response.next).update();
select_folder($$("a[href=" + current_anchor.getbaseurl() + "]"));
}).delay(500, this, response);
} else {
infobox.hide(1);
}
} else {
infobox.error(response.error);
}
}
}).get(params);
}
@@ -29,6 +29,7 @@
{% endblock %}
{% block content %}
<div class="title"><h1>{{ title }}</h1></div>
<div id="error" class="error">{{ error }}</div>
<form action="" method="POST" id="{{ fname }}" name="{{ fname }}">
<input type="hidden" name="oldname" value="{{ oldname }}" />
{% include "common/genericform.html" %}
+7 -8
View File
@@ -105,7 +105,8 @@ def folder(request, name, updatenav=True):
optparams["criteria"] = request.session["criteria"]
else:
optparams["reset"] = True
optparams["elems_per_page"] = int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))
optparams["elems_per_page"] = \
int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))
lst = ImapListing(request.user, request.session["password"],
baseurl=name, folder=name, order=order,
**optparams)
@@ -457,9 +458,9 @@ def newfolder(request, tplname="webmail/folder.html"):
if form.is_valid():
pf = request.POST.has_key("parent_folder") \
and request.POST["parent_folder"] or None
if mbc.create_folder(form.cleaned_data["name"], pf):
return ajax_response(request, ajaxnav=True)
mbc.create_folder(form.cleaned_data["name"], pf)
return ajax_response(request, ajaxnav=True)
ctx["form"] = form
ctx["selected"] = None
return ajax_response(request, status="ko", template=tplname, **ctx)
@@ -492,8 +493,7 @@ def editfolder(request, tplname="webmail/folder.html"):
or (pf is not None and pf != oldparent):
newname = form.cleaned_data["name"] if pf is None \
else "%s.%s" % (pf, form.cleaned_data["name"])
if not mbc.rename_folder(request.POST["oldname"], newname):
raise Exception
mbc.rename_folder(request.POST["oldname"], newname)
extra["url"] = newname
return ajax_response(request, ajaxnav=True, **extra)
except Exception:
@@ -518,6 +518,5 @@ def delfolder(request):
return
mbc = IMAPconnector(user=request.user.username,
password=request.session["password"])
if mbc.delete_folder(request.GET["name"]):
return ajax_response(request)
mbc.delete_folder(request.GET["name"])
return ajax_response(request, status="ko")
+6 -1
View File
@@ -74,7 +74,9 @@ def getctx(status, level=1, callback=None, **kwargs):
ctx[kw] = v
return ctx
def ajax_response(request, status="ok", url="", ajaxnav=False, template=None, **kwargs):
def ajax_response(request, status="ok", error=None,
url="", ajaxnav=False, norefresh=False,
template=None, **kwargs):
"""Ajax response shortcut
Simple shortcut that sends an JSON response. If a template is
@@ -95,10 +97,13 @@ def ajax_response(request, status="ok", url="", ajaxnav=False, template=None, **
else:
content = ""
jsonctx = {"status" : status, "content" : content}
if error is not None:
jsonctx["error"] = error
if ajaxnav:
jsonctx["ajaxnav"] = True
if url != "":
jsonctx["url"] = url
jsonctx["norefresh"] = norefresh
return HttpResponse(simplejson.dumps(jsonctx), mimetype="application/json")
def decode(s, encodings=('utf8', 'latin1', 'windows-1252', 'ascii'), charset=None):
+10 -6
View File
@@ -49,15 +49,19 @@ function ajax_submit(event) {
new Request({
method: form.get("method"),
data: data,
onSuccess: function(responseText) {
onSuccess: function(responseText){
var response = JSON.decode(responseText);
if (response.status == "ko") {
$(document.body).set("html", response.content);
$(document.body).addEvent("submit", ajax_submit);
if ($defined(error_callbacks[myid])) {
error_callbacks[myid]();
}
if ($defined(response.norefresh) && response.norefresh == true) {
$("error").set("html", response.error);
} else {
$(document.body).set("html", response.content);
$(document.body).addEvent("submit", ajax_submit);
if ($defined(error_callbacks[myid])) {
error_callbacks[myid]();
}
}
} else {
if ($defined(response.ajaxnav)) {
if ($defined(response.url)) {