Skip to content

Instantly share code, notes, and snippets.

@paralax
Created March 14, 2015 21:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paralax/866828717423caf09e70 to your computer and use it in GitHub Desktop.
Save paralax/866828717423caf09e70 to your computer and use it in GitHub Desktop.
reddit notification bot
#!/usr/bin/env python
'''RDFBot - an IRC relay of RDF headlines
Written by Andrew Gaul (http://gaul.org/). Tested with Python 2.3 and
python-irclib 0.3.4. This software has been placed into the public domain.
Issues:
* Slashdot's RDF feed sends malformed XML by appending NUL bytes to responses
occasionally. This causes RDFBot to not update until Slashdot returns valid
XML. This is a bug in Slash.
'''
__version__ = 2010110501
from ircbot import SingleServerIRCBot
import json
from threading import Thread
UPDATE_INTERVAL = 30 * 60
class Worker(Thread):
def __init__(self, connection, urls, channel):
Thread.__init__(self)
self.setDaemon(True)
self.connection = connection
self.headlines = {} # {rdf_url:{story_title:story_url}}
for url in urls:
self.headlines[url] = {}
self.channel = channel
def run(self):
import json
from time import sleep
from urllib import urlopen
import urllib
while True:
for source in self.headlines.keys():
try:
data = json.loads(urllib.urlopen(source).read())
new_headlines = {}
for item in data['data']['children']:
title = item['data']['title']
link = item['data']['url']
new_headlines[title] = link
if len(self.headlines[source]) > 0:
for title, url in new_headlines.iteritems():
if title not in self.headlines[source]:
print title
try: self.connection.notice(self.channel, """%s (%s)""" % (title, url))
except: pass
self.headlines[source] = new_headlines
except ValueError, e:
print 'Error:', source, e
except KeyError:
print 'Error: %s' % data['error']
sleep(UPDATE_INTERVAL)
class RDFBot(SingleServerIRCBot):
def __init__(self, channel, nickname, server, port, urls):
SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
self.authorized_channels = [channel]
self.worker = Worker(self.connection, urls, channel)
self.worker.start()
def on_welcome(self, c, e):
for channel in self.authorized_channels:
c.join(channel)
def get_version(self):
return 'RDFBot %s written by Andrew Gaul (http://gaul.org/)' % __version__
def main():
from sys import argv, exit
if len(argv) <= 3:
exit('Usage: %s SERVER[:PORT] CHANNEL NICKNAME' % argv[0])
s = argv[1].split(':', 1)
server = s[0]
if len(s) == 2:
try:
port = int(s[1])
except ValueError:
exit('Error: Invalid port')
else:
port = 6667
channel = "#" + argv[2]
nickname = argv[3]
f = open("feeds", "r")
feeds = map(lambda x: x.strip(), f.readlines())
f.close()
bot = RDFBot(channel, nickname, server, port, feeds)
bot.start()
if __name__ == '__mai
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment