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 = {}
|
partial_message_cache = {}
|
||||||
|
|
||||||
def render_body(msg):
|
def render_body(msg):
|
||||||
content_type = msg.get_content_type()
|
def render_text_plain(msg):
|
||||||
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":
|
|
||||||
bodytmpl = jenv.get_template("body_text_plain.html")
|
bodytmpl = jenv.get_template("body_text_plain.html")
|
||||||
context = {
|
context = {
|
||||||
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
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 = []
|
partshtml = []
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
partshtml.append(render_body(part))
|
partshtml.append(render_body(part))
|
||||||
|
@ -107,7 +102,7 @@ def render_body(msg):
|
||||||
"parts": partshtml
|
"parts": partshtml
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
elif content_type == "multipart/digest":
|
def render_multipart_digest(msg):
|
||||||
partshtml = []
|
partshtml = []
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
partshtml.append(render_message(part))
|
partshtml.append(render_message(part))
|
||||||
|
@ -116,7 +111,7 @@ def render_body(msg):
|
||||||
"parts": partshtml
|
"parts": partshtml
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
elif content_type == "message/rfc822":
|
def render_message_rfc822(msg):
|
||||||
partshtml = []
|
partshtml = []
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
partshtml.append(render_message(part))
|
partshtml.append(render_message(part))
|
||||||
|
@ -125,7 +120,7 @@ def render_body(msg):
|
||||||
"parts": partshtml
|
"parts": partshtml
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
elif content_type == "text/html":
|
def render_text_html(msg):
|
||||||
htmlpart = HTMLPart()
|
htmlpart = HTMLPart()
|
||||||
htmlpart.feed(msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1"))
|
htmlpart.feed(msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1"))
|
||||||
bodytmpl = jenv.get_template("body_text_html.html")
|
bodytmpl = jenv.get_template("body_text_html.html")
|
||||||
|
@ -133,7 +128,7 @@ def render_body(msg):
|
||||||
"body": jinja2.Markup(htmlpart.as_string())
|
"body": jinja2.Markup(htmlpart.as_string())
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
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")
|
payload = msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||||
tepart = TextEnrichedPart(payload)
|
tepart = TextEnrichedPart(payload)
|
||||||
bodytmpl = jenv.get_template("body_text_enriched.html")
|
bodytmpl = jenv.get_template("body_text_enriched.html")
|
||||||
|
@ -141,7 +136,7 @@ def render_body(msg):
|
||||||
"body": jinja2.Markup(tepart.as_string())
|
"body": jinja2.Markup(tepart.as_string())
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
elif content_type == "message/partial":
|
def render_message_partial(msg):
|
||||||
# Default header for get_param is Content-Type
|
# Default header for get_param is Content-Type
|
||||||
whole_msg_id = msg.get_param("id")
|
whole_msg_id = msg.get_param("id")
|
||||||
if not whole_msg_id in partial_message_cache:
|
if not whole_msg_id in partial_message_cache:
|
||||||
|
@ -167,10 +162,10 @@ def render_body(msg):
|
||||||
encode_message_id(whole_msg_id),
|
encode_message_id(whole_msg_id),
|
||||||
html.escape(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")
|
bodyhtml = save_part(msg, "attachment")
|
||||||
|
|
||||||
elif content_type == "multipart/signed":
|
def render_multipart_signed(msg):
|
||||||
content, signature = msg.get_payload()
|
content, signature = msg.get_payload()
|
||||||
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
||||||
content_fh.write(content.as_bytes())
|
content_fh.write(content.as_bytes())
|
||||||
|
@ -194,7 +189,7 @@ def render_body(msg):
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
|
|
||||||
elif content_type == "application/pgp":
|
def render_application_pgp(msg):
|
||||||
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
with tempfile.NamedTemporaryFile(buffering=0) as content_fh:
|
||||||
content_fh.write(msg.get_payload(decode=True))
|
content_fh.write(msg.get_payload(decode=True))
|
||||||
r = subprocess.run(["gpg", "--decrypt", content_fh.name],
|
r = subprocess.run(["gpg", "--decrypt", content_fh.name],
|
||||||
|
@ -217,7 +212,7 @@ def render_body(msg):
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
|
|
||||||
elif content_type == "multipart/alternative":
|
def render_multipart_alternative(msg):
|
||||||
partshtml = []
|
partshtml = []
|
||||||
partstypes = []
|
partstypes = []
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
|
@ -230,24 +225,24 @@ def render_body(msg):
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
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")
|
bodytmpl = jenv.get_template("body_application_x-unknown-content-type-scpfile.html")
|
||||||
context = {
|
context = {
|
||||||
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
"body": msg.get_payload(decode=True).decode(msg.get_charset() or "iso-8859-1")
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
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
|
# A PGP signature outside of a multipart/signed - useless
|
||||||
bodytmpl = jenv.get_template("body_application_pgp-signature.html")
|
bodytmpl = jenv.get_template("body_application_pgp-signature.html")
|
||||||
context = {
|
context = {
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
|
|
||||||
elif content_type == "application/x-gzip":
|
def render_application_x_gzip(msg):
|
||||||
bodyhtml = save_part(msg, "attachment")
|
bodyhtml = save_part(msg, "attachment")
|
||||||
|
|
||||||
elif content_type == "message/news":
|
def render_message_news(msg):
|
||||||
partshtml = []
|
partshtml = []
|
||||||
for part in msg.get_payload():
|
for part in msg.get_payload():
|
||||||
partshtml.append(render_message(part))
|
partshtml.append(render_message(part))
|
||||||
|
@ -258,11 +253,37 @@ def render_body(msg):
|
||||||
}
|
}
|
||||||
bodyhtml = bodytmpl.render(context)
|
bodyhtml = bodytmpl.render(context)
|
||||||
|
|
||||||
elif content_type == "image/gif":
|
def render_image_gif(msg):
|
||||||
bodyhtml = save_part(msg, "inline")
|
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:
|
else:
|
||||||
raise RuntimeError("Content-type " + content_type + " not implemented yet")
|
bodyhtml = renderers[content_type](msg)
|
||||||
|
|
||||||
return jinja2.Markup(bodyhtml)
|
return jinja2.Markup(bodyhtml)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue