def __init__(self):
        super().__init__()
        self.led = LedController(None, 43432)
        self.gift_lightpad = GiftLightPad(self)
        self.autoConnector = AutoConnector(self)
        self.autoConnector.start()

        self.webSocket = WebSocket(self)
        self.webSocket.start()
        self.paperLengthWatcher = PaperLengthController(self)
        self.sizeCalculator = GiftSizeCalculator(self.finished_size_calc, self.gift_placed, self.led)

        self.deviceServer = DeviceServer(self)
        self.deviceServer.start()

        self.orderHandler = OrderHandler(self.new_order)
        if not self.fakeorder:
            self.orderHandler.get_open_orders()
        else:
            current_order = {
                "id" : 1,
                "paper_id": 3,
                "deco_ids": [5,6,7]
            }
            self.orderHandler.current_order = current_order

            if self.testprojections:
                self.sizeCalculator.generate_mock_values()
                self.test_projection()
            else:
                self.new_order()
    def __init__(self):
        self.socket = WebSocket("0.0.0.0", 5678, MaxTokensAtOnce, TokensTTL,
                                self)
        self.socket.start()
        self.database = database.Database()
        self.externalAPI = ExternalAPI(None, None, None, None).metrics

        self.userThreads = {}
        self.clientTokens = TTLCache(maxsize=MaxTokensAtOnce, ttl=TokensTTL)
        self.medicTokens = TTLCache(maxsize=MaxTokensAtOnce, ttl=TokensTTL)
        self.userMetrics = {}
        allUsers = self.database.getAllUsers()
        for user in allUsers:
            metrics = {
            }  #{GPS: [metric], HealthStatus: [metric, metric], Sleep:[metric]}
            userDevices = self.database.getAllDevices(user)
            for device in userDevices:
                deviceType = device["type"].strip().replace(" ", "_")
                userDevice = eval(deviceType +
                                  "(device[\"authentication_fields\"],\"" +
                                  user + "\",\"" + str(device.get("id", "")) +
                                  "\", [" +
                                  str(device.get("latitude", str(None))) +
                                  "," +
                                  str(device.get("longitude", str(None))) +
                                  "])")
                for metric in userDevice.metrics:
                    if metric.metricType not in metrics:
                        metrics[metric.metricType] = []
                    metrics[metric.metricType].append(metric)

            for metric in GPS(None, user, None,
                              None).metrics + self.externalAPI:
                if metric.metricType not in metrics:
                    metrics[metric.metricType] = []
                metrics[metric.metricType].append(metric)

            self.userMetrics[user] = metrics

            #print(metrics)

            #passing only the GPS, HealthStatus and Sleep to the Thread
            self.userThreads[user] = AggregatorThread(
                self, {
                    k: v
                    for k, v in metrics.items()
                    if k in ["GPS", "HealthStatus", "Sleep"]
                }, user)
            self.userThreads[user].start()
Example #3
0
def dynJS(handler):
	handler.wrappers = False
	handler.log = False
	handler.contentType = 'text/javascript'

	print "function get_websocket_port() {return %s;}" % toJS(PORT if WebSocket.available() else False)
Example #4
0
def dynJS(handler):
	port = WebSocket.getUAPort()
	handler.wrappers = False
	handler.contentType = 'text/javascript'
	print "function get_websocket_port() {return %d;}" % port
Example #5
0
from StaticContentServer import StaticContentServer
from UiDataGenerator import UiDataGenerator
from WebSocket import WebSocket
from Constants import Constants
import sys
sys.path.append('.')
import time
import sensors
import detectors


# start UI
StaticContentServer.async_start(port=Constants.static_content_port)
WebSocket.async_start(port=Constants.web_socket_port)

#DummyDataGenerator.async_start()

# set up the IMU
IMU_SETTINGS_FILE = "IMU_settings"
imu = sensors.IMU_Reader(IMU_SETTINGS_FILE)

# set up and start the GPS
#location = sensors.GPS_location_provider()
location = sensors.IP_location_provider()

# start our detector
detector = detectors.simulated_detector()

# start generator and subscribe to the detector
UiGenerator = UiDataGenerator(detector, imu, location, sensors.getserial())
UiGenerator.subscribe_to_detector()
Example #6
0
from flask import Flask, render_template, request, send_file, make_response
from WebSocket import WebSocket, Client
from multiprocessing import Process
from gevent.wsgi import WSGIServer
import random, string, os
from irc import IRC

tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                        'templates')
app = Flask(__name__, template_folder=tmpl_dir)

webSocket = WebSocket()
webSocket.config({
    'origin_port': 8888,
    'origin_host': '127.0.0.1',
    'websocket_host': '127.0.0.1',
    'websocket_port': 8976
})


@webSocket.onConnect  #Handle the webSocket Connection, return Client() obj if auth successful
def handler(
        *args,
        **kwargs):  #Handle the client connection, do whatever you want here
    ID = args[0]
    client = args[1]
    IRC(client, ID)
    del webSocket.clients[ID]
    webSocket.log("INFO", "Connection with %s ended" % ID)

Example #7
0
pidFile = option('pidfile')
if pidFile:
	with open(pidFile, 'w') as f:
		f.write("%d\n" % os.getpid())

restart = False
preServer.stop()

try:
	server = getServer()
except ServerError, e:
	console('server', e.message)
	exit(1)

Cron.start()
WebSocket.start()

try:
	console('rorn', 'Listening for connections')
	try:
		server.serve_forever()
	except socket.error, e:
		if e.errno == errno.EBADF and (bricked() or '').startswith('Restart'):
			restart = True
		else:
			raise
except KeyboardInterrupt:
	sys.__stdout__.write("\n\n")
	console('main', 'Exiting at user request')
except (Exception, SystemExit), e:
	sys.__stdout__.write("\n\n")
class Processor:
    def __init__(self):
        self.socket = WebSocket("0.0.0.0", 5678, MaxTokensAtOnce, TokensTTL,
                                self)
        self.socket.start()
        self.database = database.Database()
        self.externalAPI = ExternalAPI(None, None, None, None).metrics

        self.userThreads = {}
        self.clientTokens = TTLCache(maxsize=MaxTokensAtOnce, ttl=TokensTTL)
        self.medicTokens = TTLCache(maxsize=MaxTokensAtOnce, ttl=TokensTTL)
        self.userMetrics = {}
        allUsers = self.database.getAllUsers()
        for user in allUsers:
            metrics = {
            }  #{GPS: [metric], HealthStatus: [metric, metric], Sleep:[metric]}
            userDevices = self.database.getAllDevices(user)
            for device in userDevices:
                deviceType = device["type"].strip().replace(" ", "_")
                userDevice = eval(deviceType +
                                  "(device[\"authentication_fields\"],\"" +
                                  user + "\",\"" + str(device.get("id", "")) +
                                  "\", [" +
                                  str(device.get("latitude", str(None))) +
                                  "," +
                                  str(device.get("longitude", str(None))) +
                                  "])")
                for metric in userDevice.metrics:
                    if metric.metricType not in metrics:
                        metrics[metric.metricType] = []
                    metrics[metric.metricType].append(metric)

            for metric in GPS(None, user, None,
                              None).metrics + self.externalAPI:
                if metric.metricType not in metrics:
                    metrics[metric.metricType] = []
                metrics[metric.metricType].append(metric)

            self.userMetrics[user] = metrics

            #print(metrics)

            #passing only the GPS, HealthStatus and Sleep to the Thread
            self.userThreads[user] = AggregatorThread(
                self, {
                    k: v
                    for k, v in metrics.items()
                    if k in ["GPS", "HealthStatus", "Sleep"]
                }, user)
            self.userThreads[user].start()

        #urls["https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json"]=[{"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIyMkRLMlgiLCJzdWIiOiI3Q05RV1oiLCJpc3MiOiJGaXRiaXQiLCJ0eXAiOiJhY2Nlc3NfdG9rZW4iLCJzY29wZXMiOiJyc29jIHJhY3QgcnNldCBybG9jIHJ3ZWkgcmhyIHJudXQgcnBybyByc2xlIiwiZXhwIjoxNTUzODAxNjA5LCJpYXQiOjE1NTM3NzI4MDl9.6_hSXgYG36430e-ZaRfcEYSzDezGJeaMF5R2PiSr4bk"}, 1]
        #urls["http://api.foobot.io/v2/device/240D676D40002482/datapoint/10/last/0/"]=[{"Accept":"application/json;charset=UTF-8","X-API-KEY-TOKEN":"eyJhbGciOiJIUzI1NiJ9.eyJncmFudGVlIjoiam9hby5wQHVhLnB0IiwiaWF0IjoxNTUyMDY2Njc5LCJ2YWxpZGl0eSI6LTEsImp0aSI6IjRiNmY2NzhiLWJjNTYtNDYxNi1hYmMyLTRiNjlkMTNkMjUzOSIsInBlcm1pc3Npb25zIjpbInVzZXI6cmVhZCIsImRldmljZTpyZWFkIl0sInF1b3RhIjoyMDAsInJhdGVMaW1pdCI6NX0.aeLLsrhh1-DVXSwl-Z_qDx1Xbr9oIid1IKsOyGQxwqQ"},1]

    def signup(self, jsonData):
        try:
            self.database.register(jsonData)

            if jsonData["type"] == "client":
                user = jsonData["username"]
                if user not in self.userMetrics:
                    self.userMetrics[user] = {}

                    for metric in GPS({}, user, None,
                                      None).metrics + self.externalAPI:
                        if metric.metricType not in self.userMetrics[user]:
                            self.userMetrics[user][metric.metricType] = []
                        self.userMetrics[user][metric.metricType].append(
                            metric)

                    self.userThreads[user] = AggregatorThread(
                        self, {
                            k: v
                            for k, v in self.userMetrics[user].items()
                            if k in ["GPS", "HealthStatus", "Sleep"]
                        }, user)
                    self.userThreads[user].start()

            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def logout(self, token):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401
        elif client:
            del self.clientTokens[token]
        elif medic:
            del self.medicTokens[token]

        return json.dumps({
            "status": 0,
            "msg": "Successful operation."
        }).encode("UTF-8"), 200

    def _generateToken(self, tokenMap, username):
        """
        Generates a new token for a user and stores it

        :param tokenMap: self.clientTokens or self.medicTokens
        :type tokenMap: dict
        :param username: of the user loggedin
        :type username: str
        :return: the new token
        :rtype: str
        """
        min_char = 30
        max_char = 40
        allchar = string.ascii_letters + string.digits

        for t, n in tokenMap.items():
            if n == username:
                return t

        token = "".join(
            choice(allchar) for x in range(randint(min_char, max_char)))
        while token in tokenMap:
            token = "".join(
                choice(allchar) for x in range(randint(min_char, max_char)))

        tokenMap[token] = username

        return token

    def signin(self, jsonData):
        userType = self.database.verifyUser(jsonData)

        if userType == 0:  # invalid login
            return json.dumps({
                "status": 1,
                "msg": "Incorrect username or password."
            }).encode("UTF-8"), 406

        elif userType == 1:  # valid login and user is a client
            token = self._generateToken(self.clientTokens,
                                        jsonData["username"])
        elif userType == 2:  # valid login and user is a medic
            token = self._generateToken(self.medicTokens, jsonData["username"])

        return json.dumps({
            "status": 0,
            "msg": "Successful operation.",
            "data": {
                "token": token
            }
        }).encode("UTF-8"), 200

    def getAllDevices(self, token):
        if self.medicTokens.get(token):
            return json.dumps({
                "status":
                1,
                "msg":
                "Medic users don't have devices associated."
            }).encode("UTF-8"), 406

        user = self.clientTokens.get(token, None)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            devices = self.database.getAllDevices(user)

            for device in devices:
                auth_fields = device.pop("authentication_fields")
                for field_name, field_value in auth_fields.items():
                    device[field_name] = field_value

        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500

        return json.dumps({
            "status": 0,
            "msg": "Successful operation.",
            "data": devices
        }).encode("UTF-8"), 200

    def updateDevice(self, token, deviceConf):
        if self.medicTokens.get(token):
            return json.dumps({
                "status":
                3,
                "msg":
                "Medic users don't have devices associated."
            }).encode("UTF-8"), 403

        user = self.clientTokens.get(token, None)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            userDevices = {
                submetric.dataSource
                for metric in self.userMetrics[user]
                for submetric in self.userMetrics[user][metric]
            }
            for device in userDevices:
                if device.id == str(deviceConf["id"]):
                    latitude = deviceConf[
                        "latitude"] if "latitude" in deviceConf else device._location[
                            0]
                    longitude = deviceConf[
                        "longitude"] if "longitude" in deviceConf else device._location[
                            1]
                    device.update(deviceConf["authentication_fields"],
                                  [latitude, longitude])
                    if user in self.userThreads:
                        self.userThreads[user].end()
                    self.userThreads[user] = AggregatorThread(
                        self, {
                            k: v
                            for k, v in self.userMetrics[user].items()
                            if k in ["GPS", "HealthStatus", "Sleep"]
                        }, user)
                    self.userThreads[user].start()
                    break
            self.database.updateDevice(user, deviceConf)
            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def deleteDevice(self, token, data):
        if self.medicTokens.get(token):
            return json.dumps({
                "status":
                3,
                "msg":
                "Medic users don't have devices associated."
            }).encode("UTF-8"), 403

        user = self.clientTokens.get(token, None)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            deviceId = data["id"]
            for metric in self.userMetrics[user]:
                for submetric in self.userMetrics[user][metric]:
                    if submetric.dataSource.id == deviceId:
                        self.userMetrics[user][metric].remove(submetric)

            self.database.deleteDevice(user, deviceId)
            if user in self.userThreads:
                self.userThreads[user].end()
            self.userThreads[user] = AggregatorThread(
                self, {
                    k: v
                    for k, v in self.userMetrics[user].items()
                    if k in ["GPS", "HealthStatus", "Sleep"]
                }, user)
            self.userThreads[user].start()

            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def addDevice(self, token, jsonData):
        if self.medicTokens.get(token):
            return json.dumps({
                "status":
                3,
                "msg":
                "Medic users don't have devices associated."
            }).encode("UTF-8"), 403

        user = self.clientTokens.get(token, None)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            id = str(self.database.addDevice(user, jsonData))
            print(id)

            if id not in [
                    submetric.dataSource.id
                    for metric in self.userMetrics[user]
                    for submetric in self.userMetrics[user][metric]
            ]:
                deviceType = jsonData["type"].strip().replace(" ", "_")
                device = eval(deviceType +
                              "(jsonData[\"authentication_fields\"],\"" +
                              user + "\",\"" + str(id) + "\", [" +
                              jsonData.get("latitude", str(None)) + "," +
                              jsonData.get("longitude", str(None)) + "])")
                for metric in device.metrics:
                    if metric.metricType not in self.userMetrics[user]:
                        self.userMetrics[user][metric.metricType] = []
                    self.userMetrics[user][metric.metricType].append(metric)

                print(self.userMetrics)
                if user in self.userThreads:
                    self.userThreads[user].end()
                self.userThreads[user] = AggregatorThread(
                    self, {
                        k: v
                        for k, v in self.userMetrics[user].items()
                        if k in ["GPS", "HealthStatus", "Sleep"]
                    }, user)
                self.userThreads[user].start()

            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def getData(self, token, endpoint, start, end, interval, patient):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            if client:
                values = self.database.getData(endpoint, client, start, end,
                                               interval)
            elif medic:
                if endpoint == "Path":
                    return json.dumps({
                        "status": 4,
                        "msg": "Only accecible to patitents."
                    }).encode("UTF-8"), 401

                if not patient:
                    return json.dumps({
                        "status": 2,
                        "msg": "Missing argument \"patient\""
                    }).encode("UTF-8"), 400

                values = self.database.getDataByMedic(medic, endpoint, patient,
                                                      start, end, interval)
            return json.dumps({
                "status": 0,
                "msg": "Successful operation.",
                "data": values
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def download(self, userCount):
        """
        Gets all data from a number of users, received
        If the number received is less than the number
         of existing users than the users are chosen randomly
        Else all the users are sent

        :param userCount: number os users to retrieve
        :type userCount: int
        :return: of all users, with all metrics and its data in each one
        :rtype: list
        """
        users = self.database.getAllUsers()

        if userCount < len(users):
            users = choices(users, k=userCount)

        allData = []

        for user in users:
            userData = {}
            for metric in [
                    "Environment", "Event", "HealthStatus", "Path",
                    "PersonalStatus", "Sleep"
            ]:
                userData[metric] = self.database.getData(
                    metric, user, 0, None, None)

            allData.append(userData)

        return json.dumps({
            "status": 0,
            "msg": "Successful operation.",
            "data": allData
        }).encode("UTF-8")

    def updateProfile(self, token, data):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401
        elif client:
            user = client
        elif medic:
            user = medic

        argsErrors = ArgumentValidator.signupAndUpdateProfile(
            True if client else False, True, data)
        if len(argsErrors) > 0:
            return json.dumps({
                "status":
                2,
                "msg":
                "Argument errors : " + ", ".join(argsErrors)
            }).encode("UTF-8"), 400

        try:
            self.database.updateProfile("client" if client else "medic", user,
                                        data)
            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def getProfile(self, token, data):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        patient = None
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401
        elif client:
            user = client
        elif medic:
            user = medic
            patient = data.get("patient")

        try:
            if patient:
                profile = self.database.getPatientProfile(medic, patient)
            else:
                profile = self.database.getProfile(user)

            return json.dumps({
                "status": 0,
                "msg": "Successful operation.",
                "data": profile
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def deleteProfile(self, token):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401
        elif client:
            user = client
        elif medic:
            user = medic

        try:
            self.database.deleteProfile(user)
            return json.dumps({
                "status": 0,
                "msg": "Successful operation."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def getSupportedDevices(self):
        try:
            values = self.database.getSupportedDevices()
            return json.dumps({
                "status": 0,
                "msg": "Successful operation.",
                "data": values
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def uploadPermission(self, token, jsonData):
        """
        Use by both medic and client
        grants/requests for a permission. calls 'grantPermission' and 'requestPermission' on database.py

        args:
        username - str - of the user the he wants to grant or request permission
        data - {username:str, health_number: int, duration: int}
        """
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        argsErrors = ArgumentValidator.uploadPermissions(
            "medic" if medic else "client", jsonData)
        if len(argsErrors) > 0:
            return json.dumps({
                "status":
                2,
                "msg":
                "Argument errors : " + ", ".join(argsErrors)
            }).encode("UTF-8"), 400

        try:
            target = jsonData["username"]
            targetToken = None
            for (k1, v1), (k2, v2) in zip(self.medicTokens.items(),
                                          self.clientTokens.items()):
                if v1 == target or v2 == target:
                    targetToken = (k1 if v1 == target else k2)

            if client:
                source, destination = self.database.grantPermission(
                    client, jsonData)
            elif medic:
                source, destination = self.database.requestPermission(
                    medic, jsonData)

            permissionThread([source], targetToken, self.socket).start()

            return json.dumps({
                "status": 0,
                "msg": "Successful operation.",
                "data": destination
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def getAllPermissions(self, token):
        """
        Use by both medic and client
        gets all current permissions. calls 'allPermissionsData' on database.py
        """
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            data = self.database.allPermissionsData(
                client if client else medic)
            return json.dumps({
                "status": 0,
                "msg": "Successful operation.",
                "data": data
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def acceptPermission(self, token, medic):
        """
        Used only by the client, accepts a pending permission

        args:
        token - str - token representing the user
        medic - str - of the medic that he wants to reject request for permission
        """
        if self.medicTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to patients"
            }).encode("UTF-8"), 406

        client = self.clientTokens.get(token)
        if not client:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            self.database.acceptPermission(client, medic)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Permission accepted with success."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def rejectPermission(self, token, medic):
        """
        Used only by the client, rejects a pending permission

        args:
        token - str - token representing the user
        medic - str - of the medic that he wants to reject request for permission
        """
        if self.medicTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to patients"
            }).encode("UTF-8"), 406

        client = self.clientTokens.get(token)
        if not client:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            self.database.rejectPermission(client, medic)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Permission rejected with success."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def removePendingPermission(self, token, client):
        """
        Used only by the medic, removes a pending permission (requests not responded by the client)

        args
        token - str - token representing the user
        client - str - of the client that he wants to remove the active permission
        """
        if self.clientTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to medics"
            }).encode("UTF-8"), 406

        medic = self.medicTokens.get(token)
        if not medic:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            self.database.deleteRequestPermission(medic, client)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Permission removed with success."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def removeAcceptedPermission(self, token, medic):
        """
        Used only by the client, removes an accepted permission

        args
        token - str - token representing the user
        username - str - of the medic that he wants to remove an accepted permission
        """
        if self.medicTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to patients"
            }).encode("UTF-8"), 406

        client = self.clientTokens.get(token)
        if not client:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        try:
            self.database.removeAcceptedPermission(client, medic)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Permission removed with success."
            }).encode("UTF-8"), 200
        except LogicException as e:
            return json.dumps({
                "status": 1,
                "msg": str(e)
            }).encode("UTF-8"), 406
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status": -1,
                "msg": "Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def process(self, responses, user):
        normalData = {}
        for resp in responses:
            metric = resp[0]
            if metric not in normalData:
                normalData[metric] = {}
            normalData[metric] = dict(normalData[metric], **resp[1])

        if "GPS" in normalData:
            envMetrics = [
                submetric for metric in self.userMetrics[user]
                for submetric in self.userMetrics[user][metric]
                if submetric.metricType == "Environment"
            ]
            if normalData["GPS"]["latitude"] != None and normalData["GPS"][
                    "longitude"] != None:
                if float(normalData["GPS"]["latitude"]) > -90 and float(
                        normalData["GPS"]["latitude"]) < 90 and float(
                            normalData["GPS"]["longitude"]) > -180 and float(
                                normalData["GPS"]["longitude"]) < 180:
                    for metric in [
                            metric for metric in envMetrics
                            if metric.metricLocation == "inside"
                    ]:
                        distance = round(
                            vincenty([
                                float(normalData["GPS"]["latitude"]),
                                float(normalData["GPS"]["longitude"])
                            ], metric.dataSource.location).m)
                        if distance <= RADIUS:
                            try:
                                jsonData = metric.getData()
                                data = metric.normalizeData(jsonData)
                                normalData["Environment"] = dict(
                                    normalData["Environment"], **data)
                            except Exception as e:
                                logging.error(
                                    "<" + user +
                                    ">Exception caught while refetching the data: "
                                    + str(e))
                                try:
                                    tokens = metric.dataSource.refreshToken()
                                    self.updateDevice(
                                        metric.dataSource.user, {
                                            "id":
                                            metric.dataSource.id,
                                            "token":
                                            tokens["token"],
                                            "refresh_token":
                                            tokens["refresh_token"]
                                        })
                                    resp = metric.normalizeData(
                                        metric.getData())
                                    normalData["Environment"] = dict(
                                        normalData["Environment"], **data)
                                except Exception as e:
                                    logging.error(
                                        "<" + user +
                                        ">Tried to refresh tokens and couldn't, caught error: "
                                        + str(e))
                    if normalData["Environment"] == {}:
                        for metric in [
                                metric for metric in envMetrics
                                if metric.metricLocation == "outside"
                        ]:
                            try:
                                jsonData = metric.getData()
                                data = metric.normalizeData(jsonData)
                                normalData["Environment"] = dict(
                                    normalData["Environment"], **data)
                            except Exception as e:
                                logging.error(
                                    "<" + user +
                                    ">Exception caught while refetching the data: "
                                    + str(e))
                                try:
                                    tokens = metric.dataSource.refreshToken()
                                    self.updateDevice(
                                        metric.dataSource.user, {
                                            "id":
                                            metric.dataSource.id,
                                            "token":
                                            tokens["token"],
                                            "refresh_token":
                                            tokens["refresh_token"]
                                        })
                                    resp = metric.normalizeData(
                                        metric.getData())
                                    normalData["Environment"] = dict(
                                        normalData["Environment"], **data)
                                except Exception as e:
                                    logging.error(
                                        "<" + user +
                                        ">Tried to refresh tokens and couldn't, caught error: "
                                        + str(e))
                    #print(normalData["GPS"])
                    normalData["Environment"]["latitude"] = normalData["GPS"][
                        "latitude"]
                    normalData["Environment"]["longitude"] = normalData["GPS"][
                        "longitude"]

            else:
                logging.error("Couldn't process GPS: " +
                              str(normalData["GPS"]))

            del normalData["GPS"]

        try:
            coords = self.userMetrics[user]["GPS"][0].normalizeData(
                self.userMetrics[user]["GPS"][0].getData())
            responses.append(("Path", {"path": coords}))
            for metric in normalData:
                if metric != "Environment":
                    normalData[metric]["latitude"] = coords["latitude"]
                    normalData[metric]["longitude"] = coords["longitude"]
        except Exception as e:
            logging.error("<" + user +
                          ">Error while fetching GPS Coordinates. " + str(e))

        for metric in normalData:
            if time not in normalData[metric]:
                normalData[metric]["time"] = int(time.time())

        print(normalData)
        try:
            self._save(normalData, user)
        except Exception as e:
            logging.error("<" + user + ">Error while saving data. " + str(e))

    def registerMood(self, token, data):
        if self.medicTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to patients"
            }).encode("UTF-8"), 406

        user = self.clientTokens.get(token)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        moods = data["moods"]
        concatMoods = moods[0]
        allMoods = {"events": [], "metrics": [], "data": {}}
        for m in moods:
            allMoods["events"].append(m)
            allMoods["metrics"].append("PersonalStatus")
            concatMoods += "," + m
        try:
            self.process([("PersonalStatus", {
                "moods": concatMoods[:-1]
            }), ("Event", {
                "events": json.dumps(allMoods)
            })], user)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Mood(s) registered with success."
            }).encode("UTF-8"), 200
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": "While saving data. " + str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status":
                -1,
                "msg":
                "While saving data.Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def deleteMood(self, token, data):
        if self.medicTokens.get(token):
            return json.dumps({
                "status": 1,
                "msg": "Only accessible to patients"
            }).encode("UTF-8"), 406

        user = self.clientTokens.get(token)
        if not user:
            return json.dumps({
                "status": 4,
                "msg": "Invalid Token."
            }).encode("UTF-8"), 401

        time = data["time"]
        deleteMetrics = ["Event", "PersonalStatus"]
        try:
            for metric in deleteMetrics:
                self.database.delete(metric, time, user)
            return json.dumps({
                "status":
                0,
                "msg":
                "Successful operation. Mood(s) deleted with success."
            }).encode("UTF-8"), 200
        except DatabaseException as e:
            return json.dumps({
                "status": -1,
                "msg": "While saving data. " + str(e)
            }).encode("UTF-8"), 500
        except Exception as e:
            return json.dumps({
                "status":
                -1,
                "msg":
                "While saving data. Server internal error. " + str(e)
            }).encode("UTF-8"), 500

    def _save(self, data, user):
        try:
            for key in data:
                self.database.insert(key, data[key], user)
        except Exception as e:
            raise e

    def end(self):
        for k in self.userThreads:
            self.userThreads[k].end()
        return ""

    def checkPermissions(self, token):
        client = self.clientTokens.get(token, None)
        medic = self.medicTokens.get(token, None)
        if not client and not medic:
            logging.error("Invalid Token in check permissions of " +
                          client if client else medic)
            return
        try:
            data = self.database.getPendingPermissions(
                client if client else medic)
            permissionThread(data, token, self.socket).start()
        except DatabaseException as e:
            logging.error("Database error in check permissions of " +
                          client if client else medic + " -> " + str(e))
            return
        except Exception as e:
            print(e)
            logging.error("Server error in check permissions of " +
                          client if client else medic + " -> " + str(e))
            return
