Refactor render_body to handle each mime-type in a nested function
This replaces the giant elif cascade with a table lookup. It also allows me to call one function from another.
This commit is contained in:
parent
035b4e1002
commit
b053ab454f
73
mbox2web
73
mbox2web
|
@ -83,22 +83,17 @@ def save_part(msg, disposition):
|
|||
partial_message_cache = {}
|
||||
|
||||
def render_body(msg):
|
||||
content_type = msg.get_content_type()
|
||||
content_disposition = msg.get_content_disposition()
|
||||
if content_disposition == "attachment":
|
||||
# XXX - not sure, if we should just store all content-types.
|
||||
# We probably should clean up html. Alternatively we could just store
|
||||
# all of them application/octet-stream, which browsers should download
|
||||
# and not try to display.
|
||||
bodyhtml = save_part(msg, content_disposition)
|
||||
|
||||
elif content_type == "text/plain":
|
||||
def render_text_plain(msg):
|
||||
bodytmpl = jenv.get_template("body_text_plain.html")
|
||||
context = {
|
||||
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "multipart/mixed":
|
||||
def render_multipart_mixed(msg):
|
||||
parts = msg.get_payload()
|
||||
if type(parts) == str:
|
||||
# mislabelled, assume text/plain
|
||||
raise NotImplementedError()
|
||||
partshtml = []
|
||||
for part in msg.get_payload():
|
||||
partshtml.append(render_body(part))
|
||||
|
@ -107,7 +102,7 @@ def render_body(msg):
|
|||
"parts": partshtml
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "multipart/digest":
|
||||
def render_multipart_digest(msg):
|
||||
partshtml = []
|
||||
for part in msg.get_payload():
|
||||
partshtml.append(render_message(part))
|
||||
|
@ -116,7 +111,7 @@ def render_body(msg):
|
|||
"parts": partshtml
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "message/rfc822":
|
||||
def render_message_rfc822(msg):
|
||||
partshtml = []
|
||||
for part in msg.get_payload():
|
||||
partshtml.append(render_message(part))
|
||||
|
@ -125,7 +120,7 @@ def render_body(msg):
|
|||
"parts": partshtml
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "text/html":
|
||||
def render_text_html(msg):
|
||||
htmlpart = HTMLPart()
|
||||
htmlpart.feed(msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1"))
|
||||
bodytmpl = jenv.get_template("body_text_html.html")
|
||||
|
@ -133,7 +128,7 @@ def render_body(msg):
|
|||
"body": jinja2.Markup(htmlpart.as_string())
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "text/enriched":
|
||||
def render_text_enriched(msg):
|
||||
payload = msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||
tepart = TextEnrichedPart(payload)
|
||||
bodytmpl = jenv.get_template("body_text_enriched.html")
|
||||
|
@ -141,7 +136,7 @@ def render_body(msg):
|
|||
"body": jinja2.Markup(tepart.as_string())
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
elif content_type == "message/partial":
|
||||
def render_message_partial(msg):
|
||||
# Default header for get_param is Content-Type
|
||||
whole_msg_id = msg.get_param("id")
|
||||
if not whole_msg_id in partial_message_cache:
|
||||
|
@ -167,10 +162,10 @@ def render_body(msg):
|
|||
encode_message_id(whole_msg_id),
|
||||
html.escape(whole_msg_id))
|
||||
|
||||
elif content_type == "application/octet-stream":
|
||||
def render_application_octet_stream(msg):
|
||||
bodyhtml = save_part(msg, "attachment")
|
||||
|
||||
elif content_type == "multipart/signed":
|
||||
def render_multipart_signed(msg):
|
||||
content, signature = msg.get_payload()
|
||||
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
||||
content_fh.write(content.as_bytes())
|
||||
|
@ -194,7 +189,7 @@ def render_body(msg):
|
|||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "application/pgp":
|
||||
def render_application_pgp(msg):
|
||||
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
||||
content_fh.write(msg.get_payload(decode=True))
|
||||
r = subprocess.run(["gpg", "--decrypt", content_fh.name],
|
||||
|
@ -217,7 +212,7 @@ def render_body(msg):
|
|||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "multipart/alternative":
|
||||
def render_multipart_alternative(msg):
|
||||
partshtml = []
|
||||
partstypes = []
|
||||
for part in msg.get_payload():
|
||||
|
@ -230,24 +225,24 @@ def render_body(msg):
|
|||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "application/x-unknown-content-type-scpfile":
|
||||
def render_application_x_unknown_content_type_scpfile(msg):
|
||||
bodytmpl = jenv.get_template("body_application_x-unknown-content-type-scpfile.html")
|
||||
context = {
|
||||
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "application/pgp-signature":
|
||||
def render_application_pgp_signature(msg):
|
||||
# A PGP signature outside of a multipart/signed - useless
|
||||
bodytmpl = jenv.get_template("body_application_pgp-signature.html")
|
||||
context = {
|
||||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "application/x-gzip":
|
||||
def render_application_x_gzip(msg):
|
||||
bodyhtml = save_part(msg, "attachment")
|
||||
|
||||
elif content_type == "message/news":
|
||||
def render_message_news(msg):
|
||||
partshtml = []
|
||||
for part in msg.get_payload():
|
||||
partshtml.append(render_message(part))
|
||||
|
@ -258,11 +253,37 @@ def render_body(msg):
|
|||
}
|
||||
bodyhtml = bodytmpl.render(context)
|
||||
|
||||
elif content_type == "image/gif":
|
||||
def render_image_gif(msg):
|
||||
bodyhtml = save_part(msg, "inline")
|
||||
|
||||
renderers = {
|
||||
"text/plain": render_text_plain,
|
||||
"multipart/mixed": render_multipart_mixed,
|
||||
"multipart/digest": render_multipart_digest,
|
||||
"message/rfc822": render_message_rfc822,
|
||||
"text/html": render_text_html,
|
||||
"text/enriched": render_text_enriched,
|
||||
"message/partial": render_message_partial,
|
||||
"application/octet-stream": render_application_octet_stream,
|
||||
"multipart/signed": render_multipart_signed,
|
||||
"application/pgp": render_application_pgp,
|
||||
"multipart/alternative": render_multipart_alternative,
|
||||
"application/x-unknown-content-type-scpfile": render_application_x_unknown_content_type_scpfile,
|
||||
"application/pgp-signature": render_application_pgp_signature,
|
||||
"application/x-gzip": render_application_x_gzip,
|
||||
"message/news": render_message_news,
|
||||
"image/gif": render_image_gif,
|
||||
}
|
||||
content_type = msg.get_content_type()
|
||||
content_disposition = msg.get_content_disposition()
|
||||
if content_disposition == "attachment":
|
||||
# XXX - not sure, if we should just store all content-types.
|
||||
# We probably should clean up html. Alternatively we could just store
|
||||
# all of them application/octet-stream, which browsers should download
|
||||
# and not try to display.
|
||||
bodyhtml = save_part(msg, content_disposition)
|
||||
else:
|
||||
raise RuntimeError("Content-type " + content_type + " not implemented yet")
|
||||
bodyhtml = renderers[content_type](msg)
|
||||
|
||||
return jinja2.Markup(bodyhtml)
|
||||
|
||||
|
|
Loading…
Reference in New Issue