From 5a8d568931d9b23ce0df1265d05259a7012081c9 Mon Sep 17 00:00:00 2001 From: Ahmed Date: Sun, 14 Jun 2026 01:46:29 +0300 Subject: init: mostly vibed --- jeeves/quotes.py | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 jeeves/quotes.py (limited to 'jeeves/quotes.py') diff --git a/jeeves/quotes.py b/jeeves/quotes.py new file mode 100644 index 0000000..c840a6d --- /dev/null +++ b/jeeves/quotes.py @@ -0,0 +1,150 @@ +""" +Sopel plugin: jeeves quotes + +Maintains a shared quote bank with automatic periodic posting. + + !quote - post a random quote + !quote add - add a quote (op/owner) + !quote del - delete quote by index (op/owner) + !quote list - show total count + !quotes - show auto-post state for this channel + !quotes on|off - enable/disable auto-posting (op/owner) + +Auto-post interval is configured via: + !set quotes_interval - minutes between auto-posts (default 60) +""" + +import os as _os, sys as _sys +_d = _os.path.dirname(_os.path.abspath(__file__)) +if _d not in _sys.path: + _sys.path.insert(0, _d) +import jv_core as jv + +import random +import time + +from sopel import plugin + + +def setup(bot): + jv.ensure_setup(bot) + + +@plugin.command("quote") +def cmd_quote(bot, trigger): + args = (trigger.group(2) or "").strip().split(None, 1) + sub = args[0].lower() if args else "" + + if sub == "add": + if not jv.is_authorized(bot, trigger): + return + text = args[1].strip() if len(args) > 1 else "" + if not text: + bot.notice("usage: !quote add ", trigger.nick) + return + with bot.memory["jv_lock"]: + bot.memory["jv_db"].setdefault("quotes", []).append(text) + n = len(bot.memory["jv_db"]["quotes"]) + jv.save(bot) + bot.notice(f"quote #{n} added", trigger.nick) + return + + if sub == "del": + if not jv.is_authorized(bot, trigger): + return + if len(args) < 2: + bot.notice("usage: !quote del ", trigger.nick) + return + try: + idx = int(args[1]) - 1 + except ValueError: + bot.notice("usage: !quote del ", trigger.nick) + return + with bot.memory["jv_lock"]: + quotes = bot.memory["jv_db"].get("quotes", []) + if idx < 0 or idx >= len(quotes): + bot.notice(f"no quote #{idx + 1}", trigger.nick) + return + quotes.pop(idx) + jv.save(bot) + bot.notice(f"quote #{idx + 1} deleted", trigger.nick) + return + + if sub == "list": + quotes = bot.memory.get("jv_db", {}).get("quotes", []) + count = len(quotes) + dest = trigger.sender if str(trigger.sender).startswith("#") else trigger.nick + bot.say(f"{count} quote(s) in the bank", dest) + return + + quotes = bot.memory.get("jv_db", {}).get("quotes", []) + if not quotes: + dest = trigger.sender if str(trigger.sender).startswith("#") else trigger.nick + bot.say("no quotes in the bank yet", dest) + return + dest = trigger.sender if str(trigger.sender).startswith("#") else trigger.nick + bot.say(random.choice(quotes), dest) + + +@plugin.command("quotes") +def cmd_quotes(bot, trigger): + args = (trigger.group(2) or "").strip().split() + arg = args[0].lower() if args else "" + in_chan = str(trigger.sender).startswith("#") + channel = str(trigger.sender) if in_chan else None + + if arg in ("on", "off"): + if not jv.is_authorized(bot, trigger): + return + if not in_chan: + bot.notice("use !quotes on|off in a channel", trigger.nick) + return + with bot.memory["jv_lock"]: + jv.chan_db(bot, channel)["quotes"]["enabled"] = (arg == "on") + jv.save(bot) + bot.say(f"quote auto-post turned {arg} for {channel}", channel) + return + + if in_chan: + ch = jv.chan_db(bot, channel) + enabled = ch["quotes"]["enabled"] + last = ch["quotes"]["last_broadcast"] + interval = jv.cfg_val(bot, "quotes_interval", channel) + if last: + ago = int(time.time() - last) + last_str = f"{ago // 60}m ago" if ago >= 60 else f"{ago}s ago" + else: + last_str = "never" + state = "on" if enabled else "off" + count = len(bot.memory.get("jv_db", {}).get("quotes", [])) + bot.say( + f"quote auto-post: {state} | every {interval} min | {count} quote(s) | last: {last_str}", + channel, + ) + else: + bot.notice("usage: !quotes [on|off] (use in a channel)", trigger.nick) + + +@plugin.interval(60) +def _quotes_tick(bot): + if "jv_db" not in bot.memory: + return + now = time.time() + quotes = bot.memory["jv_db"].get("quotes", []) + if not quotes: + return + + for chan_name in list(bot.channels): + channel = str(chan_name) + ch = jv.chan_db(bot, channel) + if not ch["quotes"]["enabled"]: + continue + interval_sec = jv.cfg_val(bot, "quotes_interval", channel) * 60 + if now - ch["quotes"]["last_broadcast"] < interval_sec: + continue + + quote = random.choice(quotes) + with bot.memory["jv_lock"]: + jv.chan_db(bot, channel)["quotes"]["last_broadcast"] = now + jv.save(bot) + bot.say(quote, channel) -- cgit v1.2.3