aboutsummaryrefslogtreecommitdiffstats
path: root/jeeves/quotes.py
blob: c840a6db0c150f01fe67bbad6799c30de866480c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
"""
Sopel plugin: jeeves quotes

Maintains a shared quote bank with automatic periodic posting.

  !quote              - post a random quote
  !quote add <text>   - add a quote (op/owner)
  !quote del <N>      - 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 <min>   - 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 <text>", 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 <N>", trigger.nick)
            return
        try:
            idx = int(args[1]) - 1
        except ValueError:
            bot.notice("usage: !quote del <N>", 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)