From bdb14d5b5fff9c53ea2684a8180f7a9e55dcc8f3 Mon Sep 17 00:00:00 2001 From: "Jannis M. Hoffmann" Date: Thu, 5 Dec 2024 21:51:33 +0100 Subject: allow rendering of an attachment for multipart/alternative --- src/jwebmail/read_mails.py | 2 +- src/jwebmail/render_mail.py | 69 +++++++++++++++++++++++++-------------------- 2 files changed, 40 insertions(+), 31 deletions(-) (limited to 'src/jwebmail') diff --git a/src/jwebmail/read_mails.py b/src/jwebmail/read_mails.py index f0f37c6..4e2b0c7 100644 --- a/src/jwebmail/read_mails.py +++ b/src/jwebmail/read_mails.py @@ -164,7 +164,7 @@ def _build_qma(username, password): def login(username, password): try: - qma = _build_qma(username, password).open() + _build_qma(username, password).open() except QMAuthError as err: if err.rc == 1: return False diff --git a/src/jwebmail/render_mail.py b/src/jwebmail/render_mail.py index f76c40a..3f72d19 100644 --- a/src/jwebmail/render_mail.py +++ b/src/jwebmail/render_mail.py @@ -40,18 +40,20 @@ def render_multipart_alternative(_subtype, content, path): T += f"
  • {to_mime_type(init['head'])}
  • " C += "
    \n" - C += mime_render( - *to_mime_types(init["head"]), init["body"], path + (len(parts) - 1,) - ) + if init["head"].get("content_disposition", "").lower() == "attachment": + C += _as_download(init, path + (len(parts) - 1,)) + else: + C += mime_render(init["head"], init.get("body"), path + (len(parts) - 1,)) C += "
    \n" for i, r in enumerate(rest, 1): T += f"
  • {to_mime_type(r['head'])}
  • \n" C += '\n" C += "" @@ -70,24 +72,9 @@ def render_multipart(_subtype, content, path): or p["head"]["content_disposition"].lower() == "none" or p["head"]["content_disposition"].lower() == "inline" ): - R += mime_render(*to_mime_types(p["head"]), p["body"], path + (i,)) + R += mime_render(p["head"], p["body"], path + (i,)) elif p["head"]["content_disposition"].lower() == "attachment": - link_text = gettext("Attachment {filename} of type {filetype}").format( - filename=p["head"]["filename"], filetype=to_mime_type(p["head"]) - ) - - ref_url = url_for( - "read", - folder=request.view_args.get("folder"), - msgid=request.view_args["msgid"], - path=".".join(map(str, [*path, i])), - format="raw", - ) - - R += "

    " - R += f'\n' - R += f"{escape(link_text)}\n" - R += "

    \n" + R += _as_download(p, [*path, i]) else: current_app.log.warning( "unknown Content-Disposition %s", p["head"]["content_disposition"] @@ -99,6 +86,26 @@ def render_multipart(_subtype, content, path): return R + "\n" +def _as_download(part, path): + link_text = gettext("Attachment {filename} of type {filetype}").format( + filename=part["head"]["filename"], filetype=to_mime_type(part["head"]) + ) + + ref_url = url_for( + "read", + folder=request.view_args.get("folder"), + msgid=request.view_args["msgid"], + path=".".join(map(str, path)), + format="raw", + ) + + R = "

    " + R += f'\n' + R += f"{escape(link_text)}\n" + R += "

    \n" + return R + + def _format_header(category, value): R = "" @@ -135,7 +142,7 @@ def render_message(subtype, msg, path): R += f"
    {to_mime_type(msg['head']['mime'])}
    \n" R += "\n" - R += mime_render(*to_mime_types(msg["head"]["mime"]), msg["body"], path + (0,)) + R += mime_render(msg["head"]["mime"], msg["body"], path + (0,)) return R + "\n" @@ -150,7 +157,9 @@ MIMERenderSubs = { } -def mime_render(maintype, subtype, content, path): +def mime_render(mime_header, content, path): + maintype = escape(mime_header["content_maintype"]) + subtype = escape(mime_header["content_subtype"]) renderer = MIMERenderSubs.get((maintype, subtype)) or MIMERenderSubs.get(maintype) if not renderer: @@ -165,9 +174,9 @@ def to_mime_type(mime): return escape(f"{mime['content_maintype']}/{mime['content_subtype']}".lower()) -def to_mime_types(mime): - return escape(mime["content_maintype"]), escape(mime["content_subtype"]) - - def format_mail(mail): - return Markup(mime_render("message", "rfc822", mail, tuple())) + return Markup( + mime_render( + {"content_maintype": "message", "content_subtype": "rfc822"}, mail, tuple() + ) + ) -- cgit v1.2.3