Handle image/gif (inline)

Inline images are very similar to attachments: We just want to store
them somewhere and refer to them. But we want to use a different element
(<img> instead of <a>) or more generally, a different template. So we
pass the disposition as an additional argument to save_part and use it
to construct the template name - which gives as a flurry of new
templates.
This commit is contained in:
Peter J. Holzer 2019-03-10 23:27:30 +01:00
parent df7fcb5777
commit a997542cfe
8 changed files with 76 additions and 5 deletions

View File

@ -51,7 +51,7 @@ def render_message(msg):
return jinja2.Markup(msghtml) return jinja2.Markup(msghtml)
def save_part(msg): def save_part(msg, disposition):
content_type = msg.get_content_type() content_type = msg.get_content_type()
extension = { extension = {
"application/octet-stream": ".bin", "application/octet-stream": ".bin",
@ -59,6 +59,7 @@ def save_part(msg):
"text/x-vcard": ".vcf", "text/x-vcard": ".vcf",
"text/plain": ".txt", "text/plain": ".txt",
"application/x-gzip": ".gz", # more likely tar.gz, but we can't know without looking into it which we ain't "application/x-gzip": ".gz", # more likely tar.gz, but we can't know without looking into it which we ain't
"image/gif": ".gif",
}[content_type] }[content_type]
name = msg.get_param("name") or "(data)" name = msg.get_param("name") or "(data)"
@ -69,7 +70,8 @@ def save_part(msg):
os.makedirs("parts", exist_ok=True) os.makedirs("parts", exist_ok=True)
with open("parts/" + filename, "wb") as fh: with open("parts/" + filename, "wb") as fh:
fh.write(payload) fh.write(payload)
bodytmpl = jenv.get_template("body_application_octet_stream.html") template_name = disposition + "_" + content_type.replace("/", "_") + ".html"
bodytmpl = jenv.get_template(template_name)
context = { context = {
"name": name, "name": name,
"url": "../../parts/" + filename, "url": "../../parts/" + filename,
@ -88,7 +90,7 @@ def render_body(msg):
# We probably should clean up html. Alternatively we could just store # We probably should clean up html. Alternatively we could just store
# all of them application/octet-stream, which browsers should download # all of them application/octet-stream, which browsers should download
# and not try to display. # and not try to display.
bodyhtml = save_part(msg) bodyhtml = save_part(msg, content_disposition)
elif content_type == "text/plain": elif content_type == "text/plain":
bodytmpl = jenv.get_template("body_text_plain.html") bodytmpl = jenv.get_template("body_text_plain.html")
@ -165,7 +167,7 @@ def render_body(msg):
html.escape(whole_msg_id)) html.escape(whole_msg_id))
elif content_type == "application/octet-stream": elif content_type == "application/octet-stream":
bodyhtml = save_part(msg) bodyhtml = save_part(msg, "attachment")
elif content_type == "multipart/signed": elif content_type == "multipart/signed":
content, signature = msg.get_payload() content, signature = msg.get_payload()
@ -242,7 +244,7 @@ def render_body(msg):
bodyhtml = bodytmpl.render(context) bodyhtml = bodytmpl.render(context)
elif content_type == "application/x-gzip": elif content_type == "application/x-gzip":
bodyhtml = save_part(msg) bodyhtml = save_part(msg, "attachment")
elif content_type == "message/news": elif content_type == "message/news":
partshtml = [] partshtml = []
@ -254,6 +256,10 @@ def render_body(msg):
"parts": partshtml, "parts": partshtml,
} }
bodyhtml = bodytmpl.render(context) bodyhtml = bodytmpl.render(context)
elif content_type == "image/gif":
bodyhtml = save_part(msg, "inline")
else: else:
raise RuntimeError("Content-type " + content_type + " not implemented yet") raise RuntimeError("Content-type " + content_type + " not implemented yet")
@ -286,6 +292,7 @@ class HTMLPart(html.parser.HTMLParser):
"h2", "a", "wbr", "hr", "pre", "img", "font", "i", "br", "table", "tr", "h2", "a", "wbr", "hr", "pre", "img", "font", "i", "br", "table", "tr",
"th", "td", "b", "select", "option", "input", "sup", "address", "th", "td", "b", "select", "option", "input", "sup", "address",
"center", "p", "h1", "dl", "h3", "ul", "li", "ol", "u", "blockquote", "center", "p", "h1", "dl", "h3", "ul", "li", "ol", "u", "blockquote",
"h4",
] ]
hide_tags = [ "title" ] hide_tags = [ "title" ]
ignore_tags = [ "html", "head", "body", "marquee", "meta", "form", ] ignore_tags = [ "html", "head", "body", "marquee", "meta", "form", ]

View File

@ -0,0 +1,9 @@
<div class="partouter">
<div class="partheader">
application/octet-stream
</div>
<div class="partinner">
<a href="{{url}}">{{name}}</a>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="partouter">
<div class="partheader">
application/x-gzip
</div>
<div class="partinner">
<a href="{{url}}">{{name}}</a>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="partouter">
<div class="partheader">
text/html (attachment)
</div>
<div class="partinner">
<a href="{{url}}">{{name}}</a>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="partouter">
<div class="partheader">
text/plain (attachment)
</div>
<div class="partinner">
<a href="{{url}}">{{name}}</a>
</div>
</div>

View File

@ -0,0 +1,9 @@
<div class="partouter">
<div class="partheader">
text/x-vcard
</div>
<div class="partinner">
<a href="{{url}}">{{name}}</a>
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="partouter">
<div class="partheader">
message/news
</div>
<div class="partinner">
{% for p in parts %}
{{p}}
{% endfor %}
</div>
</div>

View File

@ -0,0 +1,8 @@
<div class="partouter">
<div class="partheader">
image/gif
</div>
<div class="partinner">
<img src="{{url}}" alt="{{name}}">
</div>
</div>