#!/usr/bin/python
import MySQLdb
import string
import types
import SocketServer
import sys
import _mysql
class InputString:
def __init__(self, str, pos):
self.pos = pos
self.str = str
def current(self):
return self.str[self.pos]
def forwards(self):
self.pos = self.pos + 1
def backwards(self):
self.pos = self.pos + 1
def eos(self):
return self.pos >= len(self.str)
class LPCRequest(SocketServer.StreamRequestHandler):
def handle(self):
#
# Ok, I think what we do here is read the stream for a while...
#
while 1:
fluff = self.rfile.readline()
if len(fluff) > 5:
fluff = python_fromlpc(fluff)
try:
bing = doquery(self.server.connection, fluff[3], fluff[1], fluff[2], fluff[4])
results = bing.fetchall()
self.wfile.write(makelpcstring_type([fluff[0], 0, results]))
bing.close()
except IOError, (errno, strerror):
self.wfile.write(makelpcstring_type([fluff[0], 1, "I/O error(%s): %s" % (errno, strerror)]))
#except SocketServer.ProgrammingError:
# print "Programming Error."
#self.wfile.write(makelpcstring_type([fluff[0], 1, "Programming error: "]))
#self.wfile.write(makelpcstring_type([fluff[0], 1, "Programming error: " + detail]))
except TypeError:
self.wfile.write(makelpcstring_type([fluff[0], 2, "Type error."]))
except _mysql.OperationalError, (errno, details):
self.wfile.write(makelpcstring_type([fluff[0], errno, details]))
except:
self.wfile.write(makelpcstring_type([fluff[0], 1, "Another error." + str(sys.exc_info()[0])]))
class LPCServer(SocketServer.TCPServer):
def __init__(self, addr, type, conn):
SocketServer.TCPServer.__init__(self, addr, type)
self.connection = conn
class CurrentConnection:
db = 'errors'
user = 'atuin'
passwd = ''
connection = MySQLdb.connect(host='127.0.0.1', user='atuin', db='errors', port=3306, passwd='')
def connectTo(connect, db, user, passwd=''):
if connect.db != db or connect.user != user or connect.passwd != passwd:
connect.connection.close()
connect.connection = MySQLdb.connect(host='127.0.0.1', user=user, db=db, port=3306, passwd=passwd)
connect.passwd = passwd
connect.user = user
connect.db = db
def doquery(conn, db, user, passwd, query):
connectTo(conn, db, user, passwd)
fluff = MySQLdb.DictCursor(conn.connection)
fluff.execute(query)
return fluff
def makelpcstring_float(bing):
return fpformat.sci(bing, 10)
def makelpcstring_int(bing):
return str(bing)
def makelpcstring_string(bing):
bing = string.replace(bing, '\r\n', '\r')
return '"' + string.replace(bing, '"', '\\"') + '"'
def makelpcstring_dict(bing):
ret = '(['
for kw in bing.keys():
ret = ret + makelpcstring_type(kw)
ret = ret + ':'
ret = ret + makelpcstring_type(bing[kw])
ret = ret + ','
ret = ret + '])'
return ret;
def makelpcstring_type(row):
if type(row) is types.IntType or type(row) is types.LongType:
ret = makelpcstring_int(row)
elif type(row) is types.FloatType:
ret = makelpcstring_float(row)
elif type(row) is types.StringType:
ret = makelpcstring_string(row)
elif type(row) is types.ListType:
ret = makelpcstring_array(row)
elif type(row) is types.DictType:
ret = makelpcstring_dict(row)
else:
ret = '"broken"'
print 'Broken type', type(row), types.IntType,
return ret
def makelpcstring_array(arr):
ret = '({'
for row in arr:
ret = ret + makelpcstring_type(row)
ret = ret + ','
ret = ret + '})'
return ret;
def python_fromlpc(input):
"Changes the input string into a real python type."
fluff = InputString(input, 0)
return python_fromlpctype(fluff)
def pythonnum_fromlpc(input):
start = input.pos
input.forwards()
while not input.eos() and input.current() >= '0' and input.current() <= '9' or input.current() == '.':
input.forwards()
input.backwards()
return string.atoi(input.str[start:input.pos - 1])
def pythonstring_fromlpc(input):
start = input.pos
skip = 0
while not input.eos() and (input.current() != '"' or skip):
if input.current() == '\\':
skip = 1
else:
skip = 0
input.forwards()
ret = input.str[start:input.pos]
ret = string.replace(ret, '\\n', '\n')
ret = string.replace(ret, '\\"', '"')
input.forwards()
return ret
def pythonlist_fromlpc(input):
ret = []
while input.current() != '}':
ret.append(python_fromlpctype(input))
if input.current() == ',':
input.forwards()
if input.current() == '}':
input.forwards()
input.forwards()
return ret
def pythondict_fromlpc(input):
ret = {}
while input.current() != ']':
key = python_fromlpctype(input)
if input.current() == ':':
input.forwards()
ret[key] = python_fromlpctype(input)
if input.current() == ',':
input.forwards()
if input.current() == ']':
input.forwards()
input.forwards()
return ret
def python_fromlpctype(input):
if (input.current() >= '0' and input.current() <= '9') or input.current() == '-':
return pythonnum_fromlpc(input)
elif input.current() == '(':
input.forwards()
if input.current() == '[':
input.forwards()
return pythondict_fromlpc(input)
elif input.current() == '{':
input.forwards()
return pythonlist_fromlpc(input)
elif input.current() == '\"':
input.forwards()
return pythonstring_fromlpc(input)
return None
#result = doquery('errors', 'atuin', '', 'select * from comments where commenter=\'pinkfish\'');
#fluff = makelpcstring_array(result.fetchall())
#print python_fromlpc(fluff)
#
# Now we go into a loop waiting for someone to say something
#
while 1:
fluff = LPCServer(('localhost',7865), LPCRequest, CurrentConnection())
fluff.serve_forever()