From 9c4e0fe782753cd1d364102f6dbe14f88937b213 Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Wed, 22 Feb 2017 22:07:39 -0600 Subject: [PATCH] countdown: receive reminder countdowns over IRC bss/dr.botzo#11 --- countdown/ircplugin.py | 66 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/countdown/ircplugin.py b/countdown/ircplugin.py index 8765f63..90c5091 100644 --- a/countdown/ircplugin.py +++ b/countdown/ircplugin.py @@ -1,16 +1,18 @@ """Access to countdown items through bot commands.""" import logging +import re import threading import time +import irc.client +import parsedatetime as pdt +from dateutil.parser import parse from dateutil.relativedelta import relativedelta - from django.utils import timezone -from ircbot.lib import Plugin from countdown.models import CountdownItem - +from ircbot.lib import Plugin, reply_destination_for_event log = logging.getLogger('countdown.ircplugin') @@ -18,6 +20,8 @@ log = logging.getLogger('countdown.ircplugin') class Countdown(Plugin): """Report on countdown items.""" + new_reminder_regex = r'remind\s+([^\s]+)\s+(at|in|on)\s+(.*)\s+(to|that)\s+(.*)' + def __init__(self, bot, connection, event): """Initialize some stuff.""" self.running_reminders = [] @@ -39,6 +43,10 @@ class Countdown(Plugin): self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!countdown\s+(\S+)$', self.handle_item_detail, -20) + # let this interrupt markov + self.connection.add_global_handler('pubmsg', self.handle_new_reminder, -50) + self.connection.add_global_handler('privmsg', self.handle_new_reminder, -50) + super(Countdown, self).start() def stop(self): @@ -49,6 +57,9 @@ class Countdown(Plugin): self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_item_list) self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_item_detail) + self.connection.remove_global_handler('pubmsg', self.handle_new_reminder) + self.connection.remove_global_handler('privmsg', self.handle_new_reminder) + super(Countdown, self).stop() def reminder_thread(self): @@ -66,6 +77,55 @@ class Countdown(Plugin): reminder.save() time.sleep(1) + def handle_new_reminder(self, connection, event): + """Watch IRC for requests to remind new things, create countdown items.""" + what = event.arguments[0] + my_nick = connection.get_nickname() + addressed_my_nick = r'^{0:s}[:,]\s+'.format(my_nick) + sender_nick = irc.client.NickMask(event.source).nick + sent_location = reply_destination_for_event(event) + + if re.search(addressed_my_nick, what, re.IGNORECASE) is not None: + # we were addressed, were we told to add a reminder? + trimmed_what = re.sub(addressed_my_nick, '', what) + log.debug(trimmed_what) + + match = re.match(self.new_reminder_regex, trimmed_what, re.IGNORECASE) + if match: + log.debug("%s is a new reminder request", trimmed_what) + who = match.group(1) + when_type = match.group(2) + when = match.group(3) + text = match.group(5) + log.debug("%s / %s / %s", who, when, text) + + item_name = '{0:s}-{1:s}'.format(sender_nick, timezone.now().strftime('%s')) + + # parse when to send the notification + if when_type == 'in': + # relative time + calendar = pdt.Calendar() + when_t = calendar.parseDT(when, timezone.localtime(timezone.now()), + tzinfo=timezone.get_current_timezone())[0] + else: + # absolute time + when_t = timezone.make_aware(parse(when)) + + # parse the person to address, if anyone, when sending the notification + if who == 'us' or who == sent_location: + message = text + elif who == 'me': + message = '{0:s}: {1:s}'.format(sender_nick, text) + else: + message = '{0:s}: {1:s}'.format(who, text) + log.debug("%s / %s / %s", item_name, when_t, message) + + countdown_item = CountdownItem.objects.create(name=item_name, at_time=when_t, is_reminder=True, + reminder_message=message, reminder_target=sent_location) + log.info("created countdown item %s", str(countdown_item)) + + return 'NO MORE' + def handle_item_detail(self, connection, event, match): """Provide the details of one countdown item.""" name = match.group(1)