Compare commits
No commits in common. "1ee34987ac3f881faad0b387f9e5e12764a97595" and "d46e3b933af2d8930f788ce5fff3cdc7d34b33e3" have entirely different histories.
1ee34987ac
...
d46e3b933a
|
@ -69,7 +69,7 @@
|
||||||
"commands": ["doupsland"]
|
"commands": ["doupsland"]
|
||||||
},
|
},
|
||||||
"gpt3": {
|
"gpt3": {
|
||||||
"openai_key": "",
|
"openai_key": ""
|
||||||
"join_lines": "; ",
|
"join_lines": "; ",
|
||||||
"computing_replies": ["Hmm…"]
|
"computing_replies": ["Hmm…"]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
import uuid
|
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from apscheduler.triggers.date import DateTrigger
|
from apscheduler.triggers.date import DateTrigger
|
||||||
|
@ -10,52 +9,13 @@ from edmond.plugin import Plugin
|
||||||
|
|
||||||
|
|
||||||
class ReminderPlugin(Plugin):
|
class ReminderPlugin(Plugin):
|
||||||
"""Reminders using an async scheduler.
|
"""Reminders using an async scheduler."""
|
||||||
|
|
||||||
Reminders can be set in a given amount of time or to a given hour. They are
|
|
||||||
kept between restarts.
|
|
||||||
"""
|
|
||||||
|
|
||||||
REQUIRED_CONFIGS = [
|
REQUIRED_CONFIGS = [
|
||||||
"commands", "at_word", "in_word", "day_letter", "hour_letter",
|
"commands", "at_word", "in_word", "day_letter", "hour_letter",
|
||||||
"minute_letter", "second_letter", "reminder_format", "done"
|
"minute_letter", "second_letter", "reminder_format", "done"
|
||||||
]
|
]
|
||||||
|
|
||||||
def on_join(self, event):
|
|
||||||
"""Reschedule undelivered reminders."""
|
|
||||||
nick = event.source.nick
|
|
||||||
if nick != self.bot.nick:
|
|
||||||
return
|
|
||||||
|
|
||||||
joined_channel = event.target
|
|
||||||
reminder_format = self.config["reminder_format"]
|
|
||||||
saved_reminders = self.get_storage_value("reminders", [])
|
|
||||||
self.set_storage_value("reminders", [])
|
|
||||||
|
|
||||||
for reminder in saved_reminders:
|
|
||||||
# Ignore reminders for other targets than this channel.
|
|
||||||
if reminder["target"] != joined_channel:
|
|
||||||
continue
|
|
||||||
|
|
||||||
when = datetime.datetime.fromisoformat(reminder["when"])
|
|
||||||
# If the timer passed, deliver it now and forget it.
|
|
||||||
if when <= datetime.datetime.now():
|
|
||||||
message = reminder_format.format(
|
|
||||||
username=reminder["sender"],
|
|
||||||
reminder=reminder["message"]
|
|
||||||
)
|
|
||||||
self.bot.say(reminder["target"], message)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Else schedule it properly (but skip storage backup, we're on it).
|
|
||||||
self.schedule(
|
|
||||||
when,
|
|
||||||
reminder["message"],
|
|
||||||
reminder["sender"],
|
|
||||||
reminder["target"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def on_pubmsg(self, event):
|
def on_pubmsg(self, event):
|
||||||
if not self.should_handle_command(event.arguments[0]):
|
if not self.should_handle_command(event.arguments[0]):
|
||||||
return False
|
return False
|
||||||
|
@ -83,6 +43,7 @@ class ReminderPlugin(Plugin):
|
||||||
reminder = " ".join(words[2:])
|
reminder = " ".join(words[2:])
|
||||||
self.setup_reminder(mode, time, reminder, sender, target)
|
self.setup_reminder(mode, time, reminder, sender, target)
|
||||||
return True
|
return True
|
||||||
|
# self.bot.scheduler.add_job(, 'cron', hour='1', minute='52')
|
||||||
|
|
||||||
def parse_time(self, time: str) -> Optional[dict[str, int]]:
|
def parse_time(self, time: str) -> Optional[dict[str, int]]:
|
||||||
"""Parse a time request string.
|
"""Parse a time request string.
|
||||||
|
@ -111,20 +72,11 @@ class ReminderPlugin(Plugin):
|
||||||
self,
|
self,
|
||||||
mode: str,
|
mode: str,
|
||||||
time: dict[str, int],
|
time: dict[str, int],
|
||||||
message: str,
|
reminder: str,
|
||||||
sender: str,
|
sender: str,
|
||||||
target: str
|
target: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Remind something at a given time.
|
"""Remind something at a given time."""
|
||||||
|
|
||||||
There are two possible modes, "at" for a given time and "in" for a
|
|
||||||
given delay. In both cases, it should result to a datetime in the
|
|
||||||
future, or it will be discarded.
|
|
||||||
|
|
||||||
Reminders are saved in the bot's storage to prevent losing reminders
|
|
||||||
between restarts. Only when a reminder is delivered it is removed from
|
|
||||||
the storage.
|
|
||||||
"""
|
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
if mode == self.config["at_word"]:
|
if mode == self.config["at_word"]:
|
||||||
if "day" in time: # "day" is not supported in at mode.
|
if "day" in time: # "day" is not supported in at mode.
|
||||||
|
@ -148,53 +100,15 @@ class ReminderPlugin(Plugin):
|
||||||
self.signal_failure(target)
|
self.signal_failure(target)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.schedule(when, message, sender, target)
|
|
||||||
self.bot.say(target, self.config["done"])
|
|
||||||
|
|
||||||
def schedule(
|
|
||||||
self,
|
|
||||||
when: datetime.datetime,
|
|
||||||
message: str,
|
|
||||||
sender: str,
|
|
||||||
target: str,
|
|
||||||
) -> None:
|
|
||||||
"""Schedule the reminder to be delivered at the given datetime."""
|
|
||||||
identifier = str(uuid.uuid4())
|
|
||||||
# Store the reminder in case the bot shuts down before delivery.
|
|
||||||
reminder = {
|
|
||||||
"id": identifier,
|
|
||||||
"when": when.isoformat(),
|
|
||||||
"message": message,
|
|
||||||
"sender": sender,
|
|
||||||
"target": target,
|
|
||||||
}
|
|
||||||
self.append_storage_list_value("reminders", reminder)
|
|
||||||
|
|
||||||
self.bot.scheduler.add_job(
|
self.bot.scheduler.add_job(
|
||||||
self.remind,
|
self.remind,
|
||||||
trigger=DateTrigger(when),
|
trigger=DateTrigger(when),
|
||||||
args=(identifier, message, sender, target)
|
args=(reminder, sender, target)
|
||||||
)
|
)
|
||||||
self.bot.log_d(f"Scheduled {identifier} for {when}.")
|
self.bot.log_d(f"Scheduled for {when}, time was {time}.")
|
||||||
|
self.bot.say(target, self.config["done"])
|
||||||
|
|
||||||
async def remind(
|
async def remind(self, reminder: str, username: str, target: str) -> None:
|
||||||
self,
|
|
||||||
identifier: str,
|
|
||||||
reminder: str,
|
|
||||||
username: str,
|
|
||||||
target: str
|
|
||||||
) -> None:
|
|
||||||
self.bot.log_d(
|
|
||||||
f"Delivering reminder {identifier} in {target} for {username}…"
|
|
||||||
)
|
|
||||||
reminder_format = self.config["reminder_format"]
|
reminder_format = self.config["reminder_format"]
|
||||||
message = reminder_format.format(username=username, reminder=reminder)
|
message = reminder_format.format(username=username, reminder=reminder)
|
||||||
self.bot.say(target, message)
|
self.bot.say(target, message)
|
||||||
|
|
||||||
# Remove the reminder from the saved reminder list.
|
|
||||||
saved_reminders = self.get_storage_value("reminders", [])
|
|
||||||
for reminder in saved_reminders.copy():
|
|
||||||
if reminder["id"] == identifier:
|
|
||||||
saved_reminders.remove(reminder)
|
|
||||||
break
|
|
||||||
self.set_storage_value("reminders", saved_reminders)
|
|
||||||
|
|
Loading…
Reference in a new issue