Some code refactoring, extensions look more like Django applications now.
This commit is contained in:
tonio
2010-05-20 08:51:01 +02:00
parent b33fdb45d9
commit 633f09ba7c
16 changed files with 730 additions and 692 deletions
+3 -191
View File
@@ -2,27 +2,10 @@
"""
"""
from datetime import datetime
import time
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
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, getctx
from mailng.lib import db
from mailng.admin.models import Mailbox
from lib import AMrelease
from templatetags.amextras import *
from mailng.lib.email_listing import parse_search_parameters
from sql_listing import *
def infos():
return {
@@ -55,185 +38,14 @@ def urls():
include('mailng.extensions.amavis_quarantine.urls'))
def menu(**kwargs):
import views
if kwargs["target"] == "user_menu_box":
return [
{"name" : "quarantine",
"label" : _("Quarantine"),
"url" : reverse(index),
"url" : reverse(views.index),
"img" : "/static/pics/quarantine.png"}
]
return []
def __get_current_url(request):
res = "?page=%s" % request.session["page"]
for p in ["criteria", "pattern"]:
if p in request.session.keys():
res += "&%s=%s" % (p, request.session[p])
return res
@login_required
def _listing(request, internal=False, filter=None):
#start = time.time()
if not request.user.is_superuser:
mb = Mailbox.objects.get(user=request.user.id)
if filter is None:
filter = ["&maddr.email='%s'" % mb.full_address]
else:
filter += ["&maddr.email='%s'" % mb.full_address]
parse_search_parameters(request)
if request.session.has_key("pattern"):
tmp = ""
for c in request.session["criteria"].split(','):
if tmp != "":
tmp += " OR "
tmp += "msgs.%s LIKE '%%%s%%'" % (c, request.session["pattern"])
tmp = "&(%s)" % tmp
if filter is None:
filter = [tmp]
else:
filter += [tmp]
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:
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 sql_listing import SQLemail
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 = SQLemail(msg, mode, links)
return _render(request, "common/viewmail.html", {
"headers" : mail.render_headers(),
"mailbody" : mail.body,
"pre" : mail.pre
})
@login_required
def viewmail(request, mail_id):
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("", __get_current_url(request), 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):
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/viewheader.html', {
"headers" : msg.items()
})
@login_required
def delete(request, mail_id, count=1):
conn = db.getconnection("amavis_quarantine")
if mail_id[0] != "'":
mail_id = "'%s'" % mail_id
status, error = db.execute(conn,
"DELETE FROM msgs WHERE mail_id IN (%s)" % mail_id)
if status:
message = ungettext("%(count)d message deleted successfully",
"%(count)d messages deleted successfully",
count) % {"count" : count}
else:
message = error
ctx = getctx("ok", url=__get_current_url(request), message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def release(request, mail_id, count=1):
conn = db.getconnection("amavis_quarantine")
if mail_id[0] != "'":
mail_id = "'%s'" % mail_id
status, cursor = db.execute(conn, """
SELECT msgs.mail_id,secret_id,quar_type,maddr.email FROM msgs, maddr, msgrcpt
WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN (%s)
""" % (mail_id))
emails = {}
amr = AMrelease()
for row in cursor.fetchall():
if not emails.has_key(row[0]):
emails[row[0]] = {}
emails[row[0]]["rcpts"] = []
emails[row[0]]["secret"] = row[1]
emails[row[0]]["rcpts"] += [row[3]]
count = 0
error = None
for k, values in emails.iteritems():
result = amr.sendreq(k, values["secret"], *values["rcpts"])
if result:
count += 1
else:
error = result
break
if not error:
message = ungettext("%(count)d message released successfully",
"%(count)d messages released successfully",
count) % {"count" : count}
else:
message = error
ctx = getctx("ok", url=__get_current_url(request), message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def process(request):
ids = ""
count = len(request.POST["selection"].split(","))
for id in request.POST["selection"].split(","):
if ids != "":
ids += ","
ids += "'%s'" % id
if ids == "":
return HttpResponseRedirect(reverse(index))
if request.POST["action"] == "release":
return release(request, ids, count)
if request.POST["action"] == "delete":
return delete(request, ids, count)
@@ -71,6 +71,16 @@ tr.table-tr-selected {
$$("a[name=selectmsgs]").addEvent("click", function(evt) {
evt.stop();
var type = evt.target.get("href");
if (!$chk(type)) {
$$("tr[class*=table-tr-selected]").each(function(item) {
item.removeClass("table-tr-selected");
});
if ($("toggleselect").checked) {
$("toggleselect").checked = false;
tbl.selectNone();
}
return;
}
$$("td[name=type]").each(function(item) {
if (item.get("html").trim() == type) {
item.getParent().addClass("table-tr-selected");
@@ -26,18 +26,18 @@ def viewm_menu(selection, backurl, mail_id, perms):
"img" : "/static/pics/back.png",
"label" : _("Back to list")},
{"name" : "headers",
"url" : reverse(amavis_quarantine.main.viewheaders, args=[mail_id]),
"url" : reverse(amavis_quarantine.views.viewheaders, args=[mail_id]),
"img" : "/static/pics/add.png",
"label" : _("View full headers"),
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:600,y:500}}"},
{"name" : "release",
"url" : reverse(amavis_quarantine.main.release, args=[mail_id]),
"url" : reverse(amavis_quarantine.views.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]),
"url" : reverse(amavis_quarantine.views.delete, args=[mail_id]),
"img" : "/static/pics/remove.png",
"label" : _("Delete"),
"confirm" : _("Delete this message?")},
@@ -66,9 +66,12 @@ def quar_menu(selection, perms):
{"name" : "select",
"url" : "",
"img" : "/static/pics/domains.png",
"label" : _("Select all"),
"label" : _("Select"),
"class" : "menubardropdown",
"menu" : [
{"name" : "selectmsgs",
"url" : "",
"label" : _("Nothing")},
{"name" : "selectmsgs",
"url" : "S",
"label" : _("Spam")},
+1 -1
View File
@@ -1,6 +1,6 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('mailng.extensions.amavis_quarantine.main',
urlpatterns = patterns('mailng.extensions.amavis_quarantine.views',
(r'^$', 'index'),
(r'^listing/$', '_listing'),
(r'^getmailcontent/(?P<mail_id>[\w\-\+]+)/$', 'getmailcontent'),
+195
View File
@@ -0,0 +1,195 @@
# -*- coding: utf-8 -*-
from datetime import datetime
import time
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.utils.translation import ugettext as _, ungettext
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators \
import login_required
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 mailng.lib.email_listing import parse_search_parameters
from sql_listing import *
def __get_current_url(request):
res = "?page=%s" % request.session["page"]
for p in ["criteria", "pattern"]:
if p in request.session.keys():
res += "&%s=%s" % (p, request.session[p])
return res
@login_required
def _listing(request, internal=False, filter=None):
#start = time.time()
if not request.user.is_superuser:
mb = Mailbox.objects.get(user=request.user.id)
if filter is None:
filter = ["&maddr.email='%s'" % mb.full_address]
else:
filter += ["&maddr.email='%s'" % mb.full_address]
parse_search_parameters(request)
if request.session.has_key("pattern"):
tmp = ""
for c in request.session["criteria"].split(','):
if tmp != "":
tmp += " OR "
tmp += "msgs.%s LIKE '%%%s%%'" % (c, request.session["pattern"])
tmp = "&(%s)" % tmp
if filter is None:
filter = [tmp]
else:
filter += [tmp]
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:
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 sql_listing import SQLemail
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 = SQLemail(msg, mode, links)
return _render(request, "common/viewmail.html", {
"headers" : mail.render_headers(),
"mailbody" : mail.body,
"pre" : mail.pre
})
@login_required
def viewmail(request, mail_id):
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("", __get_current_url(request), 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):
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/viewheader.html', {
"headers" : msg.items()
})
@login_required
def delete(request, mail_id, count=1):
conn = db.getconnection("amavis_quarantine")
if mail_id[0] != "'":
mail_id = "'%s'" % mail_id
status, error = db.execute(conn,
"DELETE FROM msgs WHERE mail_id IN (%s)" % mail_id)
if status:
message = ungettext("%(count)d message deleted successfully",
"%(count)d messages deleted successfully",
count) % {"count" : count}
else:
message = error
ctx = getctx("ok", url=__get_current_url(request), message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def release(request, mail_id, count=1):
conn = db.getconnection("amavis_quarantine")
if mail_id[0] != "'":
mail_id = "'%s'" % mail_id
status, cursor = db.execute(conn, """
SELECT msgs.mail_id,secret_id,quar_type,maddr.email FROM msgs, maddr, msgrcpt
WHERE msgrcpt.mail_id=msgs.mail_id AND msgrcpt.rid=maddr.id AND msgs.mail_id IN (%s)
""" % (mail_id))
emails = {}
amr = AMrelease()
for row in cursor.fetchall():
if not emails.has_key(row[0]):
emails[row[0]] = {}
emails[row[0]]["rcpts"] = []
emails[row[0]]["secret"] = row[1]
emails[row[0]]["rcpts"] += [row[3]]
count = 0
error = None
for k, values in emails.iteritems():
result = amr.sendreq(k, values["secret"], *values["rcpts"])
if result:
count += 1
else:
error = result
break
if not error:
message = ungettext("%(count)d message released successfully",
"%(count)d messages released successfully",
count) % {"count" : count}
else:
message = error
ctx = getctx("ok", url=__get_current_url(request), message=message)
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
@login_required
def process(request):
ids = ""
count = len(request.POST["selection"].split(","))
for id in request.POST["selection"].split(","):
if ids != "":
ids += ","
ids += "'%s'" % id
if ids == "":
return HttpResponseRedirect(reverse(index))
if request.POST["action"] == "release":
return release(request, ids, count)
if request.POST["action"] == "delete":
return delete(request, ids, count)
+4 -42
View File
@@ -7,15 +7,10 @@ This module provides a way to integrate MailNG auto-reply
functionality into Postfix.
"""
from django.http import HttpResponse
from django.utils import simplejson
from django.contrib.auth.decorators \
import login_required
from django.conf.urls.defaults import include
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from mailng.lib import _render, events, parameters, _ctx_ok, _ctx_ko
from forms import *
from mailng.lib import events, parameters
from models import *
def infos():
@@ -50,11 +45,13 @@ def urls():
include('mailng.extensions.postfix_autoreply.urls'))
def menu(**kwargs):
import views
if kwargs["target"] != "user_menu_bar":
return []
return [
{"name" : "autoreply",
"url" : reverse(autoreply),
"url" : reverse(views.autoreply),
"img" : "/static/pics/auto-reply.png",
"class" : "boxed",
"rel" : "{handler:'iframe',size:{x:440,y:370}}",
@@ -99,38 +96,3 @@ def onModifyMailbox(**kwargs):
alias.autoreply_address = \
"%s@autoreply.%s" % (mbox.full_address, mbox.domain.name)
alias.save()
@login_required
def autoreply(request):
mb = Mailbox.objects.get(user=request.user.id)
try:
arm = ARmessage.objects.get(mbox=mb.id)
except ARmessage.DoesNotExist:
arm = None
if request.method == "POST":
if arm:
form = ARmessageForm(request.POST, instance=arm)
else:
form = ARmessageForm(request.POST)
error = None
if form.is_valid():
from mailng import userprefs
arm = form.save(commit=False)
arm.mbox = mb
arm.save()
request.user.message_set.create(
message=_("Auto reply message updated successfully.")
)
ctx = _ctx_ok(reverse(userprefs.views.index))
else:
ctx = _ctx_ko("postfix_autoreply/autoreply.html", {
"form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
form = ARmessageForm(instance=arm)
return _render(request, "postfix_autoreply/autoreply.html", {
"form" : form
})
@@ -26,7 +26,7 @@ window.addEvent("domready", function() {
{% block content %}
<div class="title"><h1>{% trans "Auto-reply message" %}</h1></div>
<form action="{% url extensions.postfix_autoreply.main.autoreply %}"
<form action="{% url extensions.postfix_autoreply.views.autoreply %}"
method="POST" id="armform" name="armform" class="simple">
{% include "common/genericform.html" %}
<div class="spacer"></div>
+1 -1
View File
@@ -1,5 +1,5 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('mailng.extensions.postfix_autoreply.main',
urlpatterns = patterns('mailng.extensions.postfix_autoreply.views',
url(r'^$', 'autoreply'),
)
+46
View File
@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
from django.http import HttpResponse
from django.utils import simplejson
from django.contrib.auth.decorators \
import login_required
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from mailng.lib import _render, _ctx_ok, _ctx_ko
from forms import *
from models import *
@login_required
def autoreply(request):
mb = Mailbox.objects.get(user=request.user.id)
try:
arm = ARmessage.objects.get(mbox=mb.id)
except ARmessage.DoesNotExist:
arm = None
if request.method == "POST":
if arm:
form = ARmessageForm(request.POST, instance=arm)
else:
form = ARmessageForm(request.POST)
error = None
if form.is_valid():
from mailng import userprefs
arm = form.save(commit=False)
arm.mbox = mb
arm.save()
request.user.message_set.create(
message=_("Auto reply message updated successfully.")
)
ctx = _ctx_ok(reverse(userprefs.views.index))
else:
ctx = _ctx_ko("postfix_autoreply/autoreply.html", {
"form" : form, "error" : error
})
return HttpResponse(simplejson.dumps(ctx),
mimetype="application/json")
form = ARmessageForm(instance=arm)
return _render(request, "postfix_autoreply/autoreply.html", {
"form" : form
})
+1 -147
View File
@@ -7,23 +7,10 @@ This module provides support to retrieve statistics from postfix log :
sent, received, bounced, rejected
"""
import calendar
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from django.conf.urls.defaults import *
from mailng.lib import events, parameters, _render
from mailng.admin.views import good_domain
from mailng.admin.models import Domain, Mailbox
from django.contrib.auth.decorators \
import login_required, user_passes_test, permission_required
from extensions.stats.grapher import Grapher, tpl
from extensions.stats.logparser import str2Time
graph_types = ['AVERAGE', 'MAX']
graph_list = [{"name" : "traffic", "label" : _("Average normal traffic")},
{"name" : "badtraffic", "label" : _("Average bad traffic")},
{"name" : "size", "label" : _("Average normal traffic size")}]
from mailng.lib import events, parameters
def infos():
return {
@@ -65,136 +52,3 @@ def menu(**kwargs):
"img" : "/static/pics/graph.png"}
]
return []
@login_required
def domain(request, dom_id):
domains = []
errors = []
return graph_display(request,dom_id,graph_types)
@login_required
def graph_display(request,dom_id,graph_t=graph_types):
domains = []
errors = []
graph_type = None
domain=None
if type(graph_t) == type([]):
graph_type = graph_t
else :
graph_type = [graph_t]
if dom_id:
domain = Domain.objects.get(pk=dom_id)
if domain:
domains.append(domain)
if domains == []:
errors.append(_("No Domain defined"))
for d in domains:
P = parser(d.name)
if type(P) == type('err'):
errors.append(P)
else:
P.plot_rrd()
return _render(request, 'stats/index.html', {
"page" : "Domain statistics", "graph" : graph_nature,
"domain": domain, "domains" : domains, "messages" : errors,
"types" : graph_type, "tmp_path" : tmp_path,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def adminindex(request):
CH = calendar.HTMLCalendar(calendar.MONDAY)
CH_print = CH.formatmonth(2009,11)
period = request.GET.has_key("period") and request.GET["period"] or "day"
domain = request.GET.has_key("domain") and request.GET["domain"] or "global"
if domain != "global":
domain = Domain.objects.get(pk=domain)
domain = domain.name
domains = Domain.objects.all()
G = Grapher()
for name, t in tpl.iteritems():
G.make_defaults(domain, t)
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"periods" : ["day", "week", "month", "year","Custom"],
"period" : period, "cal" : CH_print,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def custom_period(request):
start = None
end = None
start_ref = None
end_ref = None
domains = Domain.objects.all()
domain = request.GET.has_key("domain") and request.GET["domain"] or "global"
period = request.GET.has_key("period") and request.GET["period"] or "Custom"
if domain != "global":
domain = Domain.objects.get(pk=domain)
domain = domain.name
try:
start_ref = str(request.POST.get('start'))
start = start_ref.split(', ')[1]
end_ref = str(request.POST.get('end'))
end = end_ref.split(', ')[1]
except:
pass
if not end or not start:
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"period" : period,
"periods" : ["day", "week", "month", "year","Custom"],
"period_name":None,
"start" : start_ref,
"end" : end_ref,
"messages" : ["Custom period not selected"],
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
period_name = "%s_%s" %(start.replace('/',''),end.replace('/',''))
G = Grapher()
for tpl_name in graph_list:
G.process(domain,
period_name,
str2Time(*start.split('/')),
str2Time(*end.split('/')),
tpl[tpl_name['name']])
print "[stats] ", period
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"period" : period,
"periods" : ["day", "week", "month", "year","Custom"],
"period_name": period_name,
"start" : start_ref,
"end" : end_ref,
"messages" : None,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@good_domain
@permission_required("admin.view_mailboxes")
def index(request, dom_id=None):
domain = None
period = request.GET.has_key("period") and request.GET["period"] or "day"
if request.user.has_perm("admin.view_mailboxes"):
domain = Domain.objects.get(pk=dom_id)
return _render(request, 'stats/index.html', {
"domain" : domain,
"graphs" : graph_list,
"periods" : ["day", "week", "month", "year","Custom"],
"period" : period,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
+1 -1
View File
@@ -1,6 +1,6 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('mailng.extensions.stats.main',
urlpatterns = patterns('mailng.extensions.stats.views',
url(r'^$', 'adminindex', name='fullindex'),
url(r'^custom_period$', 'custom_period'),
url(r'^(?P<dom_id>\d+)/$', 'index', name='domindex'),
+150
View File
@@ -0,0 +1,150 @@
# -*- coding: utf-8 -*-
import calendar
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _
from mailng.lib import parameters, _render
from mailng.admin.views import good_domain
from mailng.admin.models import Domain, Mailbox
from django.contrib.auth.decorators \
import login_required, user_passes_test, permission_required
from extensions.stats.grapher import Grapher, tpl
from extensions.stats.logparser import str2Time
graph_types = ['AVERAGE', 'MAX']
graph_list = [{"name" : "traffic", "label" : _("Average normal traffic")},
{"name" : "badtraffic", "label" : _("Average bad traffic")},
{"name" : "size", "label" : _("Average normal traffic size")}]
@login_required
def domain(request, dom_id):
domains = []
errors = []
return graph_display(request,dom_id,graph_types)
@login_required
def graph_display(request,dom_id,graph_t=graph_types):
domains = []
errors = []
graph_type = None
domain=None
if type(graph_t) == type([]):
graph_type = graph_t
else :
graph_type = [graph_t]
if dom_id:
domain = Domain.objects.get(pk=dom_id)
if domain:
domains.append(domain)
if domains == []:
errors.append(_("No Domain defined"))
for d in domains:
P = parser(d.name)
if type(P) == type('err'):
errors.append(P)
else:
P.plot_rrd()
return _render(request, 'stats/index.html', {
"page" : "Domain statistics", "graph" : graph_nature,
"domain": domain, "domains" : domains, "messages" : errors,
"types" : graph_type, "tmp_path" : tmp_path,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def adminindex(request):
CH = calendar.HTMLCalendar(calendar.MONDAY)
CH_print = CH.formatmonth(2009,11)
period = request.GET.has_key("period") and request.GET["period"] or "day"
domain = request.GET.has_key("domain") and request.GET["domain"] or "global"
if domain != "global":
domain = Domain.objects.get(pk=domain)
domain = domain.name
domains = Domain.objects.all()
G = Grapher()
for name, t in tpl.iteritems():
G.make_defaults(domain, t)
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"periods" : ["day", "week", "month", "year","Custom"],
"period" : period, "cal" : CH_print,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@user_passes_test(lambda u: u.is_superuser)
def custom_period(request):
start = None
end = None
start_ref = None
end_ref = None
domains = Domain.objects.all()
domain = request.GET.has_key("domain") and request.GET["domain"] or "global"
period = request.GET.has_key("period") and request.GET["period"] or "Custom"
if domain != "global":
domain = Domain.objects.get(pk=domain)
domain = domain.name
try:
start_ref = str(request.POST.get('start'))
start = start_ref.split(', ')[1]
end_ref = str(request.POST.get('end'))
end = end_ref.split(', ')[1]
except:
pass
if not end or not start:
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"period" : period,
"periods" : ["day", "week", "month", "year","Custom"],
"period_name":None,
"start" : start_ref,
"end" : end_ref,
"messages" : ["Custom period not selected"],
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
period_name = "%s_%s" %(start.replace('/',''),end.replace('/',''))
G = Grapher()
for tpl_name in graph_list:
G.process(domain,
period_name,
str2Time(*start.split('/')),
str2Time(*end.split('/')),
tpl[tpl_name['name']])
print "[stats] ", period
return _render(request, 'stats/adminindex.html', {
"domains" : domains, "domain" : domain,
"graphs" : graph_list,
"period" : period,
"periods" : ["day", "week", "month", "year","Custom"],
"period_name": period_name,
"start" : start_ref,
"end" : end_ref,
"messages" : None,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
@login_required
@good_domain
@permission_required("admin.view_mailboxes")
def index(request, dom_id=None):
domain = None
period = request.GET.has_key("period") and request.GET["period"] or "day"
if request.user.has_perm("admin.view_mailboxes"):
domain = Domain.objects.get(pk=dom_id)
return _render(request, 'stats/index.html', {
"domain" : domain,
"graphs" : graph_list,
"periods" : ["day", "week", "month", "year","Custom"],
"period" : period,
"img_rootdir" : parameters.get("stats", "IMG_ROOTDIR")})
+4 -298
View File
@@ -1,20 +1,8 @@
# -*- coding: utf-8 -*-
import time
import sys
from django.http import HttpResponse, Http404
from django.template import Template, Context
from django.template.loader import render_to_string
from django.utils import simplejson
from django.utils.translation import ugettext as _
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, getctx
from imap_listing import *
from forms import *
from templatetags.webextras import *
from lib.email_listing import parse_search_parameters
from mailng.lib import events, parameters
def init():
events.register("UserMenuDisplay", menu)
@@ -51,298 +39,16 @@ def urls():
include('mailng.extensions.webmail.urls'))
def menu(**kwargs):
import views
if kwargs["target"] != "user_menu_box":
return []
return [
{"name" : "webmail",
"label" : _("Webmail"),
"url" : reverse(index),
"url" : reverse(views.index),
"img" : "/static/pics/webmail.png"}
]
def __get_current_url(request):
res = "%s?page=%s" % (request.session["folder"], request.session["page"])
for p in ["criteria", "pattern", "order"]:
if p in request.session.keys():
res += "&%s=%s" % (p, request.session[p])
return res
def userlogin(**kwargs):
kwargs["request"].session["password"] = kwargs["password"]
@login_required
def folder(request, name, updatenav=True):
if not name:
name = "INBOX"
order = request.GET.has_key("order") and request.GET["order"] or "-date"
if updatenav:
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
if not "navparams" in request.session.keys():
request.session["navparams"] = {}
request.session["folder"] = name
request.session["page"] = pageid
if order:
request.session["navparams"]["order"] = order
parse_search_parameters(request)
else:
# Internal usage
order = request.session["navparams"]["order"]
optparams = {}
if request.session.has_key("pattern"):
optparams["pattern"] = request.session["pattern"]
optparams["criteria"] = request.session["criteria"]
else:
optparams["reset"] = True
lst = ImapListing(request.user.username, request.session["password"],
baseurl=name, folder=name, order=order, **optparams)
page = lst.paginator.getpage(request.session["page"])
if page:
content = lst.fetch(request, page.id_start, page.id_stop)
navbar = lst.render_navbar(page)
else:
content = "Empty folder"
navbar = ""
folders = render_to_string("webmail/folders.html", {
"folders" : lst.getfolders()
})
ctx = getctx("ok", folders=folders, listing=content, navbar=navbar,
menu=listing_menu("", name, request.user.get_all_permissions()))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def index(request):
try:
navp = request.session.has_key("navparams") \
and request.session["navparams"] or {}
lst = ImapListing(request.user.username, request.session["password"],
baseurl="INBOX", navparams=navp, folder="INBOX",
empty=True)
except Exception, exp:
return _render_error(request, {"error" : exp})
return lst.render(request)
def fetchmail(request, folder, mail_id, all=False):
res = IMAPconnector(request).fetch(start=mail_id, folder=folder, all=all)
if len(res):
return res[0]
return None
@login_required
def viewmail(request, folder, mail_id=None):
from templatetags.webextras import viewm_menu
content = Template("""
<iframe width="100%" frameBorder="0" src="{{ url }}" id="mailcontent"></iframe>
""").render(Context({"url" : reverse(getmailcontent, args=[folder, mail_id])}))
menu = viewm_menu("", __get_current_url(request), folder, 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 getmailcontent(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
if "class" in msg.keys() and msg["class"] == "unseen":
IMAPconnector(request).msg_read(folder, mail_id)
email = ImapEmail(msg, mode="html", links="1")
try:
pageid = request.session["page"]
except KeyError:
pageid = "1"
return _render(request, "common/viewmail.html", {
"headers" : email.render_headers(folder=folder, mail_id=mail_id),
"folder" : folder, "imapid" : mail_id, "mailbody" : email.body,
"pre" : email.pre
})
@login_required
def getattachment(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
for part in msg.walk():
fname = part.get_filename()
if fname is None:
continue
decoded = decode_header(fname)
if decoded[0][1] is None:
fname = unicode(decoded[0][0])
else:
fname = unicode(decoded[0][0], decoded[0][1])
if fname == request.GET["fname"]:
resp = HttpResponse(part.get_payload(decode=1))
for hdr in ["Content-Disposition", "Content-Type"]:
resp[hdr] = re.sub("\s", "", part[hdr])
resp["Content-Length"] = len(resp.content)
return resp
raise Http404
@login_required
def move(request):
for arg in ["msgset", "to"]:
if not request.GET.has_key(arg):
return
mbc = IMAPconnector(request)
mbc.move(request.GET["msgset"], request.session["folder"], request.GET["to"])
return folder(request, request.session["folder"], False)
@login_required
def delete(request, fdname, mail_id):
mbc = IMAPconnector(request)
mbc.move(mail_id, fdname, "Trash")
return folder(request, fdname, False)
@login_required
def mark(request, name):
if not request.GET.has_key("status") or not request.GET.has_key("ids"):
return
mbc = IMAPconnector(request)
try:
getattr(mbc, "msg_%s" % request.GET["status"])(name, request.GET["ids"])
except AttributeError:
pass
return folder(request, name, False)
@login_required
def empty(request, name):
if name == "Trash":
mbc = IMAPconnector(request)
mbc.empty(name)
return folder(request, name, False)
@login_required
def compact(request, name):
mbc = IMAPconnector(request)
mbc.compact(name)
return folder(request, name, False)
def render_compose(request, form, posturl, bodyheader=None, body=None):
menu = compose_menu("", __get_current_url(request),
request.user.get_all_permissions())
content = render_to_string("webmail/compose.html", {
"form" : form, "bodyheader" : bodyheader, "body" : body,
"posturl" : posturl
})
ctx = getctx("ok", level=2, menu=menu, listing=content)
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
def send_mail(request, withctx=False, origmsg=None):
form = ComposeMailForm(request.POST)
if form.is_valid():
from email.mime.text import MIMEText
from email.utils import make_msgid, formatdate
import smtplib
msg = MIMEText(request.POST["id_body"].encode("utf-8"),
_charset="utf-8")
msg["Subject"] = request.POST["subject"]
msg["From"] = request.POST["from_"]
msg["To"] = request.POST["to"]
msg["Message-ID"] = make_msgid()
msg["User-Agent"] = "MailNG"
msg["Date"] = formatdate(time.time(), True)
if origmsg and origmsg.has_key("Message-ID"):
msg["References"] = msg["In-Reply-To"] = origmsg["Message-ID"]
rcpts = msg['To'].split(',')
if "cc" in request.POST.keys():
msg["Cc"] = request.POST["cc"]
rcpts += msg["Cc"].split(",")
try:
s = smtplib.SMTP(parameters.get("webmail", "SMTP_SERVER"))
if parameters.get("webmail", "SMTP_SECURED") == "yes":
s.starttls()
except (smtplib.SMTPException, ssl.SSLError), error:
print error
# Prévoir la remontée de cette erreur au niveau du client!!
if parameters.get("webmail", "SMTP_AUTHENTICATION") == "yes":
s.login(request.user.username, request.session["password"])
s.sendmail(msg['From'], rcpts, msg.as_string())
s.quit()
IMAPconnector(request).push_mail("Sent", msg)
ctx = getctx("ok", url=__get_current_url(request))
else:
ctx = getctx("ko", level=2, listing=render_to_string("webmail/compose.html",
{"form" : form}))
if not withctx:
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
return ctx, HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def compose(request):
if request.method == "POST":
return send_mail(request)
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
return render_compose(request, form, reverse(compose))
@login_required
def reply(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
if request.method == "POST":
ctx, r = send_mail(request, True, origmsg=msg)
if ctx["status"] == "ok":
IMAPconnector(request).msg_answered(folder, mail_id)
return r
email = ImapEmail(msg, True)
lines = email.body.split('\n')
body = ""
for l in lines:
if body != "":
body += "\n"
body += ">%s" % l
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
if not "Reply-To" in msg.keys():
form.fields["to"].initial = email.From
else:
form.fields["to"].initial = email.Reply_To
if request.GET.has_key("all"):
form.fields["cc"].initial = ""
toparse = msg["To"].split(",")
if "Cc" in msg.keys():
toparse += msg["Cc"].split(",")
for addr in toparse:
tmp = EmailAddress(addr)
if tmp.address and tmp.address == request.user.username:
continue
if form.fields["cc"].initial != "":
form.fields["cc"].initial += ", "
form.fields["cc"].initial += tmp.fulladdress
m = re.match("re\s*:\s*.+", email.Subject.lower())
if m:
form.fields["subject"].initial = email.Subject
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]),
textheader, body)
@login_required
def forward(request, folder, mail_id):
if request.method == "POST":
ctx, response = send_mail(request, True)
if ctx["status"] == "ok":
IMAPconnector(request).msgforwarded(folder, mail_id)
return response
msg = fetchmail(request, folder, mail_id, True)
email = ImapEmail(msg, True)
textheader = "----- %s -----" % _("Original message")
textheader += "\n%s: %s" % (_("Subject"), email.Subject)
textheader += "\n%s: %s" % (_("Date"), msg["Date"])
for hdr in ["From", "To", "Reply-To"]:
try:
key = re.sub("-", "_", hdr)
value = getattr(email, key)
textheader += "\n%s: %s" % (_(hdr), value)
except:
pass
textheader += "\n"
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
form.fields["subject"].initial = "Fwd: %s" % email.Subject
return render_compose(request, form, reverse(forward, args=[folder, mail_id]),
textheader, email.body)
+5 -5
View File
@@ -28,7 +28,7 @@ def viewm_menu(selection, backurl, folder, mail_id, perms):
"label" : _("Forward")},
{"name" : "delete",
"img" : "/static/pics/remove.png",
"url" : reverse(webmail.main.delete, args=[folder, mail_id]),
"url" : reverse(webmail.views.delete, args=[folder, mail_id]),
"label" : _("Delete")},
]
@@ -56,7 +56,7 @@ def compose_menu(selection, backurl, perms):
def listing_menu(selection, folder, perms):
entries = [
{"name" : "compose",
"url" : reverse(webmail.main.compose),
"url" : reverse(webmail.views.compose),
"img" : "/static/pics/edit.png",
"label" : _("New message")},
{"name" : "mark",
@@ -66,10 +66,10 @@ def listing_menu(selection, folder, perms):
"menu" : [
{"name" : "mark-read",
"label" : _("As read"),
"url" : reverse(webmail.main.mark, args=[folder]) + "?status=read"},
"url" : reverse(webmail.views.mark, args=[folder]) + "?status=read"},
{"name" : "mark-unread",
"label" : _("As unread"),
"url" : reverse(webmail.main.mark, args=[folder]) + "?status=unread"}
"url" : reverse(webmail.views.mark, args=[folder]) + "?status=unread"}
]
},
{"name" : "actions",
@@ -86,7 +86,7 @@ def listing_menu(selection, folder, perms):
"label" : _("Empty folder"),
"img" : "/static/pics/clear.png",
"url" : folder == "Trash" \
and reverse(webmail.main.empty, args=[folder]) or ""}
and reverse(webmail.views.empty, args=[folder]) or ""}
]
}
]
+1 -1
View File
@@ -1,6 +1,6 @@
from django.conf.urls.defaults import *
urlpatterns = patterns('mailng.extensions.webmail.main',
urlpatterns = patterns('mailng.extensions.webmail.views',
(r'^$', "index"),
(r'^compose/$', "compose"),
(r'^move/$', "move"),
+300
View File
@@ -0,0 +1,300 @@
# -*- coding: utf-8 -*-
import time
import sys
from django.http import HttpResponse, Http404
from django.template import Template, Context
from django.template.loader import render_to_string
from django.utils import simplejson
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from mailng.admin.models import Mailbox
from mailng.lib import parameters, _render, _render_error, getctx
from imap_listing import *
from forms import *
from templatetags.webextras import *
from lib.email_listing import parse_search_parameters
def __get_current_url(request):
res = "%s?page=%s" % (request.session["folder"], request.session["page"])
for p in ["criteria", "pattern", "order"]:
if p in request.session.keys():
res += "&%s=%s" % (p, request.session[p])
return res
@login_required
def folder(request, name, updatenav=True):
if not name:
name = "INBOX"
order = request.GET.has_key("order") and request.GET["order"] or "-date"
if updatenav:
pageid = request.GET.has_key("page") and int(request.GET["page"]) or 1
if not "navparams" in request.session.keys():
request.session["navparams"] = {}
request.session["folder"] = name
request.session["page"] = pageid
if order:
request.session["navparams"]["order"] = order
parse_search_parameters(request)
else:
# Internal usage
order = request.session["navparams"]["order"]
optparams = {}
if request.session.has_key("pattern"):
optparams["pattern"] = request.session["pattern"]
optparams["criteria"] = request.session["criteria"]
else:
optparams["reset"] = True
lst = ImapListing(request.user.username, request.session["password"],
baseurl=name, folder=name, order=order, **optparams)
page = lst.paginator.getpage(request.session["page"])
if page:
content = lst.fetch(request, page.id_start, page.id_stop)
navbar = lst.render_navbar(page)
else:
content = "Empty folder"
navbar = ""
folders = render_to_string("webmail/folders.html", {
"folders" : lst.getfolders()
})
ctx = getctx("ok", folders=folders, listing=content, navbar=navbar,
menu=listing_menu("", name, request.user.get_all_permissions()))
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def index(request):
try:
navp = request.session.has_key("navparams") \
and request.session["navparams"] or {}
lst = ImapListing(request.user.username, request.session["password"],
baseurl="INBOX", navparams=navp, folder="INBOX",
empty=True)
except Exception, exp:
return _render_error(request, {"error" : exp})
return lst.render(request)
def fetchmail(request, folder, mail_id, all=False):
res = IMAPconnector(request).fetch(start=mail_id, folder=folder, all=all)
if len(res):
return res[0]
return None
@login_required
def viewmail(request, folder, mail_id=None):
from templatetags.webextras import viewm_menu
content = Template("""
<iframe width="100%" frameBorder="0" src="{{ url }}" id="mailcontent"></iframe>
""").render(Context({"url" : reverse(getmailcontent, args=[folder, mail_id])}))
menu = viewm_menu("", __get_current_url(request), folder, 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 getmailcontent(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
if "class" in msg.keys() and msg["class"] == "unseen":
IMAPconnector(request).msg_read(folder, mail_id)
email = ImapEmail(msg, mode="html", links="1")
try:
pageid = request.session["page"]
except KeyError:
pageid = "1"
return _render(request, "common/viewmail.html", {
"headers" : email.render_headers(folder=folder, mail_id=mail_id),
"folder" : folder, "imapid" : mail_id, "mailbody" : email.body,
"pre" : email.pre
})
@login_required
def getattachment(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
for part in msg.walk():
fname = part.get_filename()
if fname is None:
continue
decoded = decode_header(fname)
if decoded[0][1] is None:
fname = unicode(decoded[0][0])
else:
fname = unicode(decoded[0][0], decoded[0][1])
if fname == request.GET["fname"]:
resp = HttpResponse(part.get_payload(decode=1))
for hdr in ["Content-Disposition", "Content-Type"]:
resp[hdr] = re.sub("\s", "", part[hdr])
resp["Content-Length"] = len(resp.content)
return resp
raise Http404
@login_required
def move(request):
for arg in ["msgset", "to"]:
if not request.GET.has_key(arg):
return
mbc = IMAPconnector(request)
mbc.move(request.GET["msgset"], request.session["folder"], request.GET["to"])
return folder(request, request.session["folder"], False)
@login_required
def delete(request, fdname, mail_id):
mbc = IMAPconnector(request)
mbc.move(mail_id, fdname, "Trash")
return folder(request, fdname, False)
@login_required
def mark(request, name):
if not request.GET.has_key("status") or not request.GET.has_key("ids"):
return
mbc = IMAPconnector(request)
try:
getattr(mbc, "msg_%s" % request.GET["status"])(name, request.GET["ids"])
except AttributeError:
pass
return folder(request, name, False)
@login_required
def empty(request, name):
if name == "Trash":
mbc = IMAPconnector(request)
mbc.empty(name)
return folder(request, name, False)
@login_required
def compact(request, name):
mbc = IMAPconnector(request)
mbc.compact(name)
return folder(request, name, False)
def render_compose(request, form, posturl, bodyheader=None, body=None):
menu = compose_menu("", __get_current_url(request),
request.user.get_all_permissions())
content = render_to_string("webmail/compose.html", {
"form" : form, "bodyheader" : bodyheader, "body" : body,
"posturl" : posturl
})
ctx = getctx("ok", level=2, menu=menu, listing=content)
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
def send_mail(request, withctx=False, origmsg=None):
form = ComposeMailForm(request.POST)
if form.is_valid():
from email.mime.text import MIMEText
from email.utils import make_msgid, formatdate
import smtplib
msg = MIMEText(request.POST["id_body"].encode("utf-8"),
_charset="utf-8")
msg["Subject"] = request.POST["subject"]
msg["From"] = request.POST["from_"]
msg["To"] = request.POST["to"]
msg["Message-ID"] = make_msgid()
msg["User-Agent"] = "MailNG"
msg["Date"] = formatdate(time.time(), True)
if origmsg and origmsg.has_key("Message-ID"):
msg["References"] = msg["In-Reply-To"] = origmsg["Message-ID"]
rcpts = msg['To'].split(',')
if "cc" in request.POST.keys():
msg["Cc"] = request.POST["cc"]
rcpts += msg["Cc"].split(",")
try:
s = smtplib.SMTP(parameters.get("webmail", "SMTP_SERVER"))
if parameters.get("webmail", "SMTP_SECURED") == "yes":
s.starttls()
except (smtplib.SMTPException, ssl.SSLError), error:
print error
# Prévoir la remontée de cette erreur au niveau du client!!
if parameters.get("webmail", "SMTP_AUTHENTICATION") == "yes":
s.login(request.user.username, request.session["password"])
s.sendmail(msg['From'], rcpts, msg.as_string())
s.quit()
IMAPconnector(request).push_mail("Sent", msg)
ctx = getctx("ok", url=__get_current_url(request))
else:
ctx = getctx("ko", level=2, listing=render_to_string("webmail/compose.html",
{"form" : form}))
if not withctx:
return HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
return ctx, HttpResponse(simplejson.dumps(ctx), mimetype="application/json")
@login_required
def compose(request):
if request.method == "POST":
return send_mail(request)
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
return render_compose(request, form, reverse(compose))
@login_required
def reply(request, folder, mail_id):
msg = fetchmail(request, folder, mail_id, True)
if request.method == "POST":
ctx, r = send_mail(request, True, origmsg=msg)
if ctx["status"] == "ok":
IMAPconnector(request).msg_answered(folder, mail_id)
return r
email = ImapEmail(msg, True)
lines = email.body.split('\n')
body = ""
for l in lines:
if body != "":
body += "\n"
body += ">%s" % l
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
if not "Reply-To" in msg.keys():
form.fields["to"].initial = email.From
else:
form.fields["to"].initial = email.Reply_To
if request.GET.has_key("all"):
form.fields["cc"].initial = ""
toparse = msg["To"].split(",")
if "Cc" in msg.keys():
toparse += msg["Cc"].split(",")
for addr in toparse:
tmp = EmailAddress(addr)
if tmp.address and tmp.address == request.user.username:
continue
if form.fields["cc"].initial != "":
form.fields["cc"].initial += ", "
form.fields["cc"].initial += tmp.fulladdress
m = re.match("re\s*:\s*.+", email.Subject.lower())
if m:
form.fields["subject"].initial = email.Subject
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]),
textheader, body)
@login_required
def forward(request, folder, mail_id):
if request.method == "POST":
ctx, response = send_mail(request, True)
if ctx["status"] == "ok":
IMAPconnector(request).msgforwarded(folder, mail_id)
return response
msg = fetchmail(request, folder, mail_id, True)
email = ImapEmail(msg, True)
textheader = "----- %s -----" % _("Original message")
textheader += "\n%s: %s" % (_("Subject"), email.Subject)
textheader += "\n%s: %s" % (_("Date"), msg["Date"])
for hdr in ["From", "To", "Reply-To"]:
try:
key = re.sub("-", "_", hdr)
value = getattr(email, key)
textheader += "\n%s: %s" % (_(hdr), value)
except:
pass
textheader += "\n"
form = ComposeMailForm()
form.fields["from_"].initial = request.user.username
form.fields["subject"].initial = "Fwd: %s" % email.Subject
return render_compose(request, form, reverse(forward, args=[folder, mail_id]),
textheader, email.body)