From ed68b15a31f8084216d541dc8ee8067ef6c35e29 Mon Sep 17 00:00:00 2001 From: Eric Severance Date: Fri, 21 Aug 2020 07:37:08 -0700 Subject: [PATCH] Support unknown mime type for image attachments in html email (#38682) --- homeassistant/components/smtp/notify.py | 58 ++++++++++++------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/homeassistant/components/smtp/notify.py b/homeassistant/components/smtp/notify.py index 30d7ea2645ec18..296a419c5d0f7d 100644 --- a/homeassistant/components/smtp/notify.py +++ b/homeassistant/components/smtp/notify.py @@ -215,6 +215,29 @@ def _build_text_msg(message): return MIMEText(message) +def _attach_file(atch_name, content_id): + """Create a message attachment.""" + try: + with open(atch_name, "rb") as attachment_file: + file_bytes = attachment_file.read() + except FileNotFoundError: + _LOGGER.warning("Attachment %s not found. Skipping", atch_name) + return None + + try: + attachment = MIMEImage(file_bytes) + except TypeError: + _LOGGER.warning( + "Attachment %s has an unknown MIME type. " "Falling back to file", + atch_name, + ) + attachment = MIMEApplication(file_bytes, Name=atch_name) + attachment["Content-Disposition"] = "attachment; " 'filename="%s"' % atch_name + + attachment.add_header("Content-ID", f"<{content_id}>") + return attachment + + def _build_multipart_msg(message, images): """Build Multipart message with in-line images.""" _LOGGER.debug("Building multipart email with embedded attachment(s)") @@ -228,26 +251,9 @@ def _build_multipart_msg(message, images): for atch_num, atch_name in enumerate(images): cid = f"image{atch_num}" body_text.append(f'
') - try: - with open(atch_name, "rb") as attachment_file: - file_bytes = attachment_file.read() - try: - attachment = MIMEImage(file_bytes) - msg.attach(attachment) - attachment.add_header("Content-ID", f"<{cid}>") - except TypeError: - _LOGGER.warning( - "Attachment %s has an unknown MIME type. " - "Falling back to file", - atch_name, - ) - attachment = MIMEApplication(file_bytes, Name=atch_name) - attachment["Content-Disposition"] = ( - "attachment; " 'filename="%s"' % atch_name - ) - msg.attach(attachment) - except FileNotFoundError: - _LOGGER.warning("Attachment %s not found. Skipping", atch_name) + attachment = _attach_file(atch_name, cid) + if attachment: + msg.attach(attachment) body_html = MIMEText("".join(body_text), "html") msg_alt.attach(body_html) @@ -263,15 +269,9 @@ def _build_html_msg(text, html, images): alternative.attach(MIMEText(html, ATTR_HTML, _charset="utf-8")) msg.attach(alternative) - for atch_num, atch_name in enumerate(images): + for atch_name in images: name = os.path.basename(atch_name) - try: - with open(atch_name, "rb") as attachment_file: - attachment = MIMEImage(attachment_file.read(), filename=name) + attachment = _attach_file(atch_name, name) + if attachment: msg.attach(attachment) - attachment.add_header("Content-ID", f"<{name}>") - except FileNotFoundError: - _LOGGER.warning( - "Attachment %s [#%s] not found. Skipping", atch_name, atch_num - ) return msg