refactor lazy remind, add recurring remind

This commit is contained in:
iou1name 2020-06-29 14:59:24 -04:00
parent eb3b2b746b
commit 9af77b99b6

View File

@ -7,18 +7,12 @@ import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
from collections import defaultdict from collections import defaultdict
import tools
import config import config
import module import module
def setup(bot): def setup(bot):
bot.db.execute("CREATE TABLE IF NOT EXISTS lazy_remind ("
"nick TEXT,"
"datetime TIMESTAMP,"
"reminder TEXT)")
lazy_reminds = bot.db.execute("SELECT * FROM lazy_remind").fetchall()
bot.memory['lazy_remind'] = defaultdict(list) bot.memory['lazy_remind'] = defaultdict(list)
for remind in lazy_reminds:
bot.memory['lazy_remind'][remind[0]].append(remind[1:3])
regex = ( regex = (
"(?=\d+[ywdhms])" "(?=\d+[ywdhms])"
@ -40,43 +34,68 @@ shorthand = {
@module.commands('remind') @module.commands('remind')
@module.example('.remind 3h45m Go to class') @module.example('.remind 3h45m Go to class')
def remind(bot, trigger): def remind_recur(bot, trigger):
""" """
Gives you a reminder in the given amount of time. Sets a recurring reminder.
-s, --start - Starts the cycle at the given point in time instead of now.
-l, --lazy - Only activates the reminder when you speak. -l, --lazy - Only activates the reminder when you speak.
-r, --recur - Repeats the reminder every given period.
""" """
if len(trigger.args) == 1: if len(trigger.args) < 2:
return bot.msg("Missing arguments for reminder command.") return bot.msg("Missing arguments.")
if trigger.args[1] in ['-l', '--lazy']:
if len(trigger.args) == 2:
return bot.msg("Missing arguments for reminder command.")
lazy = True
trigger.args.pop(1)
else:
lazy = False
reg = re.search(regex, trigger.args[1]) parser = tools.FulviaArgparse()
if not reg: parser.add_argument('period')
return bot.reply("I didn't understand that.") parser.add_argument('reminder', nargs='*')
args = {shorthand[g[-1]]: int(g[:-1]) for g in reg.groups() if g} parser.add_argument('-s', '--start')
if args.get('years'): parser.add_argument('-l', '--lazy', action='store_true')
args['days'] = args['years']*365 + args.get('days', 0) # screw leap years parser.add_argument('-r', '--recur', action='store_true')
del args['years'] try:
delta = timedelta(**args) args = parser.parse_args(trigger.args[1:])
dt = datetime.now() + delta except Exception as e:
reminder = ' '.join(trigger.args[2:]) return bot.reply(type(e).__name__ + ": " + str(e))
if lazy:
bot.memory['lazy_remind'][trigger.nick].append((dt, reminder)) if args.start:
bot.db.execute("INSERT INTO lazy_remind VALUES(?,?,?)", try:
(trigger.nick, dt, reminder)) start = datetime.strptime(args.start, '%Y-%m-%d %H:%M:%S')
except ValueError:
return bot.msg("Datetime improperly formatted.")
else: else:
args = (trigger.channel, trigger.nick, reminder) start = datetime.now()
bot.scheduler.add_task(announce_reminder, dt, args)
reg = re.search(regex, args.period)
if not reg:
return bot.reply("I didn't understand that time period.")
parts = {shorthand[g[-1]]: int(g[:-1]) for g in reg.groups() if g}
if parts.get('years'):
parts['days'] = parts['years']*365 + parts.get('days', 0) # screw leap years
del parts['years']
delta = timedelta(**parts)
sched_time = start + delta
reminder = ' '.join(args.reminder)
if reminder:
reminder = trigger.nick + ': ' + reminder
else:
reminder = trigger.nick + '!'
if args.recur:
recur = delta
else:
recur = None
if args.lazy:
sched_args = (trigger.nick, reminder, recur)
bot.scheduler.add_task(announce_lazy_reminder, sched_time, sched_args)
else:
sched_args = (trigger.channel, trigger.nick, reminder, recur)
bot.scheduler.add_task(announce_reminder, sched_time, sched_args)
msg = "Okay, will " msg = "Okay, will "
msg += "\x0310lazy\x03 " if lazy else "" msg += "\x0310lazy\x03 " if args.lazy else ""
msg += "remind at " msg += "remind at "
msg+= dt.strftime('[%Y-%m-%d %H:%M:%S]') msg+= sched_time.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg) bot.reply(msg)
@ -106,48 +125,50 @@ def at(bot, trigger):
at_time = ' '.join(trigger.args[1:3]) at_time = ' '.join(trigger.args[1:3])
reminder = ' '.join(trigger.args[3:]) reminder = ' '.join(trigger.args[3:])
if reminder:
reminder = trigger.nick + ': ' + reminder
else:
reminder = trigger.nick + '!'
try: try:
dt = datetime.strptime(at_time, '%Y-%m-%d %H:%M:%S') sched_time = datetime.strptime(at_time, '%Y-%m-%d %H:%M:%S')
except ValueError: except ValueError:
return bot.msg("Datetime improperly formatted.") return bot.msg("Datetime improperly formatted.")
if lazy: if lazy:
bot.memory['lazy_remind'][trigger.nick].append((dt, reminder)) sched_args = (trigger.nick, reminder)
bot.db.execute("INSERT INTO lazy_remind VALUES(?,?,?)", bot.scheduler.add_task(announce_lazy_reminder, sched_time, sched_args)
(trigger.nick, dt, reminder))
else: else:
args = (trigger.channel, trigger.nick, reminder) sched_args = (trigger.channel, trigger.nick, reminder)
bot.scheduler.add_task(announce_reminder, dt, args) bot.scheduler.add_task(announce_reminder, sched_time, sched_args)
msg = "Okay, will " msg = "Okay, will "
msg += "\x0310lazy\x03 " if lazy else "" msg += "\x0310lazy\x03 " if lazy else ""
msg += "remind at " msg += "remind at "
msg+= dt.strftime('[%Y-%m-%d %H:%M:%S]') msg+= sched_time.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg) bot.reply(msg)
def announce_reminder(bot, channel, remindee, reminder): def announce_reminder(bot, channel, remindee, reminder, delta=None):
"""Announce the reminder.""" """Announce the reminder."""
if reminder: bot.msg(channel, reminder)
msg = f"{remindee}: {reminder}" if delta:
else: sched_time = datetime.now() + delta
msg = f"{remindee}!" args = (channel, remindee, reminder, delta)
bot.msg(channel, msg) bot.scheduler.add_task(announce_reminder, sched_time, args)
def announce_lazy_reminder(bot, remindee, reminder, delta=None):
"""Announce the reminder."""
bot.memory['lazy_remind'][remindee].append(reminder)
if delta:
sched_time = datetime.now() + delta
args = (remindee, reminder, delta)
bot.scheduler.add_task(announce_lazy_reminder, sched_time, args)
@module.hook(True) @module.hook(True)
def lazy_remind(bot, trigger): def lazy_remind(bot, trigger):
"""Lazy reminds only activate when the person speaks.""" """Lazy reminds only activate when the person speaks."""
if trigger.nick not in bot.memory['lazy_remind']: for remind in bot.memory['lazy_remind'].get(trigger.nick, []):
return bot.msg(remind)
due = [r for r in bot.memory['lazy_remind'][trigger.nick] if r[0] <= datetime.now()]
if not due:
return
for remind in due:
if remind[1]:
bot.reply(remind[1])
else:
bot.msg(trigger.nick + '!')
bot.memory['lazy_remind'][trigger.nick].remove(remind) bot.memory['lazy_remind'][trigger.nick].remove(remind)
bot.db.execute("DELETE FROM lazy_remind "
"WHERE nick = ? AND datetime = ? AND reminder = ?",
(trigger.nick,) + tuple(remind))