Newer
Older
#!/usr/bin/env python
"""
irker - a simple IRC multiplexer daemon
Takes JSON objects of the form {'channel':<channel-url>, 'message':<text>}
and relays messages to IRC channels.
Run this as a daemon in order to maimntain stateful connections to IRC
servers; this will allow it to respond to server pings and minimize
join/leave traffic.
import os, sys, json, irclib, exceptions, getopt, urlparse
class SessionException(exceptions.Exception):
def __init__(self, message):
exceptions.Exception.__init__(self)
self.message = message
"IRC session and message queue processing."
self.queue = Queue.Queue()
self.thread = threading.Thread(target=self.dequeue)
self.thread.daemon = True
self.thread.start()
parsed = urlparse.urlparse(url)
host, sep, port = parsed.netloc.partition(':')
if not port:
port = 6667
self.servername = host
self.channel = parsed.path.lstrip('/')
self.port = int(port)
self.server = self.irker.irc.server()
self.irker.debug(1, "connecting: server=%s port=%s name=%s" % (self.servername, self.port, self.name()))
self.server.connect(self.servername, self.port, self.name())
def enqueue(self, message):
"Enque a message for transmission."
self.queue.put(message)
def dequeue(self):
"Try to ship pending messages from the queue."
while True:
message = self.queue.get()
self.ship(self.channel, message)
self.queue.task_done()
def name(self):
"Generate a unique name for this session."
"Block until processing of all queued messages is done."
self.queue.join()
def ship(self, channel, message):
"Ship a message to the channel."
self.irker.debug(1, "%s gets %s" % (channel, repr(message)))
self.server.join(channel)
self.server.privmsg(channel, message)
def __init__(self, debuglevel=0):
self.debuglevel = 0
thread = threading.Thread(target=self.irc.process_forever)
self.irc._thread = thread
thread.daemon = True
thread.start()
def logerr(self, errmsg):
"Log a processing error."
sys.stderr.write("irker: " + errmsg + "\n")
def debug(self, level, errmsg):
"Debugging information."
if level >= self.debuglevel:
sys.stderr.write("irker: " + errmsg + "\n")
"Accept JSON relay requests from specified stream."
while True:
inp = ifp.readline()
if not inp:
break
try:
request = json.loads(inp.strip())
except ValueError:
self.logerr("can't recognize JSON on input.")
if await:
for session in self.sessions.values():
session.await()
if "channel" not in request or "message" not in request:
self.logerr("ill-formed reqest")
else:
channel = request['channel']
message = request['message']
if channel not in self.sessions:
self.sessions[channel].enqueue(message)
debuglevel = 0
(options, arguments) = getopt.getopt(sys.argv[1:], "-d:")
for (opt, val) in options:
if opt == '-v':
debuglevel = int(val)
irker = Irker(debuglevel=debuglevel)