fixbot/api/legacy.py
author Tero Marttila <terom@fixme.fi>
Sat, 20 Feb 2010 23:06:43 +0200
changeset 64 8574aeff9b36
parent 62 e4db89a5f6bc
permissions -rw-r--r--
blind error handling tweaks
from twisted.internet import protocol
from twisted.python import log

from fixbot import buffer
from fixbot.module import ModuleInfo, Event


CLIENT_COMMANDS = [
    "module_init",
    "module_event",
]

SERVER_COMMANDS = [
    "module_ok",
]
       
class ServerProtocol (buffer.StreamProtocol, protocol.Protocol) :
    RECV_COMMANDS = CLIENT_COMMANDS
    SEND_COMMANDS = SERVER_COMMANDS    

    VALID_STATES = [
        "wait_init",
        "wait_event"
    ]
    
    # proto state
    state = None

    # module info
    module = None
    
    def _assert (self, condition, msg) :
        if not condition :
            self.transport.loseConnection()
            log.err("assert failed in APIProtocol for %s: %s" % (self.module, msg))
    
    def connectionMade (self) :
        log.msg("Client connected")

    def connectionLost (self, reason) :
        log.msg("Connection lost: %s" % reason)
        
        if self.module :
            self.factory.nexus.unregisterModule(self.module, reason.getErrorMessage())

    def on_module_init (self, i) :
        self._assert(not self.module, "module_init with non-None self.module")

        peer_secret = i.readVarLen('B')
        
        self._assert(peer_secret == self.factory.secret, "Mismatching API secrets!")

        m = ModuleInfo()
        
        m.name = i.readVarLen('B')
        m.addr = self.transport.getPeer()

        log.msg("Got mod_init for %r" % m)
        
        self.factory.nexus.registerModule(m, self)

        self.module = m

        o = self.startCommand('module_ok')

        self.send(o)

    def on_module_event (self, i) :
        self._assert(self.module, "module_event with None self.module!")

        event_type = i.readVarLen('B')
        event_msg = i.readVarLen('H')
        
        e = Event(self.module, event_type, event_msg)

        self.factory.nexus.handleEvent(e)

    def logPrefix (self) :
        if self.module :
            return str(self.module)
        else :
            return super(ServerProtocol, self).logPrefix()

class ClientProtocol (buffer.StreamProtocol, protocol.Protocol) :
    RECV_COMMANDS = SERVER_COMMANDS
    SEND_COMMANDS = CLIENT_COMMANDS

    def connectionMade (self) :
        log.msg("Connected to API server, sending module init message")

        o = self.startCommand('module_init')
        o.writeVarLen('B', self.factory.secret)
        o.writeVarLen('B', self.factory.name)

        self.send(o)

    def sendEvent (self, event) :
        o = self.startCommand('module_event')
        o.writeVarLen('B', event.type)
        o.writeVarLen('H', event.msg[:2**16])

        self.send(o)

    def on_module_ok (self, i) :
        log.msg("Registration OK")

        self.factory._onRegistered(self)
    
    def logPrefix (self) :
        return "module %s client" % (self.factory.name)