diff options
Diffstat (limited to 'alfred/mlmmj.py')
| -rw-r--r-- | alfred/mlmmj.py | 122 |
1 files changed, 59 insertions, 63 deletions
diff --git a/alfred/mlmmj.py b/alfred/mlmmj.py index b691a7c..bb5c162 100644 --- a/alfred/mlmmj.py +++ b/alfred/mlmmj.py @@ -1,22 +1,18 @@ """ Sopel plugin: mlmmj mailing list management - !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 + !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 """ -import email.utils, glob, mailbox, os, subprocess, tempfile +import email.utils, glob, 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): @@ -28,9 +24,9 @@ def cmd_list(bot, trigger): if not _owner(bot, trigger): return - args = (trigger.group(2) or "").split(None, 1) + args = (trigger.group(2) or "").split(None, 2) if not args: - bot.say("usage: !list <subscribe|unsubscribe|members|send|mod|approve|discard>") + bot.say("usage: !list <subscribe|unsubscribe|members|send|mod>") return action = args[0] @@ -41,7 +37,7 @@ def cmd_list(bot, trigger): return email_addr = args[1].strip() r = subprocess.run( - ["/usr/bin/mlmmj-sub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], + ["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 @@ -53,7 +49,7 @@ def cmd_list(bot, trigger): return email_addr = args[1].strip() r = subprocess.run( - ["/usr/bin/mlmmj-unsub", "-L", LIST_DIR, "-a", email_addr, "-s", "-f"], + ["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 @@ -89,7 +85,7 @@ def cmd_list(bot, trigger): tmpname = f.name try: r = subprocess.run( - ["/usr/bin/mlmmj-send", "-L", LIST_DIR, "-l", "1", "-m", tmpname], + ["mlmmj-send", "-L", LIST_DIR, "-m", tmpname], capture_output=True, text=True ) bot.say("sent" if r.returncode == 0 @@ -98,55 +94,55 @@ def cmd_list(bot, trigger): 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()}") + sub = args[1].strip() if len(args) > 1 else "" + mod_dir = os.path.join(LIST_DIR, "moderation") + + 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)) + 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 <filename>") + 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 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}") + elif sub == "reject": + if len(args) < 3: + bot.say("usage: !list mod reject <filename>") + 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, "-d"], + capture_output=True, text=True + ) + bot.say("rejected" if r.returncode == 0 + else f"error: {(r.stderr or r.stdout).strip()}") + + else: + bot.say("usage: !list mod [list|approve <file>|reject <file>]") else: - bot.say("usage: !list <subscribe|unsubscribe|members|send|mod|approve|discard>") + bot.say("usage: !list <subscribe|unsubscribe|members|send|mod>") |
