Quarantine plugin refactoring. It is now working like the webmail plugin, ie with an anchor based ajax navigation. What is broken for the moment:

* search functionality,
 * headers do not appear while displaying a mail.

New message system. (see infobox.js)
This commit is contained in:
tonio
2010-04-02 19:07:37 +02:00
parent 6b542225d7
commit 0252cebb4e
20 changed files with 530 additions and 254 deletions
+105 -65
View File
@@ -8,6 +8,7 @@ import email
import re
import os
from django.http import HttpResponseRedirect, HttpResponse
from django.template import Template, Context
from django.utils import simplejson
from django.conf.urls.defaults import *
from django.utils.translation import ugettext as _, ungettext
@@ -15,10 +16,11 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.decorators \
import login_required
from mailng.lib import events, parameters
from mailng.lib import _render, _ctx_ok, _ctx_ko, decode
from mailng.lib import _render, _ctx_ok, _ctx_ko, decode, getctx
from mailng.lib import db
from mailng.admin.models import Mailbox
from lib import AMrelease
from templatetags.amextras import *
from sql_listing import *
def init():
@@ -40,21 +42,71 @@ def menu(**kwargs):
return []
@login_required
def index(request, message=None):
start = time.time()
def _listing(request, internal=False, filter=None):
#start = time.time()
if not request.user.is_superuser:
mb = Mailbox.objects.get(user=request.user.id)
filter = ["&maddr.email='%s'" % mb.full_address]
if filter is None:
filter = ["&maddr.email='%s'" % mb.full_address]
else:
filter += ["&maddr.email='%s'" % mb.full_address]
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
request.session["page"] = pageid # ?? nécessaire
lst = SQLlisting(filter, baseurl="listing/", empty=internal)
if internal:
return lst.render(request, pageid=int(pageid))
page = lst.paginator.getpage(pageid)
if page:
content = lst.fetch(request, page.id_start, page.id_stop)
navbar = lst.render_navbar(page)
else:
filter = None
try:
pageid = request.GET["page"]
if pageid == "":
pageid = 1
except KeyError:
pageid = 1
lst = SQLlisting(filter)
return lst.render(request, pageid=int(pageid), start=start)
content = _("Empty quarantine")
navbar = ""
ctx = getctx("ok", listing=content, navbar=navbar,
menu=quar_menu("", request.user.get_all_permissions()))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def index(request, message=None):
return _listing(request, True)
# @login_required
# def getmailcontent(request, mail_id):
# from mailng.lib.email_listing import Email
# conn = db.getconnection("amavis_quarantine")
# status, cursor = db.execute(conn, """
# SELECT mail_text
# FROM quarantine
# WHERE quarantine.mail_id='%s'
# """ % mail_id)
# content = ""
# for part in cursor.fetchall():
# content += part[0]
# msg = email.message_from_string(content)
# links = request.GET.has_key("links") and request.GET["links"] or "0"
# mode = request.GET.has_key("mode") and request.GET["mode"] or "plain"
# mail = Email(msg, mode, links)
# return mail.render(request)
# @login_required
# def viewmail(request, mail_id):
# conn = db.getconnection("amavis_quarantine")
# status, cursor = db.execute(conn, """
# SELECT mail_text
# FROM quarantine
# WHERE quarantine.mail_id='%s'
# """ % mail_id)
# content = ""
# for part in cursor.fetchall():
# content += part[0]
# msg = email.message_from_string(content)
# ctx = getctx("ok", )
# return _render(request, 'amavis_quarantine/viewmail.html', {
# "headers" : msg, "alert" : msg.get("X-Amavis-Alert"),
# "mail_id" : mail_id, "page_id" : request.session["page"],
# "params" : request.GET
# })
@login_required
def getmailcontent(request, mail_id):
@@ -73,25 +125,25 @@ WHERE quarantine.mail_id='%s'
links = request.GET.has_key("links") and request.GET["links"] or "0"
mode = request.GET.has_key("mode") and request.GET["mode"] or "plain"
mail = Email(msg, mode, links)
return mail.render(request)
return _render(request, "common/viewmail.html", {
"headers" : "",
"mailbody" : mail.body,
"pre" : mail.pre
})
@login_required
def viewmail(request, mail_id):
conn = db.getconnection("amavis_quarantine")
status, cursor = db.execute(conn, """
SELECT mail_text
FROM quarantine
WHERE quarantine.mail_id='%s'
""" % mail_id)
content = ""
for part in cursor.fetchall():
content += part[0]
msg = email.message_from_string(content)
return _render(request, 'amavis_quarantine/viewmail.html', {
"headers" : msg, "alert" : msg.get("X-Amavis-Alert"),
"mail_id" : mail_id, "page_id" : request.GET["page"],
"params" : request.GET
})
args = ""
for kw in ["mode", "links"]:
if kw in request.GET.keys():
args += args != "" and "&" or "?"
args += "%s=%s" % (kw, request.GET[kw])
content = Template("""
<iframe width="100%" frameBorder="0" src="{{ url }}" id="mailcontent"></iframe>
""").render(Context({"url" : reverse(getmailcontent, args=[mail_id]) + args}))
menu = viewm_menu("", request.session, mail_id, request.user.get_all_permissions())
ctx = getctx("ok", menu=menu, listing=content)
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def viewheaders(request, mail_id):
@@ -129,7 +181,9 @@ def delete(request, mail_id, count=1):
count) % {"count" : count}
else:
message = error
return _redirect_to_index(request, message, count)
ctx = getctx("ok", url="?page=%s" % request.session["page"], message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def release(request, mail_id, count=1):
@@ -152,13 +206,6 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN
error = None
for k, values in emails.iteritems():
result = amr.sendreq(k, values["secret"], *values["rcpts"])
# cmd = "/tmp/amavisd-release "
# cmd += "%s %s" % (k, values["secret"])
# for rcpt in values["rcpts"]:
# cmd += " %s" % rcpt
# cmd += "\n"
# result = os.system(cmd)
# if re.search("250 [^\s]+ Ok", result):
if result:
count += 1
else:
@@ -170,7 +217,9 @@ WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN
count) % {"count" : count}
else:
message = error
return _redirect_to_index(request, message, count)
ctx = getctx("ok", url="?page=%s" % request.session["page"], message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def process(request):
@@ -182,19 +231,13 @@ def process(request):
ids += "'%s'" % id
if ids == "":
return HttpResponseRedirect(reverse(index))
print "Ok c pas vide"
if request.POST["action"] == "release":
release(request, ids, count)
return release(request, ids, count)
if request.POST["action"] == "delete":
delete(request, ids, count)
try:
pagenum = int(request.POST.get('pagenum', '1'))
except ValueError:
pagenum = 1
ctx = _ctx_ok(reverse(index) + "?page=%s" % pagenum)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
return delete(request, ids, count)
@login_required
def search(request):
@@ -211,19 +254,16 @@ def search(request):
filter += " OR "
filter += "msgs.%s LIKE '%%%s%%'" % (c, pattern)
filter = "&(%s)" % filter
lst = SQLlisting([filter])
try:
pageid = request.GET["page"]
if pageid == "":
pageid = 1
except KeyError:
pageid = 1
page = lst.paginator.getpage(pageid)
if page:
content = lst.fetch(page.id_start, page.id_stop).render(request)
navbar = lst.render_navbar(page)
else:
content = "Empty quarantine"
navbar = ""
ctx = {"status" : "ok", "listing" : content, "navbar" : navbar}
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
return _listing(request, filter=filter)
# lst = SQLlisting([filter])
# page = lst.paginator.getpage(1)
# if page:
# content = lst.fetch(page.id_start, page.id_stop).render(request)
# navbar = lst.render_navbar(page)
# else:
# content = "Empty quarantine"
# navbar = ""
# ctx = {"status" : "ok", "listing" : content, "navbar" : navbar}
# return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@@ -6,6 +6,7 @@ from mailng.lib import tables, db
from mailng.lib.email_listing import MBconnector, EmailListing
class Qtable(tables.Table):
tableid = "emails"
idkey = "mailid"
selection = tables.SelectionColumn("selection", first=True)
type = tables.Column("type", label=_("Type"))
@@ -83,6 +84,8 @@ LIMIT %d,%d
class SQLlisting(EmailListing):
tpl = "amavis_quarantine/index.html"
tbltype = Qtable
deflocation = "listing/"
defcallback = "updatelisting"
def __init__(self, filter, **kwargs):
self.mbc = SQLconnector(filter)
+129 -78
View File
@@ -3,9 +3,10 @@
{% load amextras %}
{% block css %}
#searchbox {
float: left;
/*float: left;*/ /* Marche pas ici?! obligé de le faire en JS sous FF */
margin-right: 10px;
width: 250px;
z-index: 2;
position: relative;
}
#searchbox img {
@@ -17,87 +18,137 @@
#searchparams {
background: white;
padding: 5px;
width: 150px;
width: 90%;
border-bottom: 5px solid #CCCCCC;
border-left: 5px solid #CCCCCC;
border-right: 5px solid #CCCCCC;
}
thead tr {
position: relative;
z-index: 1;
}
{% endblock %}
{% block js %}
mysubmit = function(event, name) {
event.stop();
new Element('input', {
'type' : 'hidden', 'name' : "action", style: "display:none", 'value' : name
}).inject($("listingform"), "top");
{% url extensions.amavis_quarantine.main.process as actionurl %}
$("listingform").set("action", "{{ actionurl }}");
$("listingform").set("send", {
mysubmit = function(event, name) {
event.stop();
new Element('input', {
'type' : 'hidden', 'name' : "action", style: "display:none", 'value' : name
}).inject($("listingform"), "top");
{% url extensions.amavis_quarantine.main.process as actionurl %}
$("listingform").set("action", "{{ actionurl }}");
$("listingform").set("send", {
onSuccess : function(res) {
response = JSON.decode(res);
location.href = response.url;
response = JSON.decode(res);
actioncallback(response);
}
});
$("listingform").send();
}
updatehash = function(evt) {
evt.stop();
current_anchor.parse_string(evt.target.get("href"), true).setparams(navparams);
current_anchor.update();
}
appendhash = function(evt) {
evt.stop();
location.hash += evt.target.get("href");
}
updateparams = function(evt) {
evt.stop();
current_anchor.updateparams(evt.target.get("href"));
current_anchor.update();
}
register_callback("_listing", function(resp) {
updatelisting(resp);
$$("a[name=release]").addEvent("click", function(event) {
if (!checkSelection("selection", "{% trans "Release this selection?" %}")) {
event.stop();
return;
}
mysubmit(event, "release");
});
$$("a[name=delete]").addEvent("click", function(event) {
if (!checkSelection("selection", "{% trans "Delete this selection?" %}")) {
event.stop();
return;
}
mysubmit(event, "delete");
});
var myFx = new Fx.Slide($("searchparams"));
myFx.hide();
$("searchopts").addEvent("click", function(event) {
myFx.cancel();
myFx.toggle();
});
$$("input[name=scriteria]").addEvent("click", function(event) {
myFx.cancel();
myFx.toggle();
});
$("searchfield").addEvent("change", function(event) {
var criteria = "";
$$("input[name=scriteria]:checked").each(function(obj) {
criteria = obj.value;
});
var url = "search"
+ "?pattern=" + $("searchfield").value
+ "&criteria=" + criteria;
current_anchor.parse_string(url, true).setparams(navparams);
current_anchor.update();
/*new Request.JSON({url: "{{ s_url }}", onSuccess: function(resp) {
$("listing").set("html", resp.listing);
$("navbar").set("html", resp.navbar);
{% url extensions.amavis_quarantine.main.viewmail as view_url %}
bindRows("{{ view_url }}", "{{ current_page }}");
}}).get({"pattern" : $("searchfield").value, "criteria" : criteria});*/
});
$("searchfield").addEvent("click", function(event) {
$("searchfield").select();
});
$("searchfield").addEvent("blur", function(event) {
if ($("searchfield").value == "") {
$("searchfield").set("value", "{% trans "Search..." %}");
}
});
$("searchbox").setStyle("float", "left");
$$("tr").addEvent("dblclick", viewmail);
});
actioncallback = function(resp) {
$("listing").set("html", "");
$("menubar").set("html", "");
$("navbar").set("html", "");
if (resp.status == "ok") {
infobox.show(resp.message, "green", 1);
} else {
infobox.show(resp.message, "red", 1);
}
current_anchor.parse_string(resp.url, true).setparams(navparams);
current_anchor.update(1);
}
actionclick = function(evt) {
evt.stop();
new Request.JSON({
url: evt.target.get("href"),
onSuccess: actioncallback
}).get();
}
register_callback("viewmail", function(resp) {
updatelisting(resp);
$$("a[name=back]").addEvent("click", updatehash);
$$("a[name=delete]").addEvent("click", actionclick);
$$("a[name=release]").addEvent("click", actionclick);
$$("a[name=viewmode]").addEvent("click", updateparams);
setDivHeight("mailcontent", 5, 0);
});
$("listingform").send();
}
$$("a[name=delete]").addEvent("click", function(event) {
if (!checkSelection("selection", "{% trans "Delete this selection?" %}")) {
event.stop();
return;
}
mysubmit(event, "delete");
});
$$("a[name=release]").addEvent("click", function(event) {
if (!checkSelection("selection", "{% trans "Release this selection?" %}")) {
event.stop();
return;
}
mysubmit(event, "release");
});
var myFx = new Fx.Slide($("searchparams"));
myFx.hide();
$("searchopts").addEvent("click", function(event) {
myFx.cancel();
myFx.toggle();
});
$$("input[name=scriteria]").addEvent("click", function(event) {
myFx.cancel();
myFx.toggle();
});
$("searchfield").addEvent("change", function(event) {
var criteria = "";
$$("input[name=scriteria]:checked").each(function(obj) {
criteria = obj.value;
});
{% url extensions.amavis_quarantine.main.search as s_url %}
new Request.JSON({url: "{{ s_url }}", onSuccess: function(resp) {
$("listing").set("html", resp.listing);
$("navbar").set("html", resp.navbar);
{% url extensions.amavis_quarantine.main.viewmail as view_url %}
bindRows("{{ view_url }}", "{{ current_page }}");
}}).get({"pattern" : $("searchfield").value, "criteria" : criteria});
});
$("searchfield").addEvent("click", function(event) {
$("searchfield").select();
});
$("searchfield").addEvent("blur", function(event) {
if ($("searchfield").value == "") {
$("searchfield").set("value", "{% trans "Search..." %}");
}
});
{% url extensions.amavis_quarantine.main.viewmail as view_url %}
bindRows("{{ view_url }}", "{{ current_page }}");
{% endblock %}
{% block middletitle %}{% trans "Quarantine" %}{% endblock %}
{% block menu %}
{% quar_menu "" perms %}
<div id="searchbox">
<img src="/static/pics/search.png" id="searchopts" />
<input type="text" name="searchfield" id="searchfield" value="{% trans "Search..." %}" />
<div id="searchparams">
<input type="radio" name="scriteria" value="from_addr" checked>{% trans "From address" %}<br/>
<input type="radio" name="scriteria" value="subject">{% trans "Subject" %}<br/>
<input type="radio" name="scriteria" value="from_addr,subject">{% trans "Both" %}<br/>
</div>
</div>
{% endblock %}
@@ -26,6 +26,8 @@ window.addEvent("domready", function() {
var iheight = spage.y - stable.y - slogo.y;
$("mailcontent").setStyle("height", iheight + "px");
parse_menubar("menubar");
});
</script>
@@ -7,25 +7,22 @@ from mailng.extensions import amavis_quarantine
register = template.Library()
@register.simple_tag
def viewm_menu(selection, mail_id, page_id, perms):
def viewm_menu(selection, session, mail_id, perms):
options_menu = [
{"name" : "plain",
{"name" : "viewmode",
"label" : _("View as plain text"),
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
+ "?page=%s&mode=plain" % page_id},
{"name" : "html",
"url" : "?mode=plain&links=0"},
{"name" : "viewmode",
"label" : _("View as HTML"),
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
+ "?page=%s&mode=html" % page_id},
{"name" : "links",
"url" : "?mode=html&links=0"},
{"name" : "viewmode",
"label" : _("Activate links"),
"url" : reverse(amavis_quarantine.main.viewmail, args=[mail_id])
+ "?page=%s&mode=html&links=1" % page_id}
"url" : "?mode=html&links=1"}
]
entries = [
{"name" : "back",
"url" : reverse(amavis_quarantine.main.index) + "?page=%s" % page_id,
"url" : "?page=%s" % session["page"],
"img" : "/static/pics/back.png",
"label" : _("Back to list")},
{"name" : "headers",
@@ -35,20 +32,19 @@ def viewm_menu(selection, mail_id, page_id, perms):
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:600,y:500}}"},
{"name" : "release",
"url" : reverse(amavis_quarantine.main.release, args=[mail_id])
+ "?page=%s" % page_id,
"url" : reverse(amavis_quarantine.main.release, args=[mail_id]),
"img" : "/static/pics/release.png",
"label" : _("Release"),
"confirm" : _("Release this message?")},
{"name" : "delete",
"url" : reverse(amavis_quarantine.main.delete, args=[mail_id])
+ "?page=%s" % page_id,
"url" : reverse(amavis_quarantine.main.delete, args=[mail_id]),
"img" : "/static/pics/remove.png",
"label" : _("Delete"),
"confirm" : _("Delete this message?")},
{"name" : "options",
"label" : _("Options"),
"img" : "/static/pics/settings.png",
"class" : "menubardropdown",
"menu" : options_menu}
]
@@ -69,6 +65,8 @@ def quar_menu(selection, perms):
"label" : _("Delete")},
]
return render_to_string('main/menu.html',
menu = render_to_string('main/menu.html',
{"selection" : selection, "entries" : entries,
"perms" : perms})
searchbar = render_to_string('common/email_searchbar.html', {})
return menu + searchbar
+3 -4
View File
@@ -2,13 +2,12 @@ from django.conf.urls.defaults import *
urlpatterns = patterns('mailng.extensions.amavis_quarantine.main',
(r'^$', 'index'),
url(r'^viewmail/(?P<mail_id>[\w\-\+]+)/$', 'viewmail',
name="viewmail_std"),
url(r'^viewmail/$', 'viewmail', name="viewmail_null"),
(r'^listing/$', '_listing'),
(r'^getmailcontent/(?P<mail_id>[\w\-\+]+)/$', 'getmailcontent'),
(r'^viewheaders/(?P<mail_id>[\w\-\+]+)/$', 'viewheaders'),
(r'^(?P<mail_id>[\w\-\+]+)/headers/$', 'viewheaders'),
(r'^process/$', 'process'),
(r'^delete/(?P<mail_id>[\w\-\+]+)/$', 'delete'),
(r'^release/(?P<mail_id>[\w\-\+]+)/$', 'release'),
(r'^search/', 'search'),
(r'^(?P<mail_id>[\w\-\+]+)/$', 'viewmail'),
)
+4 -4
View File
@@ -248,12 +248,12 @@ class IMAPconnector(object):
class ImapListing(EmailListing):
tpl = "webmail/index.html"
tbltype = WMtable
deflocation = "INBOX/"
defcallback = "wm_updatelisting"
def __init__(self, user, password, baseurl=None, **kwargs):
def __init__(self, user, password, **kwargs):
self.mbc = IMAPconnector(user=user, password=password)
EmailListing.__init__(self, **kwargs)
if baseurl:
self.paginator.baseurl = baseurl
EmailListing.__init__(self, **kwargs)
def getfolders(self):
md_folders = [{"name" : "INBOX", "icon" : "overview.png"},
+7 -13
View File
@@ -10,7 +10,7 @@ from django.core.urlresolvers import reverse
from django.conf.urls.defaults import include
from django.contrib.auth.decorators import login_required
from mailng.admin.models import Mailbox
from mailng.lib import events, parameters, _render, _render_error
from mailng.lib import events, parameters, _render, _render_error, getctx
from imap_listing import *
from forms import *
from templatetags.webextras import *
@@ -51,13 +51,6 @@ def menu(**kwargs):
def userlogin(**kwargs):
kwargs["request"].session["password"] = kwargs["password"]
def getctx(status, level=1, **kwargs):
callername = sys._getframe(level).f_code.co_name
ctx = {"status" : status, "callback" : callername}
for kw, v in kwargs.iteritems():
ctx[kw] = v
return ctx
@login_required
def folder(request, name, updatenav=True):
if not name:
@@ -76,7 +69,7 @@ def folder(request, name, updatenav=True):
order = request.session["navparams"]["order"]
lst = ImapListing(request.user.username, request.session["password"],
name, folder=name, order=order)
baseurl=name, folder=name, order=order)
page = lst.paginator.getpage(request.session["page"])
if page:
content = lst.fetch(request, page.id_start, page.id_stop)
@@ -94,10 +87,11 @@ def index(request):
navp = request.session.has_key("navparams") \
and request.session["navparams"] or {}
lst = ImapListing(request.user.username, request.session["password"],
"INBOX", navparams=navp, folder="INBOX")
baseurl="INBOX", navparams=navp, folder="INBOX",
empty=True)
except Exception as exp:
return _render_error(request, {"error" : exp})
return lst.render(request, empty=True)
return lst.render(request)
def fetchmail(request, folder, mail_id, all=False):
res = IMAPconnector(request).fetch(start=mail_id, folder=folder, all=all)
@@ -128,7 +122,7 @@ def getmailcontent(request, folder, mail_id):
except KeyError:
pageid = "1"
folder, imapid = msg["imapid"].split("/")
return _render(request, "webmail/viewmail.html", {
return _render(request, "common/viewmail.html", {
"headers" : email.render_headers(folder, mail_id),
"folder" : folder, "imapid" : imapid, "mailbody" : email.body,
"pre" : email.pre
@@ -270,7 +264,7 @@ def reply(request, folder, mail_id):
else:
form.fields["subject"].initial = "Re: %s" % email.Subject
textheader = "%s %s" % (email.From, _("wrote:"))
return render_compose(request, form, reverse(reply, args[folder, mail_id]),
return render_compose(request, form, reverse(reply, args=[folder, mail_id]),
textheader, body)
@login_required
+24 -37
View File
@@ -1,6 +1,20 @@
{% extends "common/email_listing.html" %}
{% load i18n %}
{% block css %}
#listing {
position: absolute;
left: 155px;
right: 0px;
top: 130px;
height: expression(document.body.clientHeight - 35 + "px");
overflow: auto;
}
html > body #listing {
position: fixed;
bottom: 35px;
}
#leftcol {
float: left;
width: 150px;
@@ -97,22 +111,9 @@ tr.selected {
{% endblock %}
{% block js %}
navparams = new Hash({
{% for k, v in navparams.items %}
{{ k }} : "{{ v }}",
{% endfor %}
});
wm_updatelisting = function(resp) {
updatelisting(resp);
updatelisting = function(resp) {
if ($defined(resp.menu)) {
$("menubar").set("html", resp.menu);
parse_menubar("menubar");
}
$("listing").set("html", resp.listing);
if ($defined(resp.navbar)) {
$("navbar").set("html", resp.navbar);
$("navbar").getChildren("a").addEvent("click", navbarcallback);
}
$$("a[name=compose]").addEvent("click", loadCompose);
$$("a[name=empty]").addEvent("click", empty);
if (!checkSelection()) {
@@ -123,7 +124,7 @@ tr.selected {
empty = function(event) {
event.stop();
new Request.JSON({url : event.target.get("href"), onSuccess : function(resp) {
updatelisting(resp);
wm_updatelisting(resp);
}}).get();
}
@@ -147,17 +148,8 @@ tr.selected {
obj.getParent().addClass("selected");
}
{% url extensions.webmail.main.folder as view_url %}
viewmail = function(event) {
event.stop();
if (event.target.parentNode.id) {
var url = event.target.parentNode.id + "/";
event.target.parentNode.setStyle("background", "#ffffcc");
current_anchor.baseurl(url).update();
}
}
register_callback("viewmail", function(resp) {
updatelisting(resp, "hidden");
wm_updatelisting(resp, "hidden");
$$("a[name=back]").addEvent("click", loadFolder);
$$("a[name=reply]").addEvent("click", reply);
$$("a[name=replyall]").addEvent("click", replyall);
@@ -173,7 +165,7 @@ tr.selected {
});
compose_callback = function(resp) {
updatelisting(resp);
wm_updatelisting(resp);
window.addEvent("resize", function(evt) {
setDivHeight("id_body", $("mailheader").getSize().y, 0);
});
@@ -184,7 +176,7 @@ tr.selected {
onSuccess: function(resp) {
resp = JSON.decode(resp);
if (resp.status == "ko") {
updatelisting(resp);
wm_updatelisting(resp);
window.fireEvent("resize");
return;
}
@@ -228,7 +220,7 @@ tr.selected {
current_anchor.update();
}
register_callback("folder", function(resp) {
updatelisting(resp);
wm_updatelisting(resp);
if (navparams.has("order")) {
src = navparams.get("order").charAt(0) == "-" ? "down_arrow.png" : "up_arrow.png";
th = $$("th[id=" + navparams.get("order").substring(1) + "]");
@@ -341,18 +333,10 @@ tr.selected {
});
});
navbarcallback = function(event) {
event.stop();
current_anchor.setparams(navparams);
current_anchor.parse_string(event.target.getParent().get("href")).update();
}
foldercallback = function(event) {
select(event.target);
loadFolder(event, event.target);
}
ajaxListener("INBOX/", updatelisting);
$$("a[name=loadfolder]").addEvent("click", foldercallback);
{% endblock %}
{% block middletitle %}{% trans "Webmail" %}{% endblock %}
@@ -374,3 +358,6 @@ tr.selected {
</ul>
</div>
{% endblock %}
{% block menu %}
{% endblock %}
@@ -1,54 +0,0 @@
{% load i18n %}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head profile="http://www.w3.org/2005/10/profile">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="/static/stylesheets/box.css" />
<style type="text/css">
body {
margin: 5px;
}
#mailcontent {
width: 100%;
border: 0px transparent none;
margin: 0;
}
table#emailheaders {
width: 100%;
border-collapse: collapse;
margin-bottom: 10px;
}
#emailheaders td,
#emailheaders th {
height: 22px;
text-align: left;
padding-left: 10px;
border: 1px solid #ccc;
}
#emailheaders td {
font-size: 1em;
}
#emailheaders th {
background: #F7F9Fb;
}
#emailheaders a, #emailheaders a:visited {
color: blue;
text-decoration: none;
}
#emailheaders a:hover {
text-decoration: underline;
}
pre {
font-size: medium;
}
</style>
</head>
<body>
<div id="table-container">
{{ headers }}
</div>
{% if pre %}<pre>{% endif %}{{ mailbody }}{% if pre %}</pre>{% endif %}
</body>
</html>
@@ -75,6 +75,17 @@ def listing_menu(selection, folder, perms):
"url" : reverse(webmail.main.compose),
"img" : "/static/pics/edit.png",
"label" : _("New message")},
{"name" : "actions",
"img" : "/static/pics/domains.png",
"label" : _("Mark messages"),
"class" : "menubardropdown",
"menu" : [
{"name" : "mark-read",
"label" : _("As read")},
{"name" : "mark-unread",
"label" : _("As unread")}
]
}
]
if folder in ["Trash"]:
entries += [