fulvia/modules/remind.py

175 lines
4.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Reminds of things.
"""
import os
import re
from datetime import datetime, timedelta
from collections import defaultdict
import tools
import config
import module
def setup(bot):
bot.memory['lazy_remind'] = defaultdict(list)
regex = (
"(?=\d+[ywdhms])"
"(\d+y)?"
"(\d+w)?"
"(\d+d)?"
"(\d+h)?"
"(\d+m)?"
"(\d+s)?"
)
shorthand = {
'y': 'years',
'w': 'weeks',
'd': 'days',
'h': 'hours',
'm': 'minutes',
's': 'seconds',
}
@module.commands('remind')
@module.example('.remind 3h45m Go to class')
def remind_recur(bot, trigger):
"""
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.
-r, --recur - Repeats the reminder every given period.
"""
if len(trigger.args) < 2:
return bot.msg("Missing arguments.")
parser = tools.FulviaArgparse()
parser.add_argument('period')
parser.add_argument('reminder', nargs='*')
parser.add_argument('-s', '--start', nargs=2)
parser.add_argument('-l', '--lazy', action='store_true')
parser.add_argument('-r', '--recur', action='store_true')
try:
args = parser.parse_args(trigger.args[1:])
except Exception as e:
return bot.reply(type(e).__name__ + ": " + str(e))
if args.start:
try:
start = datetime.strptime(' '.join(args.start),'%Y-%m-%d %H:%M:%S')
except ValueError:
return bot.msg("Datetime improperly formatted.")
else:
start = datetime.now()
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 += "\x0310lazy\x03 " if args.lazy else ""
msg += "remind at "
msg+= sched_time.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg)
@module.commands('at')
@module.example('.at 2012-12-21 18:00:00 End the world.')
def at(bot, trigger):
"""
Gives you a reminder at the given time and date. Datetime must be in
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.
-l, --lazy - Only activates the reminder when you speak.
"""
if len(trigger.args) < 2:
return bot.msg("Missing arguments for reminder command.")
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
if ':' in trigger.args[1]:
at_time = datetime.now().strftime('%Y-%m-%d') + ' ' + trigger.args[1]
reminder = ' '.join(trigger.args[2:])
else:
at_time = ' '.join(trigger.args[1:3])
reminder = ' '.join(trigger.args[3:])
if reminder:
reminder = trigger.nick + ': ' + reminder
else:
reminder = trigger.nick + '!'
try:
sched_time = datetime.strptime(at_time, '%Y-%m-%d %H:%M:%S')
except ValueError:
return bot.msg("Datetime improperly formatted.")
if lazy:
sched_args = (trigger.nick, reminder)
bot.scheduler.add_task(announce_lazy_reminder, sched_time, sched_args)
else:
sched_args = (trigger.channel, trigger.nick, reminder)
bot.scheduler.add_task(announce_reminder, sched_time, sched_args)
msg = "Okay, will "
msg += "\x0310lazy\x03 " if lazy else ""
msg += "remind at "
msg+= sched_time.strftime('[%Y-%m-%d %H:%M:%S]')
bot.reply(msg)
def announce_reminder(bot, channel, remindee, reminder, delta=None):
"""Announce the reminder."""
bot.msg(channel, reminder)
if delta:
sched_time = datetime.now() + delta
args = (channel, remindee, reminder, delta)
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)
def lazy_remind(bot, trigger):
"""Lazy reminds only activate when the person speaks."""
for remind in list(bot.memory['lazy_remind'].get(trigger.nick, [])):
bot.msg(remind)
bot.memory['lazy_remind'][trigger.nick].remove(remind)