1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#!/usr/bin/env python
"""
update_topic.py - Keep topic in #spline up-to-date
Copyright 2015, Alexander Sulfrian <alex@spline.inf.fu-berlin.de>
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://padlite.spline.de/p/treffen%y%m%d'
REGEX = re.compile(r'.*(http://padlite\.spline\.de/p/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(self)
def writable(self):
return False
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'
|