diff options
| author | Ahmed <git@gumx.cc> | 2026-06-16 15:46:50 +0300 |
|---|---|---|
| committer | Ahmed <git@gumx.cc> | 2026-06-16 15:46:50 +0300 |
| commit | 2ec606411139edea79bbd7b98a0f9a22350fbaff (patch) | |
| tree | 69f75beed788c33df0350a423c69d0c446574107 /alfred | |
| parent | c227b93f43baa30ebb18ea2d08df3b486304cf16 (diff) | |
add: list moderation commands to alfred
Diffstat (limited to 'alfred')
| -rw-r--r-- | alfred/mlmmj.py | 75 |
1 files changed, 65 insertions, 10 deletions
diff --git a/alfred/mlmmj.py b/alfred/mlmmj.py index 5dfbfc3..b691a7c 100644 --- a/alfred/mlmmj.py +++ b/alfred/mlmmj.py @@ -1,18 +1,22 @@ """ Sopel plugin: mlmmj mailing list management - !list subscribe <email> - subscribe to list@gumx.cc - !list unsubscribe <email> - unsubscribe - !list members - show all subscribers - !list send <message> - send a message to the list as owner + !list subscribe <email> - subscribe (forced, no confirmation email) + !list unsubscribe <email> - unsubscribe + !list members - show all subscribers + !list send <message> - send a message to the list as owner (bypasses moderation) + !list mod - show pending moderation queue + !list approve <id> - approve a held post + !list discard <id> - discard a held post """ -import email.utils, glob, os, subprocess, tempfile +import email.utils, glob, mailbox, os, subprocess, tempfile from sopel import plugin LIST_DIR = "/var/spool/mlmmj/list" LIST_ADDR = "list@gumx.cc" OWNER_ADDR = "ahmed@gumx.cc" +MOD_DIR = os.path.join(LIST_DIR, "moderation") def _owner(bot, trigger): @@ -26,7 +30,7 @@ def cmd_list(bot, trigger): args = (trigger.group(2) or "").split(None, 1) if not args: - bot.say("usage: !list <subscribe|unsubscribe|members|send>") + bot.say("usage: !list <subscribe|unsubscribe|members|send|mod|approve|discard>") return action = args[0] @@ -37,7 +41,7 @@ def cmd_list(bot, trigger): return email_addr = args[1].strip() r = subprocess.run( - ["mlmmj-sub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], + ["/usr/bin/mlmmj-sub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], capture_output=True, text=True ) bot.say(f"subscribed: {email_addr}" if r.returncode == 0 @@ -49,7 +53,7 @@ def cmd_list(bot, trigger): return email_addr = args[1].strip() r = subprocess.run( - ["mlmmj-unsub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], + ["/usr/bin/mlmmj-unsub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], capture_output=True, text=True ) bot.say(f"unsubscribed: {email_addr}" if r.returncode == 0 @@ -85,7 +89,7 @@ def cmd_list(bot, trigger): tmpname = f.name try: r = subprocess.run( - ["mlmmj-send", "-L", LIST_DIR, "-l", "1", "-m", tmpname], + ["/usr/bin/mlmmj-send", "-L", LIST_DIR, "-l", "1", "-m", tmpname], capture_output=True, text=True ) bot.say("sent" if r.returncode == 0 @@ -93,5 +97,56 @@ def cmd_list(bot, trigger): finally: os.unlink(tmpname) + elif action == "mod": + files = sorted(os.listdir(MOD_DIR)) if os.path.isdir(MOD_DIR) else [] + if not files: + bot.say("moderation queue empty") + return + for fname in files[:5]: + fpath = os.path.join(MOD_DIR, fname) + try: + with open(fpath, "rb") as f: + msg = mailbox.Message(f) + subj = (msg.get("Subject", "(no subject)") or "")[:50] + frm = (msg.get("From", "") or "")[:30] + except Exception: + subj, frm = "(unreadable)", "" + bot.say(f"{fname} {subj} — {frm}") + if len(files) > 5: + bot.say(f"... and {len(files) - 5} more") + + elif action == "approve": + args2 = (trigger.group(2) or "").split(None, 2) + if len(args2) < 2: + bot.say("usage: !list approve <id>") + return + fid = args2[1].strip() + path = os.path.join(MOD_DIR, fid) + if not os.path.isfile(path): + bot.say(f"not found: {fid}") + return + r = subprocess.run( + ["/usr/bin/mlmmj-send", "-L", LIST_DIR, "-l", "1", "-m", path], + capture_output=True, text=True + ) + if r.returncode == 0: + os.unlink(path) + bot.say(f"approved: {fid}") + else: + bot.say(f"error: {(r.stderr or r.stdout).strip()}") + + elif action == "discard": + args2 = (trigger.group(2) or "").split(None, 2) + if len(args2) < 2: + bot.say("usage: !list discard <id>") + return + fid = args2[1].strip() + path = os.path.join(MOD_DIR, fid) + if not os.path.isfile(path): + bot.say(f"not found: {fid}") + return + os.unlink(path) + bot.say(f"discarded: {fid}") + else: - bot.say("usage: !list <subscribe|unsubscribe|members|send>") + bot.say("usage: !list <subscribe|unsubscribe|members|send|mod|approve|discard>") |
