mirror of git://git.psyced.org/git/pypsyc
71 lines
2.3 KiB
Python
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)
|