From c41a6faab04bbf0cdb89e18299e88946557ddf99 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Thu, 18 Jun 2026 12:44:38 +0300 Subject: fix: help string and mail list mod command --- alfred/helpstrings.py | 3 +- alfred/mlmmj.py | 91 ++++++++++++++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/alfred/helpstrings.py b/alfred/helpstrings.py index 2abaa5f..009a42a 100644 --- a/alfred/helpstrings.py +++ b/alfred/helpstrings.py @@ -59,12 +59,13 @@ VPN = { "remove": "vpn remove: remove a peer live and from wg0.conf. usage: !vpn remove name", } -LIST_TOPIC = "list: members subscribe unsubscribe send. type !help list for details" +LIST_TOPIC = "list: members subscribe unsubscribe send mod. type !help list for details" LIST = { "members": "list members: show all subscribers. usage: !list members", "subscribe": "list subscribe: subscribe an address. usage: !list subscribe email", "unsubscribe": "list unsubscribe: unsubscribe an address. usage: !list unsubscribe email", "send": "list send: send a message to the list. usage: !list send message", + "mod": "list mod: list archive messages or remove one. usage: !list mod or !list mod rm N", } GIT_TOPIC = "git: list desc hook remove. type !help git for details" diff --git a/alfred/mlmmj.py b/alfred/mlmmj.py index bb5c162..c618adf 100644 --- a/alfred/mlmmj.py +++ b/alfred/mlmmj.py @@ -1,13 +1,17 @@ """ Sopel plugin: mlmmj mailing list management - !list subscribe - subscribe to list@gumx.cc - !list unsubscribe - unsubscribe - !list members - show all subscribers - !list send - send a message to the list as owner + !list subscribe - subscribe to list@gumx.cc + !list unsubscribe - unsubscribe + !list members - show all subscribers + !list send - send a message to the list as owner + !list mod - show recent archive messages + !list mod rm - remove message N from archive """ import email.utils, glob, os, subprocess, tempfile +import mailbox +from email.header import decode_header from sopel import plugin LIST_DIR = "/var/spool/mlmmj/list" @@ -95,54 +99,59 @@ def cmd_list(bot, trigger): elif action == "mod": sub = args[1].strip() if len(args) > 1 else "" - mod_dir = os.path.join(LIST_DIR, "moderation") + archive_dir = os.path.join(LIST_DIR, "archive") + + def _decode(s): + if not s: + return '' + parts = decode_header(s) + out = [] + for part, charset in parts: + if isinstance(part, bytes): + out.append(part.decode(charset or 'utf-8', errors='replace')) + else: + out.append(part) + return ''.join(out) if not sub or sub == "list": - if not os.path.isdir(mod_dir): - bot.say("mod: no moderation queue") - return - items = sorted(os.listdir(mod_dir)) + items = sorted( + f for f in os.listdir(archive_dir) + if os.path.isfile(os.path.join(archive_dir, f)) and not f.endswith('.html') + ) if not items: - bot.say("mod: queue empty") - else: - bot.say(f"mod: {len(items)} pending") - for name in items[:10]: - bot.say(f" {name}") - - elif sub == "approve": - if len(args) < 3: - bot.say("usage: !list mod approve ") + bot.say("archive: empty") return - fname = args[2].strip() - fpath = os.path.join(mod_dir, fname) - if not os.path.exists(fpath): - bot.say(f"mod: not found: {fname}") - return - r = subprocess.run( - ["mlmmj-moderate", "-L", LIST_DIR, "-m", fpath, "-a"], - capture_output=True, text=True - ) - bot.say("approved" if r.returncode == 0 - else f"error: {(r.stderr or r.stdout).strip()}") - - elif sub == "reject": + bot.say(f"archive: {len(items)} message(s)") + for fname in items[-10:]: + fpath = os.path.join(archive_dir, fname) + with open(fpath, 'rb') as f: + msg = mailbox.Message(f) + subject = _decode(msg.get('Subject', '(no subject)')) + sender = _decode(msg.get('From', '')) + name = sender.split('<')[0].strip().strip('"') or sender + bot.say(f" {fname} {subject[:40]} <{name}>") + + elif sub == "rm": if len(args) < 3: - bot.say("usage: !list mod reject ") + bot.say("usage: !list mod rm ") return fname = args[2].strip() - fpath = os.path.join(mod_dir, fname) - if not os.path.exists(fpath): - bot.say(f"mod: not found: {fname}") + fpath = os.path.join(archive_dir, fname) + if not os.path.isfile(fpath): + bot.say(f"mod rm: not found: {fname}") return - r = subprocess.run( - ["mlmmj-moderate", "-L", LIST_DIR, "-m", fpath, "-d"], - capture_output=True, text=True + os.remove(fpath) + html_path = fpath + '.html' + if os.path.isfile(html_path): + os.remove(html_path) + subprocess.Popen( + ["python3", "/home/ahmed/scripts/archive-gen.py", LIST_DIR], + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) - bot.say("rejected" if r.returncode == 0 - else f"error: {(r.stderr or r.stdout).strip()}") + bot.say(f"removed: {fname}") else: - bot.say("usage: !list mod [list|approve |reject ]") + bot.say("usage: !list mod [list|rm ]") else: bot.say("usage: !list ") -- cgit v1.2.3