class Orchestrator(StateMachine):
    print("Started orchestrator")
    fakeorder = False
    testprojections = False
    optlist, _ = getopt.getopt(sys.argv[1:], "", ["fakeorder=", "testprojections="])
    print(optlist)
    for o,a in optlist:
        if o in ["--fakeorder"]:
            fakeorder = True
        elif o in ["--testprojections"]:
            testprojections = True
        else:
            assert False, "unhandled option " + o

    devices = {}

    # states
    idle = State('Idle', initial=True)
    waitingForGift = State('WaitingForGift')
    start = State('Start')
    sizeCalculated = State('SizeCalculated')
    paperPrepared = State('PaperPrepared')
    paperCutOff = State('PaperCutOff')
    knifeMovedBack = State('KnifeMovedBack')
    giftPlaced = State('GiftProjected')
    giftWrapped = State('GiftWrapped')
    firstFold = State('FirstFold')
    secondFold = State('SecondFold')
    thirdFold = State('ThirdFold')

    # actions
    new_order = idle.to(start)
    finished_size_calc = start.to(sizeCalculated) # when size was calculated continue with preparing paper
    finished_paper_prep = sizeCalculated.to(paperPrepared) # paper is prepared. now project the paper on the table
    paper_not_prepared = paperPrepared.to(sizeCalculated) # paper is not in range anymore
    cut_paper_off = paperPrepared.to(paperCutOff) # paper is laid out (lightpad2 is semi-bright). now project the gift on top of the paper
    moved_knife_back = paperCutOff.to(knifeMovedBack)

    gift_placed = knifeMovedBack.to(giftPlaced)
    gift_removed = giftPlaced.to(knifeMovedBack)

    finish = giftPlaced.to(idle)
    next_order = giftPlaced.to(waitingForGift)
    tape_teared = giftPlaced.to(firstFold) | firstFold.to(secondFold) | secondFold.to(thirdFold)
    finish_order = thirdFold.to(start)

    test_projection = idle.to(knifeMovedBack)

    def __init__(self):
        super().__init__()
        self.led = LedController(None, 43432)
        self.gift_lightpad = GiftLightPad(self)
        self.autoConnector = AutoConnector(self)
        self.autoConnector.start()

        self.webSocket = WebSocket(self)
        self.webSocket.start()
        self.paperLengthWatcher = PaperLengthController(self)
        self.sizeCalculator = GiftSizeCalculator(self.finished_size_calc, self.gift_placed, self.led)

        self.deviceServer = DeviceServer(self)
        self.deviceServer.start()

        self.orderHandler = OrderHandler(self.new_order)
        if not self.fakeorder:
            self.orderHandler.get_open_orders()
        else:
            current_order = {
                "id" : 1,
                "paper_id": 3,
                "deco_ids": [5,6,7]
            }
            self.orderHandler.current_order = current_order

            if self.testprojections:
                self.sizeCalculator.generate_mock_values()
                self.test_projection()
            else:
                self.new_order()

    def on_enter_idle(self):
        print('No orders')

    def on_enter_waitingForGift(self):
        self.webSocket.send_current_state()

    def on_enter_start(self):
        print('New Order')
        self.sizeCalculator.active = True
        self.webSocket.send_current_state()

    def on_enter_sizeCalculated(self):
        print('Size calculated - watching the paper now')
        self.webSocket.send_current_state()
        #self.motorDriver.set_paper_length(self.sizeCalculator.paper_width)
        #self.motorDriver.start()
        self.paperLengthWatcher.set_paper_dimensions(self.sizeCalculator.paper_height)

    def on_enter_paperPrepared(self):
        print('Finished paper prep!')
        # project paper onto the table now
        # send message to ws to render paper projection
        self.webSocket.send_current_state()

    def on_enter_paperCutOff(self):
        print('Paper cut off')
        self.webSocket.send_current_state()

    def on_enter_knifeMovedBack(self):
        print('Knife moved back')
        self.webSocket.send_current_state()
        self.led.set_rgb("0,0,0")
        self.gift_lightpad.active = True

    def on_enter_giftPlaced(self):
        print('Project the arrows onto the paper')
        # project arrows onto the paper now
        # send message to ws to render arrow projection
        self.webSocket.send_current_state()

    def on_enter_giftWrapped(self):
        print('gift was placed')
        # project arrows onto the paper now
        # send message to ws to render arrow projection
        self.webSocket.send_current_state()

    def on_enter_firstFold(self):
        print("first fold done")
        self.webSocket.send_current_state()

    def on_enter_secondFold(self):
        print("second fold done")
        self.webSocket.send_current_state()

    def on_enter_thirdFold(self):
        print("third fold done")
        self.webSocket.send_current_state()

    def handle_lightpad_change(self, id, value):
        try:
            if id == 1:
                self.gift_lightpad.set_value(value)
            elif id == 2:
                if value == 0:
                    self.cut_paper_off()
                else:
                    self.moved_knife_back()
        except exceptions.TransitionNotAllowed:
            pass
            #print("Transition not allowed")
            #print(self.current_state)

    def get_current_message(self):

        state_id = self.current_state.identifier
        if hasattr(self, 'orderHandler'):
            #current_order = self.orderHandler.current_order_items
            current_order = self.orderHandler.current_order
        else:
            current_order = {}
        message = {
            "state": state_id,
            "gift_width": self.sizeCalculator.gift_width,
            "gift_height": self.sizeCalculator.gift_height,
            "gift_depth": self.sizeCalculator.gift_depth,
            "paper_width": self.sizeCalculator.paper_width,
            "paper_height": self.sizeCalculator.paper_height,
            "current_order": current_order
        }
        return str(message).replace("'",'"')

    def update_devices(self, devices):
        self.devices = {**self.devices, **devices}

        if led_unit_name in devices:
            led_ip = devices[led_unit_name]
            self.led.ip = led_ip
            self.led.set_rgb("255,0,0")
            print("Updated LED IP")
Example #10
0
from flask import Flask, render_template, request, send_file, make_response
from WebSocket import WebSocket, Client
from multiprocessing import Process
from gevent.wsgi import WSGIServer
import random, string, os
from irc import IRC

tmpl_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'templates')
app = Flask(__name__,template_folder=tmpl_dir)

webSocket = WebSocket()
webSocket.config({'origin_port' : 8888,
				  'origin_host' : '127.0.0.1',
				  'websocket_host' : '127.0.0.1',
				  'websocket_port' : 8976
				})

@webSocket.onConnect #Handle the webSocket Connection, return Client() obj if auth successful
def handler(*args, **kwargs): #Handle the client connection, do whatever you want here
	ID = args[0]
	client = args[1]
	IRC(client, ID)
	del webSocket.clients[ID]
	webSocket.log("INFO", "Connection with %s ended" % ID)

def loop():
	webSocket.running = True
	while webSocket.running:
		handler()
		webSocket.log("INFO","Handler initiated")