pypsyc/fippos-twisted/pypsyc/PSYC.py

71 lines
2.3 KiB
Python

from pypsyc.State import State
from twisted.protocols.basic import LineReceiver
class PSYCProtocol(LineReceiver):
statemachine = None
state = 'vars'
mc = None
text = None
delimiter = '\n'
initialized = False
def connectionMade(self):
self.statemachine = State()
self.reset()
self.transport.write('.\n')
def msg(self, vars, mc, text):
"""serialize a packet and send to the other side
@type vars: C{dict}
@param vars: Dictionary of variables to be serialized.
Variables should be strings or lists, variable names start
with an underscore
@type mc: C{str}
@param mc: Methodname of the packet, starts with an underscore
@type text: C{str}
@param text: Data part of the packet"""
packet = self.statemachine.serialize(vars) # this has a newline already!
packet += mc + '\n'
packet += text + '\n'
packet += '.\n'
self.transport.write(packet.encode('iso-8859-1'))
def reset(self):
self.statemachine.reset()
self.state = 'vars'
self.mc = ''
self.text = ''
def lineReceived(self, line):
"""this does not yet handle binary mode and fragments"""
line = line.strip()
if self.initialized is False:
if line != '.':
self.msg({}, '_error_syntax_protocol_initialization',
'The protocol begins with a dot on a line of by itself')
self.transport.loseConnection()
return
else:
self.initialized = True
return
if line == '.':
self.packetReceived()
elif self.state is 'vars' and line.startswith('_'):
self.statemachine.eat(None)
self.mc = line
self.state = 'text'
elif self.state == 'vars':
self.statemachine.eat(line)
else:
self.text += line + '\n'
def packetReceived(self):
vars = self.statemachine.copy()
peer = self.transport.getPeer()
if not vars.has_key('_source'):
vars['_source'] = 'psyc://%s:-%d'%(peer.host, peer.port)
mc = self.mc[:]
data = self.text[:].strip().decode('iso-8859-1')
self.reset()
self.factory.packetReceived(vars, mc, data, self, peer)