#!/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: s = ' '.join(args.start) try: start = datetime.strptime(s,'%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.require_admin @module.commands('clear_dup_reminders') def remind_recur(bot, trigger): """ Clear out duplicate reminders from Fulvia's memory. This is only a temporary fix to the memory issue. """ bot.scheduler.tasks = list(dict.fromkeys(bot.scheduler.tasks)) bot.scheduler.dump_database() def announce_reminder(bot, sched_time, channel, remindee, reminder, delta=None): """Announce the reminder.""" bot.msg(channel, reminder) if delta: sched_time = sched_time + delta args = (channel, remindee, reminder, delta) bot.scheduler.add_task(announce_reminder, sched_time, args) def announce_lazy_reminder(bot, sched_time, remindee, reminder, delta=None): """Announce the reminder.""" bot.memory['lazy_remind'][remindee].append(reminder) if delta: sched_time = sched_time + 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)