From 4a5699a4c90f50ae0d88bae542640209417445b5 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sun, 8 Dec 2024 16:52:05 +0100
Subject: [PATCH] =?UTF-8?q?Mail:=20Prvn=C3=AD=20kousky=20skriptu=20na=20zp?=
 =?UTF-8?q?racov=C3=A1n=C3=AD=20DSN?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 bin/process-dsn | 70 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100755 bin/process-dsn

diff --git a/bin/process-dsn b/bin/process-dsn
new file mode 100755
index 00000000..3b09a7e9
--- /dev/null
+++ b/bin/process-dsn
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+
+# XXX: Work in progress :XXX
+
+import email.message
+import email.parser
+import email.policy
+import sys
+
+# import mo.db as db
+# import mo.email
+# import mo.users
+import mo.util
+
+mo.util.init_standalone()
+
+
+class DSN:
+    msg: email.message.EmailMessage
+    message_id: str
+    parse_status: str
+    dsn_action: str
+    dsn_status: str
+
+    def __init__(self):
+        parser = email.parser.Parser(policy=email.policy.default)
+        self.msg = parser.parse(sys.stdin)
+        self.message_id = (self.msg['Message-Id'] or '?').strip()
+        self.dsn_action = '?'
+        self.dsn_status = '?'
+        self.parse_status = self.parse_dsn()
+
+    def parse_dsn(self) -> str:
+        if self.msg.get_content_type() != 'multipart/report':
+            return 'unexpected content-type'
+
+        if not self.msg.is_multipart():
+            return 'not multipart'
+
+        report_type = self.msg['Content-type'].params.get('report-type', '?')
+        if report_type != 'delivery-status':
+            return 'unknown report-type'
+
+        if len(self.msg.get_payload()) < 2:
+            return 'too few parts'
+
+        part2 = self.msg.get_payload(1)
+        if part2.get_content_type() != 'message/delivery-status':
+            return 'unexpected part 2 type'
+
+        dsn = part2.get_payload()
+        if len(dsn) < 2:
+            return 'DSN too short'
+
+        # main = dsn[0]
+
+        per_addr = dsn[1]
+        self.dsn_action = per_addr['Action']
+        self.dsn_status = per_addr['Status']
+
+        if self.dsn_action != 'failed':
+            return 'not failed'
+
+        print(self.msg.get_payload(2).get_content_type())
+
+        return 'ok'
+
+
+dsn = DSN()
+print(f'DSN: {dsn.message_id} {dsn.parse_status} {dsn.dsn_action} {dsn.dsn_status}')
-- 
GitLab