"""
Irker protocol implementation.
"""
from twisted.internet import protocol, defer
from twisted.protocols import basic
from twisted.python import log
import json, urlparse
class Irk (basic.LineOnlyReceiver) :
"""
A connected Irk client.
"""
delimiter = '\n'
def connectionMade (self) :
self.transport.logPrefix = self.logPrefix
log.msg("connected", self)
def connectionLost (self, reason) :
log.err("connection lost", reason)
def error (self, *args) :
log.err(*args)
self.transport.loseConnection()
def lineReceived (self, line) :
"""
JSON -> in
"""
try :
irk = json.loads(line)
except ValueError as ex :
# invalid
return self.error(ex, line)
# dispatch
self.factory.irkReceived(irk).addErrback(self.error, line)
def __str__ (self) :
host = self.transport.getHost()
peer = self.transport.getPeer()
return "{host.host}:{host.port}:{peer.host}".format(host=host, peer=peer)
logPrefix = __str__
class IrkFactory (protocol.ServerFactory) :
"""
Manage connected Irk clients.
"""
protocol = Irk
def __init__ (self, irc) :
self.irc = irc
@defer.inlineCallbacks
def irkReceived (self, irk) :
"""
Deffered to handle lookup of target, and then sending message.
Errbacks on failures.
"""
log.msg(str(irk))
if not 'to' in irk :
raise ValueError("missing target: to")
# MUST NOT be unicode
# XXX: ValueError?
url = urlparse.urlparse(str(irk['to']))
# connect, join, etc.
target = yield self.irc.target(url)
# privmsg?
privmsg = irk.get('privmsg')
if privmsg :
# MUST be unicode
privmsg = unicode(privmsg)
# dispatch
target.privmsg(privmsg)