summaryrefslogtreecommitdiff
path: root/server/piztor_server.py
diff options
context:
space:
mode:
authorTeddy <[email protected]>2013-08-25 17:55:34 +0800
committerTeddy <[email protected]>2013-08-25 17:55:34 +0800
commitf4d0989ae888bc2f83f0bc09cc826f7c79b1b6b5 (patch)
tree79c9fbb49a5a857c56843cef01b032e3430aa085 /server/piztor_server.py
parentf74999631c4f83a0c8532d6b7adb348dcd5d5205 (diff)
parent0a76dad753ed88a7575c2aafdd068ef6caa7247f (diff)
Merge branch 'master' of github.com:Determinant/piztor
Diffstat (limited to 'server/piztor_server.py')
-rw-r--r--server/piztor_server.py234
1 files changed, 0 insertions, 234 deletions
diff --git a/server/piztor_server.py b/server/piztor_server.py
deleted file mode 100644
index 81805b3..0000000
--- a/server/piztor_server.py
+++ /dev/null
@@ -1,234 +0,0 @@
-import sqlalchemy
-import SocketServer, socket, select
-import struct
-import os
-
-from sqlalchemy import create_engine
-from sqlalchemy import Column, Integer, String, Float
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import sessionmaker
-from random import randint
-
-engine = create_engine('sqlite:///t.sqlite', echo = False)
-Base = declarative_base()
-Session = sessionmaker(bind=engine)
-
-def get_hex(data):
- return "".join([hex(ord(c))[2:].zfill(2) for c in data])
-
-class PiztorError(Exception):
- def __init__(self, msg):
- self.err_msg = msg
- def __str__(self, msg):
- return self.err_msg
-
-class ConnectionError(PiztorError):
- pass
-
-class ReqReadError(ConnectionError):
- def __init__(self):
- super(ReqReadError, self).__init__("Error while reading request")
-
-class ReqInvalidError(ConnectionError):
- def __init__(self):
- super(ReqInvalidError, self).__init__("Invalid request")
-
-class TokenInvalidError(ConnectionError):
- def __init__(self):
- super(TokenInvalidError, self).__init__("Invalid token")
-
-class DataManager(object):
- def __init__(self, piz_srv):
- self.piz_srv = piz_srv
-
-class UserManager(DataManager):
-
- class User(Base):
- __tablename__ = 'users'
- id = Column(Integer, primary_key = True)
- gid = Column(Integer)
- username = Column(String)
- password = Column(String)
- token = Column(Integer)
-
- def get_user_by_token(self, token):
- session = Session()
- User = UserManager.User
- entries = session.query(User).filter(User.token == token).all()
- if len(entries) == 0:
- raise TokenInvalidError()
- return entries[0]
-
- def authentication_handle(self, opt_type, data):
- print "Parsing User Data"
- pos = -1
- for i in xrange(0, len(data)):
- if data[i] == '\0':
- print i
- if pos != -1:
- raise ReqInvalidError()
- pos = i
- break
- if pos == -1:
- raise ReqInvalidError()
- username = data[0:pos]
- password = data[pos + 1:]
-
- print "Trying to login with following info:"
- print (username, password)
-
- session = Session()
- entries = session.query(UserManager.User). \
- filter(UserManager.User.username == username).all()
- if len(entries) == 0:
- return struct.pack("!BLB", 0, 0, 1)
- entry = entries[0]
- if entry.password != password: # Auth failed
- print "Login failed!"
- return struct.pack("!BLB", 0, 0, 1)
- else: # Succeeded
- print "Logged in sucessfully!"
- entry.token = randint(0, 2147483647)
- session.commit()
- return struct.pack("!BLB", 0, entry.token, 0)
-
-
-class MesgManager(DataManager):
- def mesg_sending_handle(self, opt_type, data):
- print "Parsing Mesg Data"
- try:
- if len(data) < 8:
- raise ReqInvalidError()
- sender_token, recv_id = struct.unpack("!LL", data[:8])
- msg = data[8:]
- print (sender_token, recv_id, msg)
- return struct.pack("!B", 1)
- except struct.error:
- raise ReqInvalidError()
-
-class LocationManager(DataManager):
-
- class LocationInfo(Base):
- __tablename__ = "location_info"
- uid = Column(Integer, primary_key = True)
- lat = Column(Float(precesion = 64))
- lng = Column(Float(precesion = 64))
- # More: last_update
-
- def location_update_handle(self, opt_type, data):
- print "Parsing a Location Update"
- try:
- if len(data) < 8:
- raise ReqInvalidError()
- sender_token, lat, lng = struct.unpack("!Ldd", data)
- print "Updating location data with following info:"
- print (sender_token, lat, lng)
-
- user = self.piz_srv. \
- user_mgr.get_user_by_token(sender_token)
- session = Session()
- LInfo = LocationManager.LocationInfo
- q = session.query(LInfo).filter(LInfo.uid == user.id)
- entry = q.first()
- entry.lat = lat
- entry.lng = lng
- session.commit()
- print "Location update succeeded!"
- return struct.pack("!BB", 2, 0)
- except TokenInvalidError:
- print "Location update failed!"
- return struct.pack("!BB", 2, 1)
- except struct.error:
- raise ReqInvalidError()
-
- def location_request_handle(self, opt_type, data):
- print "Parsing a Location Request"
- try:
- if len(data) != 8:
- raise ReqInvalidError()
- sender_token, gid = struct.unpack("!LL", data)
- print "Requesting location data with following info:"
- print (sender_token, gid)
- session = Session()
- UInfo = UserManager.User
- LInfo = LocationManager.LocationInfo
- user_list = session.query(UInfo).filter(UInfo.gid == gid).all()
- reply = struct.pack("!BL", 3, len(user_list))
- for user in user_list:
- loc = session.query(LInfo).filter(LInfo.uid == user.id).first()
- reply += struct.pack("!Ldd", user.id, loc.lat, loc.lng)
- print get_hex(reply)
- return reply
- except struct.error:
- raise ReqInvalidError()
-
-class PiztorServer():
-
-
- class GenericHandler(SocketServer.StreamRequestHandler):
-
- def handle(self):
- print self.piz_srv
- sock = self.request
- sock.settimeout(100)
-# sock.setblocking(0)
- data = ""
- try:
- while True:
-# ready = select.select([sock], [], [], 10)
-# if not ready[0]:
-# raise ReqReadError()
- buff = sock.recv(4096)
- if len(buff) == 0:
- break # terminated
- else:
- data += buff
- sock.shutdown(socket.SHUT_RD)
-
- print "Got the data:" + get_hex(data)
-
- if len(data) < 1:
- print "invalid length"
- raise ReqInvalidError()
- opt_id = struct.unpack("!B", data[0])[0]
- print opt_id
- reply = self.piz_srv.mgr_map[opt_id](opt_id, data[1:])
- sock.sendall(reply)
- finally:
- sock.close()
-
- class ForkingEchoServer(SocketServer.ForkingMixIn, SocketServer.TCPServer):
- pass
-
- def __init__(self, host, port):
- PiztorServer.GenericHandler.piz_srv = self
- srv = PiztorServer.ForkingEchoServer((host, port),
- PiztorServer.GenericHandler)
- srv.request_queue_size = 100
-# srv.timeout = 2
- self.server = srv
-
- self.user_mgr = UserManager(self)
- self.mesg_mgr = MesgManager(self)
- self.location_mgr = LocationManager(self)
-
- self.mgr_map = [ self.user_mgr.authentication_handle,
- self.mesg_mgr.mesg_sending_handle,
- self.location_mgr.location_update_handle,
- self.location_mgr.location_request_handle]
-
- Base.metadata.create_all(engine)
-
-
- def run(self):
- try:
- self.server.serve_forever()
- except KeyboardInterrupt:
- print "Exiting..."
- self.server.shutdown()
- print "Server shutdown"
-
-if __name__ == "__main__":
-
- ps = PiztorServer("localhost", 9999)
- ps.run()