pvl/irker/irk.py
author Tero Marttila <terom@paivola.fi>
Fri, 11 Jan 2013 17:13:11 +0200
changeset 81 448ed86d0510
child 83 1cb48f2ba1e9
permissions -rw-r--r--
pvl.irker: irker reimplementation in Twisted
"""
    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)