#!/usr/bin/env python3 """ admin panel for faggot-chan. runs on the box that has the files, so there's nothing on discord to reach (not even with admin perms). the bot re-reads all of these on every message, no restart needed. admin.py list admin.py edit opens it in $EDITOR (vim if unset) admin.py block [note] admin.py unblock """ import json import os import shlex import subprocess import sys from pathlib import Path SCRIPT_DIR = Path(__file__).resolve().parent BOT_CONFIG = SCRIPT_DIR / "files" / "config" TARGETS = { "blocked": BOT_CONFIG / "blocked.txt", "prompt": BOT_CONFIG / "system_prompt.txt", "settings": BOT_CONFIG / "settings.json", "reactions": BOT_CONFIG / "reactions.json", "params": SCRIPT_DIR / "config" / "params.json", # main.py side, ollama options } def edit(name: str): path = TARGETS[name] path.parent.mkdir(parents=True, exist_ok=True) original = path.read_bytes() if path.exists() else None # to put back if the json ends up broken and they give up if original is None: path.write_text("{}\n" if path.suffix == ".json" else "", encoding="utf-8") editor = shlex.split(os.environ.get("EDITOR", "vim")) while True: subprocess.call([*editor, str(path)]) if path.suffix != ".json": return try: json.loads(path.read_text(encoding="utf-8")) return except json.JSONDecodeError as e: print(f"that's not valid json: {e}") if input("open it again? (y/n): ").strip().lower() in ("y", "yes"): continue if original is None: path.unlink() else: path.write_bytes(original) print("reverted") return def blocked_ids(lines: list[str]) -> set[str]: return {l.split("#")[0].strip() for l in lines if l.split("#")[0].strip()} def block(user_id: str, note: str = ""): path = TARGETS["blocked"] lines = path.read_text(encoding="utf-8").splitlines() if path.exists() else [] if user_id in blocked_ids(lines): print(f"{user_id} is already blocked") return lines.append(f"{user_id} # {note}" if note else user_id) path.parent.mkdir(parents=True, exist_ok=True) path.write_text("\n".join(lines) + "\n", encoding="utf-8") print(f"blocked {user_id}") def unblock(user_id: str): path = TARGETS["blocked"] lines = path.read_text(encoding="utf-8").splitlines() if path.exists() else [] kept = [l for l in lines if l.split("#")[0].strip() != user_id] if len(kept) == len(lines): print(f"{user_id} wasn't blocked") return path.write_text("\n".join(kept) + "\n", encoding="utf-8") print(f"unblocked {user_id}") def usage(): print(__doc__.strip()) sys.exit(1) def main(): args = sys.argv[1:] if not args: usage() cmd = args[0] if cmd == "list": for name, path in TARGETS.items(): print(f"{name:10} {path}{'' if path.exists() else ' (not made yet)'}") elif cmd == "edit" and len(args) == 2 and args[1] in TARGETS: edit(args[1]) elif cmd == "block" and len(args) >= 2 and args[1].isdigit(): block(args[1], " ".join(args[2:])) elif cmd == "unblock" and len(args) == 2 and args[1].isdigit(): unblock(args[1]) else: usage() if __name__ == "__main__": main()