diff --git a/src/postorius/static/postorius/js/held_messages.js b/src/postorius/static/postorius/js/held_messages.js
index 88e7d03..ceddb63 100644
--- a/src/postorius/static/postorius/js/held_messages.js
+++ b/src/postorius/static/postorius/js/held_messages.js
@@ -9,7 +9,7 @@
success: function(data) {
$('#msg-title').html(data.subject);
$('.modal-footer form input[name="msgid"]').attr('value', msgid);
- $('#held-stripped-message').html(data.stripped_msg.replace(/\n/g, "
"));
+ $('#held-stripped-message').html(data.stripped_msg.body.replace(/\n/g, "
"));
$('#held-full-message').html(data.msg.replace(/\n/g, "
"));
$('#held-messages-modal').modal('show');
},
diff --git a/src/postorius/views/rest.py b/src/postorius/views/rest.py
index df9ddda..31ef3ee 100644
--- a/src/postorius/views/rest.py
+++ b/src/postorius/views/rest.py
@@ -16,46 +16,98 @@
# You should have received a copy of the GNU General Public License along with
# Postorius. If not, see .
import json
+import email
+import sys
-from email import message_from_string
+from email.Header import decode_header
+from base64 import b64decode
+from email.Parser import Parser as EmailParser
+from email.utils import parseaddr
+from StringIO import StringIO
from django.http import HttpResponse, Http404
-
from django.contrib.auth.decorators import login_required
from django.utils.translation import gettext as _
+
from postorius.auth.decorators import *
-def _strip_email(email_text):
- """Strip most of the headers from the email for the
- held messages view.
+# based on https://www.ianlewis.org/en/parsing-email-attachments-python
+def parse_attachment(message_part, counter):
+ content_disposition = message_part.get("Content-Disposition", None)
+ if content_disposition:
+ dispositions = content_disposition.strip().split(";")
+ if bool(content_disposition and dispositions[0].lower() == "attachment"):
- Only these headers would be kept:
- - To
- - From
- - Date
- - CC
- - Subject
+ file_data = message_part.get_payload(decode=True)
+ attachment = StringIO(file_data)
+ attachment.content_type = message_part.get_content_type()
+ attachment.size = len(file_data)
+ attachment.name = message_part.get_filename()
- If available, show only the text part of the email.
+ if not attachment.name:
+ ext = mimetypes.guess_extension(part.get_content_type())
+ if not ext:
+ ext = '.bin'
+ attachment.name = 'part-%03d%s' % (counter, ext)
- TODO: maxking - modify this later to extract text from HTML
- to be displayed there.
- """
- msg = message_from_string(email_text)
+ return attachment
+ return None
- content_type = msg.get_content_type()
- if content_type == 'multipart/alternative':
- for part in msg.walk():
- if part.get_content_type() == 'text/plain':
- msg.set_payload(part.as_string())
+def parse(content):
+ p = EmailParser()
+ msgobj = p.parsestr(content)
+ if msgobj['Subject'] is not None:
+ decodefrag = decode_header(msgobj['Subject'])
+ subj_fragments = []
+ for s , enc in decodefrag:
+ if enc:
+ s = unicode(s , enc).encode('utf8','replace')
+ subj_fragments.append(s)
+ subject = ''.join(subj_fragments)
+ else:
+ subject = None
- show_headers = ['To', 'From', 'Date', 'CC', 'Subject']
- for header in msg.keys():
- if header not in show_headers:
- del msg[header]
+ attachments = []
+ body = None
+ html = None
+ counter = 1
+ for part in msgobj.walk():
+ attachment = parse_attachment(part, counter)
+ if attachment:
+ attachments.append(attachment)
+ counter += 1
+ elif part.get_content_type() == "text/plain":
+ if body is None:
+ body = ""
+ if part.get_content_charset():
+ body += unicode(
+ part.get_payload(decode=True),
+ part.get_content_charset(),
+ 'replace'
+ ).encode('utf8','replace')
+ else:
+ body += part.get_payload(decode=True)
+ elif part.get_content_type() == "text/html":
+ if html is None:
+ html = ""
+ if part.get_content_charset():
+ html += unicode(
+ part.get_payload(decode=True),
+ part.get_content_charset(),
+ 'replace'
+ ).encode('utf8','replace')
+ else:
+ html += part.get_payload(decode=True)
+ return {
+ 'subject' : subject,
+ 'body' : body,
+ 'html' : html,
+ 'from' : parseaddr(msgobj.get('From'))[1],
+ 'to' : parseaddr(msgobj.get('To'))[1],
+ #'attachments': attachments,
+ }
- return msg.as_string()
@login_required
@list_moderator_required
@@ -76,7 +128,7 @@
response_data['moderation_reasons'] = held_message.moderation_reasons
response_data['hold_date'] = held_message.hold_date
response_data['msg'] = held_message.msg
- response_data['stripped_msg'] = _strip_email(held_message.msg)
+ response_data['stripped_msg'] = parse(held_message.msg)
response_data['msgid'] = held_message.request_id
response_data['subject'] = held_message.subject