owenrusk.dev

errands

small jobs the runtime does for the studio.

git clone https://owenrusk.dev/errands.git

commit 80998294706659e50f33e515823dcdcda37924af
parent c708695ab10718280a5615c6df88a70c05a5be70
author Owen Rusk <owen@papermothgames.com>
date   2024-10-24 11:30:52 -0500
mail: text from multipart messages
errands/mail.py+9-2
tests/test_mail.py+9-0
diff --git a/errands/mail.py b/errands/mail.py
index 5cfbc6c..5050c01 100644
--- a/errands/mail.py
+++ b/errands/mail.py
@@ -25,15 +25,22 @@ def connect() -> imaplib.IMAP4:
     return box
 
 
+def text(msg) -> str:
+    for part in msg.walk():
+        if part.get_content_type() == "text/plain" and not part.get_filename():
+            payload = part.get_payload(decode=True) or b""
+            return payload.decode(part.get_content_charset() or "utf-8", "replace")
+    return ""
+
+
 def parse(uid: str, raw: bytes) -> Message:
     msg = email.message_from_bytes(raw)
-    payload = msg.get_payload(decode=True) or b""
     return Message(
         uid=uid,
         sender=parseaddr(msg.get("From", ""))[1].lower(),
         subject=msg.get("Subject", ""),
         message_id=msg.get("Message-ID", ""),
-        body=payload.decode(msg.get_content_charset() or "utf-8", "replace"),
+        body=text(msg),
     )
 
 
diff --git a/tests/test_mail.py b/tests/test_mail.py
index f1813f0..bde07b7 100644
--- a/tests/test_mail.py
+++ b/tests/test_mail.py
@@ -44,6 +44,15 @@ class UnreadTest(unittest.TestCase):
         self.assertEqual(got[0].body, "hello\n")
         self.assertTrue(box.closed)
 
+    def test_plain_text_from_multipart(self):
+        msg = EmailMessage()
+        msg["From"] = "someone@example.com"
+        msg["Subject"] = "screenshot"
+        msg.set_content("it's attached\n")
+        msg.add_alternative("<p>it's attached</p>", subtype="html")
+        msg.add_attachment(b"\x89PNG", maintype="image", subtype="png", filename="shot.png")
+        self.assertEqual(mail.parse("3", bytes(msg)).body, "it's attached\n")
+
     def test_nothing_unread(self):
         self.assertEqual(mail.unread(lambda: FakeBox({})), [])