owenrusk.dev

errands

small jobs the runtime does for the studio.

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

commit 8e13b9422f1cec6b15fb393ad78ce78c6f60998f
parent c52bac36a928e769b44250d3c2e0ff55fe9297ee
author Owen Rusk <owen@papermothgames.com>
date   2025-11-04 14:15:50 -0600
mail: decode encoded subjects
errands/mail.py+2-1
tests/test_mail.py+5-0
diff --git a/errands/mail.py b/errands/mail.py
index 4994635..3ea74c8 100644
--- a/errands/mail.py
+++ b/errands/mail.py
@@ -3,6 +3,7 @@ import email
 import imaplib
 import smtplib
 from dataclasses import dataclass
+from email.header import decode_header, make_header
 from email.message import EmailMessage
 from email.utils import formatdate, make_msgid, parseaddr
 
@@ -39,7 +40,7 @@ def parse(uid: str, raw: bytes) -> Message:
     return Message(
         uid=uid,
         sender=parseaddr(msg.get("From", ""))[1].lower(),
-        subject=msg.get("Subject", ""),
+        subject=str(make_header(decode_header(msg.get("Subject", "")))),
         message_id=msg.get("Message-ID", ""),
         references=msg.get("References", ""),
         body=text(msg),
diff --git a/tests/test_mail.py b/tests/test_mail.py
index e7f4021..10f84c7 100644
--- a/tests/test_mail.py
+++ b/tests/test_mail.py
@@ -53,6 +53,11 @@ class UnreadTest(unittest.TestCase):
         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_encoded_subject(self):
+        message = mail.parse("4", raw(subject="caf\u00e9 hours"))
+        self.assertEqual(message.subject, "caf\u00e9 hours")
+        self.assertIn(b"=?utf-8?", raw(subject="caf\u00e9 hours"))
+
     def test_skips_our_own(self):
         box = FakeBox({b"1": raw(sender="Paper Moth Games <support@papermothgames.com>"), b"2": raw()})
         self.assertEqual([m.uid for m in mail.unread(lambda: box)], ["2"])