Reduces complexity of object_from_message

Helper functions created to help break up the flow
This commit is contained in:
Martin Whitehouse 2022-07-25 02:22:32 +02:00
parent a5e74d6449
commit 4e2b7deefb
No known key found for this signature in database
GPG Key ID: 3FCE1D3E9DEC09C1

View File

@ -528,6 +528,52 @@ def get_ticket_id_from_subject_slug(
return ticket_id return ticket_id
def add_file_if_always_save_incoming_email_message(
files_: list[SimpleUploadedFile],
message: str
) -> None:
"""When `settings.HELPDESK_ALWAYS_SAVE_INCOMING_EMAIL_MESSAGE` is `True`
add a file to the files_ list"""
if getattr(django_settings, 'HELPDESK_ALWAYS_SAVE_INCOMING_EMAIL_MESSAGE', False):
# save message as attachment in case of some complex markup renders
# wrong
files_.append(
SimpleUploadedFile(
_("original_message.eml").replace(
".eml",
timezone.localtime().strftime("_%d-%m-%Y_%H:%M") + ".eml"
),
str(message).encode("utf-8"),
'text/plain'
)
)
def get_encoded_body(body: str) -> str:
try:
return body.encode('ascii').decode('unicode_escape')
except UnicodeEncodeError:
return body.encode('utf-8')
def get_body_from_fragments(body) -> str:
"""Gets a body from the fragments, joined by a double line break"""
return "\n\n".join(f.content for f in EmailReplyParser.read(body).fragments)
def get_email_body_from_part_payload(part) -> str:
"""Gets an decoded body from the payload part, if the decode fails,
returns without encoding"""
try:
return encoding.smart_str(
part.get_payload(decode=True)
)
except UnicodeDecodeError:
return encoding.smart_str(
part.get_payload(decode=False)
)
def object_from_message(message: str, def object_from_message(message: str,
queue: Queue, queue: Queue,
logger: logging.Logger logger: logging.Logger
@ -591,29 +637,17 @@ def object_from_message(message: str,
if ticket_id is None and getattr(django_settings, 'HELPDESK_FULL_FIRST_MESSAGE_FROM_EMAIL', False): if ticket_id is None and getattr(django_settings, 'HELPDESK_FULL_FIRST_MESSAGE_FROM_EMAIL', False):
# first message in thread, we save full body to avoid # first message in thread, we save full body to avoid
# losing forwards and things like that # losing forwards and things like that
body_parts = [] body = EmailReplyParser.parse_reply(get_body_from_fragments(body))
for f in EmailReplyParser.read(body).fragments:
body_parts.append(f.content)
full_body = '\n\n'.join(body_parts)
body = EmailReplyParser.parse_reply(body)
else: else:
# second and other reply, save only first part of the # second and other reply, save only first part of the
# message # message
body = EmailReplyParser.parse_reply(body) body = EmailReplyParser.parse_reply(body)
full_body = body full_body = body
# workaround to get unicode text out rather than escaped text # workaround to get unicode text out rather than escaped text
try: body = get_encoded_body(body)
body = body.encode('ascii').decode('unicode_escape')
except UnicodeEncodeError:
body.encode('utf-8')
logger.debug("Discovered plain text MIME part") logger.debug("Discovered plain text MIME part")
else: else:
try: email_body = get_email_body_from_part_payload(part)
email_body = encoding.smart_str(
part.get_payload(decode=True))
except UnicodeDecodeError:
email_body = encoding.smart_str(
part.get_payload(decode=False))
if not body and not full_body: if not body and not full_body:
# no text has been parsed so far - try such deep parsing # no text has been parsed so far - try such deep parsing
@ -680,19 +714,7 @@ def object_from_message(message: str,
if not body: if not body:
body = "" body = ""
if getattr(django_settings, 'HELPDESK_ALWAYS_SAVE_INCOMING_EMAIL_MESSAGE', False): add_file_if_always_save_incoming_email_message(files, message)
# save message as attachment in case of some complex markup renders
# wrong
files.append(
SimpleUploadedFile(
_("original_message.eml").replace(
".eml",
timezone.localtime().strftime("_%d-%m-%Y_%H:%M") + ".eml"
),
str(message).encode("utf-8"),
'text/plain'
)
)
smtp_priority = message.get('priority', '') smtp_priority = message.get('priority', '')
smtp_importance = message.get('importance', '') smtp_importance = message.get('importance', '')