Skip to content

Instantly share code, notes, and snippets.

@iiie
Last active December 14, 2015 14:58
Show Gist options
  • Save iiie/5104266 to your computer and use it in GitHub Desktop.
Save iiie/5104266 to your computer and use it in GitHub Desktop.
Beginnings of a topic changing bot plugin for pycon and supybot.
from dateutil.parser import parse as date_parse
from datetime import datetime, timedelta
import json
import operator
import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
# these are the extra modules we'll be using
import supybot.ircmsgs as ircmsgs
import supybot.schedule as schedule
class TopicTracker(callbacks.Plugin):
def __init__(self, irc):
self.__parent = super(TopicTracker)
self.__parent.__init__(irc)
self.tracks = {}
self.channels = {}
self.json_url = "https://us.pycon.org/2013/schedule/conference.json"
"""
{'#channel': [(start, end, title),...],...}
"""
self.trackTime = 3300 # 55 minutes
self.warn_ahead = 300
try:
schedule.removeEvent('updateTopicTrackerEvent')
except KeyError:
pass
def updateEventCaller():
self.updateTrackerEvents(irc)
schedule.addPeriodicEvent(updateEventCaller, self.trackTime, 'updateTopicTrackerEvent')
self.irc = irc
def pulljson(self, irc):
# Get file
j = json.load(open(self.json_url))
now = datetime.now()
for session in j:
end = date_parse(session['end'])
if end < now:
continue
s = (date_parse(session['start']), end, session['name'], session['conf_url'])
if session['room'] in self.tracks:
self.tracks[session['room']].append(s)
else:
self.tracks[session['room']] = [s]
for room, sessions in tracks.items():
sorted(sessions, key=operator.itemgetter(0))
def updateTrackerEvents(self, irc):
nexttime = self.nextSessionChange()
now = datetime.now()
for room, sessions in self.tracks:
if not sessions:
self.updateTopic(irc, room)
continue
start, end, start2 = sessions[0][0], sessions[0][1], None
if len(sessions) > 1:
start2 = sessions[1][0]
if start + timedelta(days=2) > now:
self.updateTopic(irc, room, sessions[0])
continue
if start2 - end > timedelta(hours=8):
self.updateTopic(irc, room, sessions[0])
if start > now:
self.updateTopic(irc, room, None, sessions[0])
elif start < now and now < end:
self.updateTopic(irc, room, sessions[0], sessions[1])
if start > now and start - timedelta(seconds=self.warn_ahead) < now:
self.notifyRoom(irc, room, sessions[0])
elif start2 > now and start2 - timedelta(seconds=self.warn_ahead) < now:
self.notifyRoom(irc, room, sessions[1])
try:
schedule.rescheduleEvent('nextTrackerEvent', nexttime)
except Exception:
try:
schedule.removeEvent('nextTrackerEvent')
except KeyError:
pass
def updateTrackerEventCaller():
self.updateTrackerEvents(irc)
schedule.addEvent(updateTrackerEventCaller, nexttime, 'nextTrackerEvent')
def nextSessionChange(self):
nextsession = False
now = datetime.now()
for room, sessions in self.tracks:
self.tracks[room] = filter(lambda x:x[1] > now, sessions)
for room, sessions in self.tracks:
start, end = sessions[0][0], sessions[0][1]
if nextsession:
if start < now and now < end:
# session started but not ended
if nextsession > end:
nextsession = end
elif start > now:
# session not yet started
if nextsession > start:
nextsession = start
elif start > now:
nextsession = start
else:
nextsession = end
if nextsession < now:
# TODO: log
return deltatime(minutes=5)
return nextsession - now
"""
https://github.com/jamessan/Supybot/blob/master/src/schedule.py
https://github.com/codersquid/pycon2013/issues/24
http://gitorious.org/supybot/supybot/blobs/a8d2e35fb11440e845b0ab6b9f40abe9c23a49ea/docs/PLUGIN_TUTORIAL.rst
http://sourceforge.net/apps/mediawiki/gribble/index.php?title=Supybot.schedule
http://ubottu.com/supydocs/plugins/RSS.html
http://gitorious.org/supybot/supybot/blobs/40941e044acf5a79cc9d95f5bf49b742243fc410/plugins/RSS/plugin.py
http://ubottu.com/supydocs/plugins/Channel.html
"""
def notifyRoom(self, irc, channel, *sessions):
now = time.time()
# TODO: Make dates use datetime and use minutes or human readable.
irc.queueMsg(ircmsgs.privmsg(channel,
'{next} starting in {howlong}'.format(
next=next_session[2],
howlong=(next_session[0] - now)
)))
def updateTitle(self, irc, channel, current_session=None, next_session=None):
now = datetime.now()
if current_session and current_session[0] > now:
message = '/topic Next: {0} {1} at {3}'.format(
current_session[2], current_session[3], current_session[0])
elif current_session and next_session:
message = '/topic Now: {0} {1}, Next: {2} {3}'.format(
current_session[2], current_session[3],
next_session[2], next_session[3])
elif not current_session and not next_session:
message = '/topic PyCon 2013!'
else d
irc.queueMsg(ircmsgs.privmsg(channel, message))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment