mirror of git://git.psyced.org/git/pypsyc
160 lines
3.7 KiB
Python
Executable File
160 lines
3.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
## parse.py
|
|
|
|
|
|
# Licensed under the MIT license
|
|
# http://opensource.org/licenses/mit-license.php
|
|
|
|
# <C> Copyright 2007, Manuel Jacob
|
|
|
|
|
|
from packets import MMPPacket, PSYCPacket
|
|
|
|
def parse_vars(lines):
|
|
cvars = {}
|
|
pvars = {}
|
|
|
|
_list = None
|
|
|
|
for i in lines:
|
|
tmp = i.split('\t')
|
|
if tmp[0] == ':':
|
|
vars[_list].append(tmp[1])
|
|
continue
|
|
|
|
elif tmp[0].startswith(':'):
|
|
vars = cvars
|
|
|
|
elif tmp[0].startswith('='):
|
|
vars = pvars
|
|
|
|
if tmp[0][1:6] == '_list':
|
|
_list = tmp[0][1:]
|
|
vars[_list] = [tmp[1]]
|
|
|
|
else:
|
|
_list = None
|
|
vars[tmp[0][1:]] = tmp[1]
|
|
|
|
return cvars, pvars
|
|
|
|
|
|
class LineBased:
|
|
def __init__(self):
|
|
self.__buffer = ''
|
|
self.linemode = True
|
|
|
|
def data(self, data):
|
|
self.__buffer += data
|
|
while self.linemode and self.__buffer:
|
|
try:
|
|
line, self.__buffer = self.__buffer.split('\n', 1)
|
|
self.line(line)
|
|
except ValueError:
|
|
return
|
|
|
|
else:
|
|
if not self.linemode:
|
|
__buffer = self.__buffer
|
|
self.__buffer = ''
|
|
self.raw(__buffer)
|
|
|
|
|
|
class MMPParser(LineBased): # callback-based
|
|
pvars = {}
|
|
def __init__(self):
|
|
LineBased.__init__(self)
|
|
self.reset()
|
|
|
|
def reset(self):
|
|
self.mode = 'vars'
|
|
self.varlines = []
|
|
|
|
self.cvars = {}
|
|
self.body = ''
|
|
|
|
def line(self, line):
|
|
if line == '.':
|
|
self.recv()
|
|
elif self.mode == 'vars':
|
|
if line:
|
|
self.varlines.append(line)
|
|
else:
|
|
self.cvars, pvars = parse_vars(self.varlines)
|
|
|
|
for key, value in pvars.items():
|
|
if value:
|
|
self.pvars[key] = value
|
|
else:
|
|
if key in self.pvars:
|
|
del self.pvars[key]
|
|
|
|
self.mode = 'body'
|
|
|
|
else:
|
|
self.body += line + '\n'
|
|
|
|
def recv(self):
|
|
vars = self.pvars.copy()
|
|
vars.update(self.cvars)
|
|
if self.body and self.body[-1] == '\n':
|
|
self.body = self.body[:-1]
|
|
packet = MMPPacket(vars, self.body)
|
|
packet.not_to_render = True
|
|
self.recv_packet(packet)
|
|
self.reset()
|
|
|
|
def recv_packet(self, packet):
|
|
raise NotImplementedError
|
|
|
|
|
|
class PSYCParser:
|
|
pvars = {}
|
|
|
|
def parse(self, packet):
|
|
lines = packet.body.split('\n')
|
|
_is_text = False
|
|
cvars = {}
|
|
varlines = []
|
|
textlines = []
|
|
mc = ''
|
|
|
|
for i in lines:
|
|
if not i:
|
|
continue
|
|
|
|
tmp = i.split('\t')
|
|
|
|
if _is_text:
|
|
textlines.append(i)
|
|
|
|
elif i[0] in (':', '='):
|
|
varlines.append(i)
|
|
|
|
elif i[0] == '_':
|
|
cvars, pvars = parse_vars(varlines)
|
|
|
|
for key, value in pvars.items():
|
|
if value:
|
|
self.pvars[key] = value
|
|
else:
|
|
if key in self.pvars:
|
|
del self.pvars[key]
|
|
|
|
mc = i
|
|
_is_text = True
|
|
|
|
text = '\n'.join(textlines)
|
|
vars = self.pvars.copy()
|
|
vars.update(cvars)
|
|
packet = PSYCPacket(packet.mmpvars, vars, mc, text)
|
|
packet.not_to_render = True
|
|
return packet
|
|
|
|
|
|
if __name__ == '__main__':
|
|
MMPParser().data(':_context\ti\n=_foo\tbar\n\n_message_public\nHello\n.\n')
|
|
MMPParser().data(':_context\ti\n\n_message_public\nHello\n.\n')
|