Skip to content

Commit a8c8157

Browse files
committed
Add better functions to decode emails.
See ietf-tools#1042 - Legacy-Id: 5750
1 parent a41abe3 commit a8c8157

1 file changed

Lines changed: 57 additions & 24 deletions

File tree

ietf/nomcom/utils.py

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import datetime
2-
import email
32
import hashlib
43
import os
54
import re
65
import tempfile
76

7+
from email.header import decode_header
88
from email.utils import parseaddr
9+
from email.Iterators import typed_subpart_iterator
10+
from email import message_from_string
911

1012
from django.conf import settings
1113
from django.contrib.sites.models import Site
@@ -153,29 +155,6 @@ def store_nomcom_private_key(request, year, private_key):
153155
request.session['NOMCOM_PRIVATE_KEY_%s' % year] = out
154156

155157

156-
def extract_body(payload):
157-
if isinstance(payload, str):
158-
return payload
159-
else:
160-
if payload:
161-
return '\n'.join([extract_body(part.get_payload()) for part in payload])
162-
163-
164-
def parse_email(text):
165-
if isinstance(text, unicode):
166-
text = str(text)
167-
msg = email.message_from_string(text)
168-
169-
# comment
170-
#body = quopri.decodestring(extract_body(msg.get_payload()))
171-
charset = msg.get_content_charset()
172-
body = extract_body(msg.get_payload())
173-
if charset:
174-
body = body.decode(charset)
175-
176-
return msg['From'], msg['Subject'], body
177-
178-
179158
def validate_private_key(key):
180159
key_file = tempfile.NamedTemporaryFile(delete=False)
181160
key_file.write(key)
@@ -346,6 +325,60 @@ def get_or_create_nominee(nomcom, candidate_name, candidate_email, position, aut
346325
return nominee
347326

348327

328+
def getheader(header_text, default="ascii"):
329+
"""Decode the specified header"""
330+
331+
headers = decode_header(header_text)
332+
header_sections = [unicode(text, charset or default)
333+
for text, charset in headers]
334+
return u"".join(header_sections)
335+
336+
337+
def get_charset(message, default="ascii"):
338+
"""Get the message charset"""
339+
340+
if message.get_content_charset():
341+
return message.get_content_charset()
342+
343+
if message.get_charset():
344+
return message.get_charset()
345+
346+
return default
347+
348+
349+
def get_body(message):
350+
"""Get the body of the email message"""
351+
352+
if message.is_multipart():
353+
# get the plain text version only
354+
text_parts = [part for part in typed_subpart_iterator(message,
355+
'text',
356+
'plain')]
357+
body = []
358+
for part in text_parts:
359+
charset = get_charset(part, get_charset(message))
360+
body.append(unicode(part.get_payload(decode=True),
361+
charset,
362+
"replace"))
363+
364+
return u"\n".join(body).strip()
365+
366+
else: # if it is not multipart, the payload will be a string
367+
# representing the message body
368+
body = unicode(message.get_payload(decode=True),
369+
get_charset(message),
370+
"replace")
371+
return body.strip()
372+
373+
374+
def parse_email(text):
375+
msg = message_from_string(text)
376+
377+
body = get_body(msg)
378+
subject = getheader(msg['Subject'])
379+
return msg['From'], subject, body
380+
381+
349382
def create_feedback_email(nomcom, msg):
350383
from ietf.nomcom.models import Feedback
351384
by, subject, body = parse_email(msg)

0 commit comments

Comments
 (0)