mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-18 05:51:26 +02:00
It is now possible to access emails attachments.
This commit is contained in:
@@ -243,3 +243,4 @@ class ImapEmail(Email):
|
||||
self.headers += [{"name" : label, "value" : getattr(IMAPheader, "parse_%s" % f.lower())(msg[f])}]
|
||||
except AttributeError:
|
||||
self.headers += [{"name" : label, "value" : msg[f]}]
|
||||
|
||||
|
||||
+35
-14
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import sys
|
||||
from django.http import HttpResponse
|
||||
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
|
||||
@@ -114,19 +114,40 @@ def viewmail(request, folder, mail_id=None):
|
||||
|
||||
@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).msgseen(msg["imapid"])
|
||||
email = ImapEmail(msg, mode="html", links="1")
|
||||
try:
|
||||
pageid = request.session["page"]
|
||||
except KeyError:
|
||||
pageid = "1"
|
||||
folder, imapid = msg["imapid"].split("/")
|
||||
return _render(request, "webmail/viewmail.html", {
|
||||
"headers" : email.render_headers(), "folder" : folder,
|
||||
"imapid" : imapid, "mailbody" : email.body, "pre" : email.pre
|
||||
})
|
||||
msg = fetchmail(request, folder, mail_id, True)
|
||||
if "class" in msg.keys() and msg["class"] == "unseen":
|
||||
IMAPconnector(request).msgseen(msg["imapid"])
|
||||
email = ImapEmail(msg, mode="html", links="1")
|
||||
try:
|
||||
pageid = request.session["page"]
|
||||
except KeyError:
|
||||
pageid = "1"
|
||||
folder, imapid = msg["imapid"].split("/")
|
||||
return _render(request, "webmail/viewmail.html", {
|
||||
"headers" : email.render_headers(folder, mail_id),
|
||||
"folder" : folder, "imapid" : imapid, "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):
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
{% load i18n %}
|
||||
<table id="emailheaders">
|
||||
{% for hdr in headers %}
|
||||
<tr><th width="130px">{{ hdr.name }}</th><td>{{ hdr.value }}</td></tr>
|
||||
{% endfor %}
|
||||
{% if attachments %}
|
||||
<tr>
|
||||
<th>{% trans "Attachments" %}</th>
|
||||
<td>
|
||||
{% url extensions.webmail.main.getattachment folder mail_id as test %}
|
||||
{% for attachment in attachments %}
|
||||
<a href="{{ test }}?fname={{ attachment }}">{{ attachment }}</a>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
</table>
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
#emailheaders th {
|
||||
background: #F7F9Fb;
|
||||
}
|
||||
#emailheaders a, #emailheaders a:visited {
|
||||
color: blue;
|
||||
text-decoration: none;
|
||||
}
|
||||
#emailheaders a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -5,6 +5,7 @@ urlpatterns = patterns('mailng.extensions.webmail.main',
|
||||
(r'^compose/$', "compose"),
|
||||
(r'^move/$', "move"),
|
||||
(r'^empty/(?P<name>.+)/', "empty"),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/part/$', 'getattachment'),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/content/$', 'getmailcontent'),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/reply/$', 'reply'),
|
||||
(r'^(?P<folder>.+)/(?P<mail_id>[\w\-\+]+)/$', 'viewmail'),
|
||||
|
||||
+18
-3
@@ -1,11 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import re
|
||||
from email.header import decode_header
|
||||
import lxml
|
||||
import lxml.html
|
||||
from lxml import etree
|
||||
from django.template.loader import render_to_string
|
||||
from django.template import Template, Context
|
||||
from django.utils.translation import ugettext as _
|
||||
from mailng.lib import _render, decode
|
||||
|
||||
attached_map = {}
|
||||
@@ -126,9 +128,13 @@ class Email(object):
|
||||
self.attached_map = {}
|
||||
contents = {"html" : "", "plain" : ""}
|
||||
self.headers = []
|
||||
self.attachments = []
|
||||
for part in msg.walk():
|
||||
if part.get_content_maintype() == 'multipart':
|
||||
continue
|
||||
if part.has_key("Content-Disposition"):
|
||||
if re.match("^attachment", part["Content-Disposition"]):
|
||||
self.attachments += [part]
|
||||
if part.get_content_type() in ("text/html", "text/plain"):
|
||||
contents[part.get_content_subtype()] += part.get_payload(decode=True)
|
||||
if mode != "html" or links == "0":
|
||||
@@ -168,9 +174,18 @@ class Email(object):
|
||||
return map[m.group(1)]
|
||||
return url
|
||||
|
||||
def render_headers(self):
|
||||
def render_headers(self, folder, mail_id):
|
||||
attachments = []
|
||||
for part in self.attachments:
|
||||
decoded = decode_header(part.get_filename())
|
||||
if decoded[0][1] is None:
|
||||
attachments += [decoded[0][0]]
|
||||
else:
|
||||
attachments += [unicode(decoded[0][0], decoded[0][1])]
|
||||
return render_to_string("webmail/headers.html", {
|
||||
"headers" : self.headers
|
||||
"headers" : self.headers,
|
||||
"folder" : folder, "mail_id" : mail_id,
|
||||
"attachments" : attachments != [] and attachments or None
|
||||
})
|
||||
|
||||
def render(self, request):
|
||||
@@ -190,7 +205,7 @@ class Email(object):
|
||||
else:
|
||||
html.rewrite_links(self.map_cid)
|
||||
body = html.find("body")
|
||||
if not body:
|
||||
if body is None:
|
||||
body = lxml.html.tostring(html)
|
||||
else:
|
||||
body = lxml.html.tostring(body)
|
||||
|
||||
Reference in New Issue
Block a user