mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-25 05:58:42 +01:00
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# coding: utf-8
|
||||
|
||||
from datetime import datetime
|
||||
from django.utils.translation import ugettext as _, ugettext_noop
|
||||
@@ -11,6 +11,7 @@ from models import *
|
||||
|
||||
class Qtable(tables.Table):
|
||||
tableid = "emails"
|
||||
styles = "table-condensed"
|
||||
idkey = "mailid"
|
||||
|
||||
type = tables.Column("type", align="center", width="30px",
|
||||
@@ -81,7 +82,6 @@ class SQLlisting(EmailListing):
|
||||
deflocation = "listing/"
|
||||
defcallback = "updatelisting"
|
||||
reset_wm_url = True
|
||||
table_styles = "table-condensed"
|
||||
|
||||
def __init__(self, user, msgs, filter, **kwargs):
|
||||
if user.group == 'SimpleUsers':
|
||||
|
||||
@@ -94,7 +94,7 @@ def _listing(request):
|
||||
return empty_quarantine(request)
|
||||
|
||||
content = lst.fetch(request, page.id_start, page.id_stop)
|
||||
navbar = lst.render_navbar(page, "listing/")
|
||||
navbar = lst.render_navbar(page, "listing/?")
|
||||
ctx = getctx("ok", listing=content, navbar=navbar,
|
||||
menu=quar_menu("", request.user))
|
||||
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
"""
|
||||
import re
|
||||
from django.utils.translation import ugettext as _
|
||||
from modoboa.lib.exceptions import ModoboaException
|
||||
|
||||
class WebmailError(Exception):
|
||||
class WebmailError(ModoboaException):
|
||||
errorexpr = re.compile("\[([^\]]+)\]\s*([^\.]+)")
|
||||
|
||||
def __init__(self, reason, ajax=False):
|
||||
@@ -20,7 +22,7 @@ class WebmailError(Exception):
|
||||
def __str__(self):
|
||||
return self.reason
|
||||
|
||||
class ImapError(Exception):
|
||||
class ImapError(ModoboaException):
|
||||
def __init__(self, reason):
|
||||
self.reason = reason
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@ from django.utils.translation import ugettext_noop as _
|
||||
|
||||
class ComposeMailForm(forms.Form):
|
||||
from_ = forms.CharField(label=_("From"))
|
||||
to = forms.CharField(label=_("To"), widget=forms.Textarea())
|
||||
cc = forms.CharField(label=_("Cc"), widget=forms.Textarea(), required=False)
|
||||
to = forms.CharField(label=_("To"))
|
||||
cc = forms.CharField(label=_("Cc"), required=False)
|
||||
subject = forms.CharField(label=_("Subject"), max_length=255, required=False)
|
||||
|
||||
origmsgid = forms.CharField(widget=forms.HiddenInput(), required=False)
|
||||
origmsgid = forms.CharField(label="", widget=forms.HiddenInput(), required=False)
|
||||
|
||||
class FolderForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
|
||||
@@ -135,7 +135,7 @@ class IMAPconnector(object):
|
||||
if not status:
|
||||
raise Exception(msg)
|
||||
|
||||
def _cmd(self, name, *args):
|
||||
def _cmd(self, name, *args, **kwargs):
|
||||
"""IMAP command wrapper
|
||||
|
||||
To simplify errors handling, this wrapper calls the
|
||||
@@ -166,9 +166,16 @@ class IMAPconnector(object):
|
||||
raise ImapError(e)
|
||||
if typ == "NO":
|
||||
raise ImapError(data)
|
||||
if not name in self.m.untagged_responses:
|
||||
return None
|
||||
return self.m.untagged_responses.pop(name)
|
||||
if not kwargs.has_key('responses'):
|
||||
if not name in self.m.untagged_responses:
|
||||
return None
|
||||
return self.m.untagged_responses.pop(name)
|
||||
res = []
|
||||
for r in kwargs['responses']:
|
||||
if not r in self.m.untagged_responses:
|
||||
return None
|
||||
res.append(self.m.untagged_responses.pop(r))
|
||||
return res
|
||||
|
||||
def __find_content_in_bodystruct(self, bodystruct, mtype, stype, prefix=""):
|
||||
"""Retrieve the number (index) of a specific part
|
||||
@@ -358,7 +365,6 @@ class IMAPconnector(object):
|
||||
if r'\HasChildren' in flags:
|
||||
descr["path"] = name
|
||||
descr["sub"] = []
|
||||
descr["class"] = "subfolders"
|
||||
result += [descr]
|
||||
from operator import itemgetter
|
||||
return sorted(result, key=itemgetter("name"))
|
||||
@@ -411,7 +417,7 @@ class IMAPconnector(object):
|
||||
"""
|
||||
self._add_flag(mbox, msgset, r'(\Seen)')
|
||||
|
||||
def msgforwarded(self, mailbox, mailid):
|
||||
def msg_forwarded(self, mailbox, mailid):
|
||||
self._add_flag(mailbox, mailid, '($Forwarded)')
|
||||
|
||||
def msg_answered(self, mailbox, mailid):
|
||||
@@ -475,7 +481,8 @@ class IMAPconnector(object):
|
||||
self.quota_limit = self.quota_actual = None
|
||||
return
|
||||
|
||||
data = self._cmd("GETQUOTAROOT", self._encodefolder(mailbox))
|
||||
data = self._cmd("GETQUOTAROOT", self._encodefolder(mailbox),
|
||||
responses=["QUOTAROOT", "QUOTA"])
|
||||
if data is None:
|
||||
self.quota_limit = self.quota_actual = None
|
||||
return
|
||||
|
||||
@@ -26,15 +26,18 @@ from exceptions import *
|
||||
|
||||
class WMtable(tables.Table):
|
||||
tableid = "emails"
|
||||
styles = "table-condensed"
|
||||
idkey = "imapid"
|
||||
select = tables.ImgColumn("select", cssclass="draggable left", width="1%",
|
||||
defvalue="%spics/grippy.png" % settings.MEDIA_URL,
|
||||
header="<input type='checkbox' name='toggleselect' id='toggleselect' />")
|
||||
select = tables.ImgColumn(
|
||||
"select", cssclass="draggable left", width="1%",
|
||||
defvalue="%spics/grippy.png" % settings.MEDIA_URL,
|
||||
header="<input type='checkbox' name='toggleselect' id='toggleselect' />"
|
||||
)
|
||||
flags = tables.ImgColumn("flags", width="2%")
|
||||
withatts = tables.ImgColumn("withatts", width="2%")
|
||||
subject = tables.Column("subject", label=__("Subject"), width="50%")
|
||||
from_ = tables.Column("from", width="20%", label=__("From"))
|
||||
date = tables.Column("date", width="20%", label=__("Date"))
|
||||
subject = tables.Column("subject", label=__("Subject"), width="50%", limit=60)
|
||||
from_ = tables.Column("from", width="20%", label=__("From"), limit=30)
|
||||
date = tables.Column("date", width="10%", label=__("Date"))
|
||||
|
||||
cols_order = ["select", "withatts", "flags", "subject", "from_", "date"]
|
||||
|
||||
|
||||
@@ -1,115 +1,24 @@
|
||||
{% extends "layout_simple.html" %}
|
||||
{% extends "common/generic_modal_form.html" %}
|
||||
{% load i18n %}
|
||||
{% block html_head %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}webmail/css/attachments.css" />
|
||||
<script src="{{ MEDIA_URL }}webmail/js/webmail.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
function del_attachment(evt) {
|
||||
evt.stop();
|
||||
new Request.JSON.mdb({
|
||||
url: this.get("href"),
|
||||
onSuccess: function(resp) {
|
||||
this.getParent().dispose();
|
||||
}.bind(this)
|
||||
}).get();
|
||||
}
|
||||
|
||||
function upload_cb(fname, tmpname) {
|
||||
$("upload_status").setStyle("display", "none");
|
||||
$("submit").set("disabled", false);
|
||||
$("error").set("html", "");
|
||||
|
||||
var ndiv = new Element("div");
|
||||
var delbtn = new Element("a")
|
||||
.set("name", "delattachment")
|
||||
.set("href", "{% url modoboa.extensions.webmail.views.delattachment %}?name=" + tmpname)
|
||||
.set("html", "<img src='{{MEDIA_URL}}pics/remove.png' />")
|
||||
.inject(ndiv);
|
||||
var label = new Element("label").set("html", fname).inject(ndiv);
|
||||
|
||||
delbtn.addEvent("click", del_attachment);
|
||||
$("id_attachment").set("value", "");
|
||||
ndiv.inject($("attachment_list"));
|
||||
}
|
||||
|
||||
function upload_error(msg) {
|
||||
$("upload_status").setStyle("display", "none");
|
||||
$("error").set("html", msg);
|
||||
$("submit").set("disabled", false);
|
||||
}
|
||||
|
||||
window.addEvent("domready", function() {
|
||||
$("uploadfile").addEvent("submit", function(evt) {
|
||||
if ($("id_attachment").value == "") {
|
||||
evt.stop();
|
||||
return;
|
||||
}
|
||||
$("upload_status").setStyle("display", "block");
|
||||
$("submit").set("disabled", true);
|
||||
});
|
||||
$$("a[name=delattachment]").addEvent("click", del_attachment);
|
||||
$("done").addEvent("click", function(evt) {
|
||||
var nfiles = 0;
|
||||
var shortlist = "";
|
||||
var html;
|
||||
|
||||
$$("a[name=delattachment]").each(function(item) {
|
||||
var label = item.getNext();
|
||||
|
||||
nfiles++;
|
||||
if (nfiles <= 2) {
|
||||
if (shortlist != "") {
|
||||
shortlist += ", ";
|
||||
} else {
|
||||
shortlist = "(";
|
||||
}
|
||||
shortlist += label.get("html");
|
||||
return;
|
||||
}
|
||||
if (nfiles == 3) {
|
||||
shortlist += ", ...";
|
||||
}
|
||||
});
|
||||
if (shortlist != "") {
|
||||
shortlist += ")";
|
||||
}
|
||||
html = interpolate(ngettext("%s file", "%s files", nfiles), [nfiles]);
|
||||
html += " <span class='shortlist'>" + shortlist + "</span>";
|
||||
parent.document.getElementById("list")
|
||||
.set("html", html);
|
||||
parent.SqueezeBox.close();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="title"><h1>{% trans "Attachments" %}</h1></div>
|
||||
<div id="error" class="error">{{ error }}</div>
|
||||
<form enctype="multipart/form-data" method="post" name="uploadfile" id="uploadfile"
|
||||
target="upload_target"
|
||||
action="{% url modoboa.extensions.webmail.views.attachments %}">
|
||||
{% include "common/genericform.html" %}
|
||||
<div class="row">
|
||||
<input type="submit" id="submit" name="submit" value="{% trans 'Attach' %}" />
|
||||
</div>
|
||||
</form>
|
||||
{% block modalbody %}
|
||||
{{ block.super }}
|
||||
<div id="test" style="text-align: center">
|
||||
<input type="button" class="btn btn-primary" id="submit" name="submit" value="{% trans 'Attach' %}" />
|
||||
</div>
|
||||
<div id="upload_status" style="display:none">
|
||||
<img src="{{MEDIA_URL}}css/spinner.gif" /> {% trans "Uploading.." %}
|
||||
<img src="{{ MEDIA_URL }}css/spinner.gif" /> {% trans "Uploading.." %}
|
||||
</div>
|
||||
<iframe id="upload_target" name="upload_target" src="#"
|
||||
style="width:0;height:0;border:0px solid #fff;"></iframe>
|
||||
<div id="attachment_list">
|
||||
<div class="well" id="attachment_list">
|
||||
{% for att in attachments %}
|
||||
<div>
|
||||
<div class="row-fluid">
|
||||
<a href="{% url modoboa.extensions.webmail.views.delattachment %}?name={{ att.tmpname }}"
|
||||
name="delattachment">
|
||||
<img src="{{ MEDIA_URL }}pics/remove.png" />
|
||||
<i class="icon-remove"></i>
|
||||
</a>
|
||||
<label>{{ att.fname }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="done_container">
|
||||
<input type="button" id="done" name="done" value="{% trans 'Done' %}" />
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n libextras %}
|
||||
<form method="POST" action="{{ posturl }}" id="composemail">
|
||||
<form class="form-horizontal" method="POST" action="{{ posturl }}" id="composemail">
|
||||
<div id="compose-container">
|
||||
<div id="mailheader">
|
||||
<div id="mailheader" class="well">
|
||||
{% render_form form %}
|
||||
<div id="attachments" name="{% url modoboa.extensions.webmail.views.attachments %}">
|
||||
<div>
|
||||
@@ -14,7 +14,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="spacer"></div>
|
||||
|
||||
<div id="body_container">
|
||||
{% if body %}
|
||||
<textarea id="id_body" name="id_body" class="editor">{% if bodyheader %}{{ bodyheader }}{% endif %}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<script type="text/javascript">
|
||||
{% if status == "ok" %}
|
||||
parent.upload_cb("{{ fname }}", "{{ tmpname }}");
|
||||
parent.webmail.upload_success("{{ fname }}", "{{ tmpname }}");
|
||||
{% else %}
|
||||
parent.upload_error("{{ error }}");
|
||||
parent.webmail.upload_error("{{ error }}");
|
||||
{% endif %}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
@@ -15,7 +15,7 @@ def viewmail_menu(selection, folder, user, mail_id=None):
|
||||
entries = [
|
||||
{"name" : "back",
|
||||
"url" : "javascript:history.go(-1);",
|
||||
"img" : static_url("pics/back.png"),
|
||||
"img" : "icon-arrow-left",
|
||||
"label" : _("Back")},
|
||||
{"name" : "reply",
|
||||
"url" : "action=reply&mbox=%s&mailid=%s" % (folder, mail_id),
|
||||
@@ -58,12 +58,12 @@ def viewmail_menu(selection, folder, user, mail_id=None):
|
||||
def compose_menu(selection, backurl, user):
|
||||
entries = [
|
||||
{"name" : "back",
|
||||
"url" : "javascript:history.go(-2);",#backurl,
|
||||
"img" : static_url("pics/back.png"),
|
||||
"url" : "javascript:history.go(-2);",
|
||||
"img" : "icon-arrow-left",
|
||||
"label" : _("Back")},
|
||||
{"name" : "sendmail",
|
||||
"url" : "",
|
||||
"img" : static_url("pics/send-receive.png"),
|
||||
"img" : "icon-envelope",
|
||||
"label" : _("Send")},
|
||||
]
|
||||
return render_to_string('common/buttons_list.html',
|
||||
@@ -109,14 +109,13 @@ def listmailbox_menu(selection, folder, user):
|
||||
"img" : static_url("pics/clear.png"),
|
||||
"url" : reverse(webmail.views.empty, args=[folder])}
|
||||
]
|
||||
menu = render_to_string("common/buttons_list.html",
|
||||
{"selection" : selection, "entries" : entries,
|
||||
"user" : user, "css" : "nav"})
|
||||
# searchbar = render_to_string("common/email_searchbar.html", {
|
||||
# "MEDIA_URL" : settings.MEDIA_URL
|
||||
# })
|
||||
# return menu + searchbar
|
||||
return menu
|
||||
searchbar = render_to_string('common/email_searchbar.html', {
|
||||
"MEDIA_URL" : settings.MEDIA_URL
|
||||
})
|
||||
return render_to_string('common/buttons_list.html', dict(
|
||||
selection=selection, entries=entries, extracontent=searchbar,
|
||||
user=user, css="nav"
|
||||
))
|
||||
|
||||
@register.simple_tag
|
||||
def print_folders(folders, selected=None, withunseen=False, withmenu=False):
|
||||
|
||||
@@ -56,7 +56,7 @@ def __render_common_components(request, folder_name, lst=None, content=None, men
|
||||
else:
|
||||
navbar = ""
|
||||
if lst:
|
||||
content = "<div class='info'>%s</div>" \
|
||||
content = "<div class='alert alert-info'>%s</div>" \
|
||||
% _("This folder contains no messages")
|
||||
|
||||
ret = {
|
||||
@@ -307,7 +307,7 @@ def delfolder(request):
|
||||
|
||||
@login_required
|
||||
@needs_mailbox()
|
||||
def attachments(request, tplname="webmail/attachments.html"):
|
||||
def attachments(request, tplname="webmail/attachments2.html"):
|
||||
if request.method == "POST":
|
||||
csuploader = AttachmentUploadHandler()
|
||||
request.upload_handlers.insert(0, csuploader)
|
||||
@@ -336,8 +336,15 @@ def attachments(request, tplname="webmail/attachments.html"):
|
||||
return _render(request, "webmail/upload_done.html", {
|
||||
"status" : "ko", "error" : error
|
||||
});
|
||||
ctx = {"form" : AttachmentForm(),
|
||||
"attachments" : request.session["compose_mail"]["attachments"]}
|
||||
ctx = {
|
||||
"title" : _("Attachments"),
|
||||
"formid" : "uploadfile",
|
||||
"target" : "upload_target",
|
||||
"enctype" : "multipart/form-data",
|
||||
"form" : AttachmentForm(),
|
||||
"action" : reverse(attachments),
|
||||
"attachments" : request.session["compose_mail"]["attachments"]
|
||||
}
|
||||
return _render(request, tplname, ctx)
|
||||
|
||||
@login_required
|
||||
@@ -578,10 +585,17 @@ def newindex(request):
|
||||
if not request.is_ajax():
|
||||
request.session["lastaction"] = None
|
||||
imapc = get_imapconnector(request)
|
||||
imapc.getquota(curmbox)
|
||||
response["refreshrate"] = \
|
||||
int(parameters.get_user(request.user, "REFRESH_INTERVAL")) * 1000
|
||||
response["mboxes"] = render_mboxes_list(request, imapc)
|
||||
response["quota"] = ImapListing.computequota(imapc)
|
||||
if response["quota"] < 50:
|
||||
response["quotalevel"] = "success"
|
||||
elif response["quotalevel"] < 80:
|
||||
response["quotalevel"] = "warning"
|
||||
else:
|
||||
response["quotalevel"] = "danger"
|
||||
return _render(request, "webmail/index2.html", response)
|
||||
|
||||
if action in ["reply", "forward"]:
|
||||
|
||||
Reference in New Issue
Block a user