fulvia/modules/remind.py

154 lines
4.1 KiB
Python
Raw Normal View History

2018-03-16 03:13:43 -04:00
#!/usr/bin/env python3
"""
Reminds of things.
"""
import os
import re
2020-01-13 13:12:36 -05:00
from datetime import datetime, timedelta
2020-01-16 15:23:56 -05:00
from collections import defaultdict
2018-03-16 03:13:43 -04:00
2019-10-08 12:39:13 -04:00
import config
2020-01-13 13:12:36 -05:00
import module
2018-03-16 03:13:43 -04:00
2020-01-16 15:23:56 -05:00
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)
for remind in lazy_reminds:
bot.memory['lazy_remind'][remind[0]].append(remind[1:3])
2019-06-28 08:06:39 -04:00
regex = (
"(?=\d+[ywdhms])"
2020-01-13 13:12:36 -05:00
"(\d+y)?"
"(\d+w)?"
"(\d+d)?"
"(\d+h)?"
"(\d+m)?"
"(\d+s)?"
2019-06-28 08:06:39 -04:00
)
2020-01-13 13:12:36 -05:00
shorthand = {
'y': 'years',
'w': 'weeks',
'd': 'days',
'h': 'hours',
'm': 'minutes',
's': 'seconds',
}
@module.commands('remind')
@module.example('.remind 3h45m Go to class')
2018-03-16 03:13:43 -04:00
def remind(bot, trigger):
2020-01-16 15:23:56 -05:00
"""
Gives you a reminder in the given amount of time.
-l, --lazy - Only activates the reminder when you speak.
"""
2020-01-07 18:58:19 -05:00
if len(trigger.args) == 1:
2018-05-25 15:21:18 -04:00
return bot.msg("Missing arguments for reminder command.")
2020-01-16 15:23:56 -05:00
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
2018-03-16 03:13:43 -04:00
2020-01-13 13:12:36 -05:00
reg = re.search(regex, trigger.args[1])
if not reg:
return bot.reply("I didn't understand that.")
args = {shorthand[g[-1]]: int(g[:-1]) for g in reg.groups() if g}
2020-03-27 13:14:24 -04:00
if args.get('years'):
args['days'] = args['years']*365 + args.get('days', 0) # screw leap years
del args['years']
2020-01-13 13:12:36 -05:00
delta = timedelta(**args)
dt = datetime.now() + delta
reminder = ' '.join(trigger.args[2:])
2020-01-16 15:23:56 -05:00
if lazy:
bot.memory['lazy_remind'][trigger.nick].append((dt, reminder))
bot.db.execute("INSERT INTO lazy_remind VALUES(?,?,?)",
(trigger.nick, dt, reminder))
else:
args = (trigger.channel, trigger.nick, reminder)
bot.scheduler.add_task(announce_reminder, dt, args)
msg = "Okay, will "
msg += "\x0310lazy\x03 " if lazy else ""
msg += "remind at "
msg+= dt.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg)
2018-03-16 03:13:43 -04:00
2020-01-13 13:12:36 -05:00
@module.commands('at')
@module.example('.at 2012-12-21 18:00:00 End the world.')
2018-03-16 03:13:43 -04:00
def at(bot, trigger):
"""
2020-01-07 18:58:19 -05:00
Gives you a reminder at the given time and date. Datetime must be in
2020-01-13 13:12:36 -05:00
YYYY-MM-DD HH:MM:SS format. Only the bot's timezone is used. If
YYYY-MM-DD is excluded, it is assumed to be today's date.
2020-01-16 15:23:56 -05:00
-l, --lazy - Only activates the reminder when you speak.
2018-03-16 03:13:43 -04:00
"""
2020-01-13 13:12:36 -05:00
if len(trigger.args) < 2:
2020-01-07 18:58:19 -05:00
return bot.msg("Missing arguments for reminder command.")
2020-01-16 15:23:56 -05:00
if trigger.args[1] in ['-l', '--lazy']:
if len(trigger.args) < 3:
return bot.msg("Missing arguments for reminder command.")
lazy = True
trigger.args.pop(1)
else:
lazy = False
2020-01-13 13:12:36 -05:00
if ':' in trigger.args[1]:
at_time = datetime.now().strftime('%Y-%m-%d') + ' ' + trigger.args[1]
reminder = ' '.join(trigger.args[2:])
2018-03-16 03:13:43 -04:00
else:
2020-01-13 13:12:36 -05:00
at_time = ' '.join(trigger.args[1:3])
2020-01-08 07:51:00 -05:00
reminder = ' '.join(trigger.args[3:])
2018-03-16 03:13:43 -04:00
2020-01-07 18:58:19 -05:00
try:
2020-01-13 13:12:36 -05:00
dt = datetime.strptime(at_time, '%Y-%m-%d %H:%M:%S')
2020-01-07 18:58:19 -05:00
except ValueError:
return bot.msg("Datetime improperly formatted.")
2018-03-16 03:13:43 -04:00
2020-01-16 15:23:56 -05:00
if lazy:
bot.memory['lazy_remind'][trigger.nick].append((dt, reminder))
bot.db.execute("INSERT INTO lazy_remind VALUES(?,?,?)",
(trigger.nick, dt, reminder))
else:
args = (trigger.channel, trigger.nick, reminder)
bot.scheduler.add_task(announce_reminder, dt, args)
msg = "Okay, will "
msg += "\x0310lazy\x03 " if lazy else ""
msg += "remind at "
msg+= dt.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg)
2018-03-16 03:13:43 -04:00
2020-01-13 13:12:36 -05:00
def announce_reminder(bot, channel, remindee, reminder):
"""Announce the reminder."""
if reminder:
msg = f"{remindee}: {reminder}"
2018-03-16 03:13:43 -04:00
else:
2020-01-13 13:12:36 -05:00
msg = f"{remindee}!"
bot.msg(channel, msg)
2020-01-16 15:23:56 -05:00
@module.hook(True)
def lazy_remind(bot, trigger):
"""Lazy reminds only activate when the person speaks."""
if trigger.nick not in bot.memory['lazy_remind']:
return
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.db.execute("DELETE FROM lazy_remind "
"WHERE nick = ? AND datetime = ? AND reminder = ?",
(trigger.nick,) + tuple(remind))