121 lines
3.3 KiB
Python
121 lines
3.3 KiB
Python
|
from UserModel import UserModel
|
||
|
from CameraModel import CameraModel
|
||
|
import CameraCommander
|
||
|
from WaitActivity import WaitActivity
|
||
|
|
||
|
|
||
|
class UserCommand:
|
||
|
class InvalidStateException(Exception):
|
||
|
pass
|
||
|
|
||
|
|
||
|
def __init__(self, sock, addr):
|
||
|
self.sock = sock
|
||
|
self.addr = addr[0]
|
||
|
self.port = addr[1]
|
||
|
|
||
|
|
||
|
def receive(self):
|
||
|
data = b""
|
||
|
ret = self.sock.recv(1)
|
||
|
while ret and ret != b"\x00":
|
||
|
data = data + ret
|
||
|
ret = self.sock.recv(1)
|
||
|
if not data:
|
||
|
return None
|
||
|
return data.decode()
|
||
|
|
||
|
|
||
|
def send(self, msg):
|
||
|
data = (msg + "\0").encode()
|
||
|
return self.sock.send(data) == len(data)
|
||
|
|
||
|
|
||
|
def close(self):
|
||
|
print("[UserCommand] : Closing connection with {}:{}".format(self.addr, self.port))
|
||
|
self.sock.close()
|
||
|
self.sock = None
|
||
|
self.addr = None
|
||
|
self.port = None
|
||
|
|
||
|
|
||
|
def callback(self, result, error_msg = None):
|
||
|
print("[UserCommand] : Send reply to {}:{}".format(self.addr, self.port))
|
||
|
if result:
|
||
|
self.send("ok")
|
||
|
elif error_msg:
|
||
|
self.send("error:" + error_msg)
|
||
|
else:
|
||
|
self.send("error")
|
||
|
self.close()
|
||
|
|
||
|
|
||
|
def execute(self):
|
||
|
if not self.sock:
|
||
|
raise UserCommand.InvalidStateException()
|
||
|
data = self.receive()
|
||
|
if not data:
|
||
|
print("[UserCommand] : Connection lost with {}:{}".format(self.addr, self.port))
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
words = data.split(":")
|
||
|
if len(words) != 4:
|
||
|
print("[UserCommand] : Error from {}:{}, invalid data".format(self.addr, self.port))
|
||
|
self.send("error:invalid_data")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
userMdl = UserModel()
|
||
|
user = userMdl.getByLogin(words[0])
|
||
|
if not user:
|
||
|
print("[UserCommand] : Error from {}:{}, invalid username".format(self.addr, self.port))
|
||
|
self.send("error:invalid_username")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
if user.password != words[1]:
|
||
|
print("[UserCommand] : Error from {}:{}, invalid password for user ({})".format(self.addr, self.port, user.login))
|
||
|
self.send("error:invalid_password")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
camMdl = CameraModel()
|
||
|
camera = camMdl.getById(words[3])
|
||
|
if not camera:
|
||
|
print("[UserCommand] : Error from user ({}) at {}:{}, invalid camera's serial number".format(user.login, self.addr, self.port))
|
||
|
self.send("error:invalid_camera_id")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
if not userMdl.haveCamera(user, camera):
|
||
|
print("[UserCommand] : User ({}) at {}:{} is not allowed to command camera ({})".format(user.login, self.addr, self.port, camera.id))
|
||
|
self.send("error:not_authorized")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
context = CameraCommander.CameraCommander.GetContext(camera)
|
||
|
if not context:
|
||
|
print("[UserCommand] : Error from user ({}) at {}:{}, camera ({}) is not registered".format(user.login, self.addr, self.port, camera.id))
|
||
|
self.send("error:camera_not_registered")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
if not isinstance(context.state, WaitActivity):
|
||
|
print("[UserCommand] : Error from user ({}) at {}:{}, camera ({}) is busy".format(user.login, self.addr, self.port, camera.id))
|
||
|
self.send("error:camera_busy")
|
||
|
self.close()
|
||
|
return
|
||
|
|
||
|
if words[2] == "enable":
|
||
|
context.enable(self)
|
||
|
elif words[2] == "disable":
|
||
|
context.disable(self)
|
||
|
elif words[2] == "disconnect":
|
||
|
context.disconnect(self)
|
||
|
else:
|
||
|
print("[UserCommand] : Error from user ({}) at {}:{}, invalid command".format(user.login, self.addr, self.port))
|
||
|
self.send("error:invalid_command")
|
||
|
self.close()
|
||
|
return
|