#!/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)