#!/usr/bin/env python """ update_topic.py - Keep topic in #spline up-to-date Copyright 2015, Alexander Sulfrian Licensed under the Eiffel Forum License 2. http://inamidst.com/phenny/ """ import asyncore import re import socket import threading from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta from calendar import TUESDAY CHANNEL = '#spline' FROMAT = 'http://pad.spline.de/treffen%y%m%d' REGEX = re.compile(r'.*(http://pad\.spline\.de/treffen[0-9]{6}).*') def setup(phenny): Scheduler(phenny) class Timer(object): def __init__(self, sock): self.sock = sock self.start() def start(self): sleep = seconds_until(get_next_meeting() + timedelta(days=1)) self.timer = threading.Timer(sleep, self.run) self.timer.start() def run(self): self.sock.send('.') self.start() def cancel(self): self.timer.cancel() class Scheduler(asyncore.dispatcher): def __init__(self, phenny): self.phenny = phenny self.phenny._orig_close = self.phenny.close self.phenny.close = (lambda: self._phenny_close()) recv_timer, send_timer = socket.socketpair() self.timer = Timer(send_timer) asyncore.dispatcher.__init__(self, recv_timer) def _phenny_close(self): self.close() self.phenny._orig_close() def close(self): self.timer.cancel() asyncore.dispatcher.close() def handle_read(self): data = self.recv(8192) if data: self._exec() else: self.close() def _exec(self): # get topic, topic update is handled if a topic is received self.phenny.write(['TOPIC'], CHANNEL) def seconds_until(when): today = datetime.today().date() return (when - today).total_seconds() def get_next_meeting(): today = datetime.today() return (today + relativedelta(months=+1, day=1, weekday=TUESDAY)).date() def update_topic(phenny, channel, topic): if channel != CHANNEL: return match = REGEX.match(topic) if match is None: return new_topic = topic.replace( match.groups()[0], get_next_meeting().strftime(FROMAT), 1) if new_topic != topic: print('Updating topic') phenny.msg('ChanServ', 'TOPIC %s %s' % (channel, new_topic)) def topic_change(phenny, input): update_topic(phenny, input.sender, input) topic_change.event = 'TOPIC' topic_change.rule = r'.*' def topic_reply(phenny, input): update_topic(phenny, input.args[1], input) topic_reply.event = '332' topic_reply.rule = r'.*' def request_topic(phenny, input): parts = input.split(None, 1) if len(parts) < 2: phenny.notice(input.nick, 'Usage: %s #channel' % parts[0]) else: phenny.write(['TOPIC'], parts[1]) phenny.notice(input.nick, 'Done.') request_topic.rule = r'^!(update|topic|update-topic)(?: +(.*))?$' request_topic.event = 'NOTICE'