def getClientInfo(): clientID = request.args['clientID'] includeEvents = 'includeEvents' in request.args try: client = Client.get(Client.id == clientID) except DoesNotExist: return json.jsonify({"msg": "no such client"}), 404 if client.private: if client.owner != g.user: return "", 403 response = { "clientID": client.id, "name": client.name, "latitude": client.latitude, "longitude": client.longitude, "address": client.address, "owner": client.owner.id, "tags": [tag.title for tag in client.getTags()], "private": client.private } if includeEvents: events = (Event.select(Event, Client).join( Client).where((Event.client_id == client.id) & (Event.timestamp >= timeSubtract(days=1)))) response.update({ "events": [event.toFrontendObject(include_id=False) for event in events] }) return json.jsonify(**response)
def handler(self, data): database.connect() clientID = data['clientID'] try: client = Client.get(Client.id == clientID) except DoesNotExist: print("Client does not exist") return for userID in client.subscriber_list: user = User.get(User.id == userID) if data['status']: email = { "dst": user.email, "subject": "high {}".format(clientID), "msg": "Client {} has high value readings, which indicates bad air quality." .format(clientID) } else: email = { "dst": user.email, "subject": "low {}".format(clientID), "msg": "Client {} readings has gone normal.".format(clientID) } sendQueue("mail", json.dumps(email)) email['dst'] = user.phone sendQueue("sms", json.dumps(email)) database.close()
def editClient(): if g.user is None: return json.jsonify(result="Need to login") __paramsList__ = { "clientID": "str", "name": "str", "latitude": "float", "longitude": "float", "address": "str", "tags": "json", "private": "bool", "temperature_limit": "float", "humidity_limit": "float", "colevel_limit": "float", "dustlevel_limit": "float" } params = paramsParse(__paramsList__, request.args) try: client = Client.get(Client.id == params['clientID']) except DoesNotExist: return json.jsonify(result="clientid not found"), 404 if client.owner != g.user: return json.jsonify(result="you don't have permission"), 403 client.name = params['name'] client.latitude = params['latitude'] client.longitude = params['longitude'] client.address = params['address'] client.private = params['private'] client.temperature_limit = params['temperature_limit'] client.humidity_limit = params['humidity_limit'] client.colevel_limit = params['colevel_limit'] client.dustlevel_limit = params['dustlevel_limit'] client.save() TagsMap.link(client, params['tags']) return json.jsonify(result="success")
def addClient(): # AJAX: Add new client # Parameters: # - id: Uniquely identified ID # - latitude, longitude: client's location in latitude and longitude # - address: client's location in real world address # Returns # apiKey: API key for that client __paramsList__ = { "name": "str", "latitude": "float", "longitude": "float", "address": "str", "private": "bool", } if g.user is None: return json.jsonify(result='need to login first') params = paramsParse(__paramsList__, request.args) params['owner'] = g.user.id client = Client.create(**params) tags = json.loads(request.args['tags']) TagsMap.link(client, tags) return json.jsonify(result="success", apiKey=client.api_key, clientID=str(client.id))
def joinAllPrivateRooms(user): database.connect() clients = (Client.select().where((Client.owner == user) & (Client.private))) for client in clients: socketio.join_room("client_{}".format(client.id)) database.close()
def handler(self, data): clientID = data['clientID'] database.connect() client = Client.get(Client.id == clientID) with database.atomic(): LastEvent.delete().where(LastEvent.client_id == client).execute() Event.delete().where(Event.client_id == client).execute() client.delete_instance() database.close()
def subscribe(): clientID = request.args['clientID'] if g.user is None: return json.dumps({"result": "Need to login"}) userID = g.user.id client = Client.get(Client.id == clientID) client.subscriber_list.append(userID) client.save() return json.jsonify(result="success")
def exportUser(): if g.user is None: return json.jsonify(result="Need to login") clientID = request.args['clientID'] client = Client.get(Client.id == clientID) if client.owner != g.user: return json.jsonify(result="you don't have permission"), 403 # exportClient(clientID) return json.jsonify(result="success")
def handler(self, data): database.connect() client = Client.get(Client.id == data['clientID']) formatTable = { "json": ".json", "csv": ".csv", } compressionTable = { "gzip": ".gz", "bzip2": ".bz2", "none": "" } try: fileExt = formatTable[data['format']] except ValueError: raise FileFormatNotSupported try: compExt = compressionTable[data['compression']] except ValueError: raise FileFormatNotSupported fileName = "client_{username}_{clientid}_{time}{ext}{compExt}".format( username=client.owner.username, clientid=str(client.id), time=int(utcNow().timestamp()), ext=fileExt, compExt=compExt) filePath = os.path.join(config.EXPORT_FOLDER, fileName) if data['compression'] == "none": file = open(filePath, "w") elif data['compression'] == "gzip": file = gzip.open(filePath, "wt") else: file = bz2.open(filePath, "wt") events = (Event .select(Event, Client) .join(Client) .where(Event.client_id == client)) events = [event.toFrontendObject(include_id=False) for event in events] if data['format'] == "json": self._writeJSONData(file, client, events) elif data['format'] == "csv": self._writeCSVData(file, events) file.close() link = "{http}://{domain}/static/export/{fileName}".format(http=Config.PREFERRED_URL_SCHEME, domain=Config.SERVER_NAME, fileName=fileName) sendQueue("mail", json.dumps({ "dst": client.owner.email, "subject": "Export client {}".format(str(client.id)), "msg": "<a href=\"{link}\">{link}</a>".format(link=link) }))
def addEvent(): # API: Add events from a client # Parameters: # - clientID: client id # - temperature, humidity, dustLevel, coLevel: self-explanatory # - apiKey: API key specific to that client # Returns: # {"result": <result>} __paramsList__ = { "client_id": "str", "temperature": "float", "humidity": "float", "dustlevel": "float", "colevel": "float", "apikey": "str" } params = paramsParse(__paramsList__, request.args) if 'time' not in request.args: params['timestamp'] = utcNow() else: params['timestamp'] = fromTimestamp(request.args['time']) with database.atomic(): try: client = Client.get(Client.id == params['client_id']) except DoesNotExist: return json.jsonify(result="no such client"), 404 if client.api_key != params['apikey']: return json.jsonify(result="invalid api key"), 403 del params['apikey'] event = Event.create(**params) last_event, created = LastEvent.create_or_get(client_id=event.client_id, event_id=event.id) last_event.event_id = event.id last_event.save() broadcastEvent(event.toFrontendObject(include_geo=True), private=client.private) if overThreshold(client, event): if not client.last_notification: sendNotification(str(event.client_id.id), True) client.last_notification = True client.save() else: if client.last_notification: sendNotification(str(event.client_id.id), False) client.last_notification = False client.save() return json.jsonify(result="success")
def joinRoom(clientID, wsTokenKey=None, wsTokenValue=None): database.connect() if clientID == "index": socketio.join_room("index") return {"msg": "ok"} try: client = Client.get(Client.id == clientID) except DoesNotExist: return {"msg": "client not found"} if client.private: if (wsTokenKey is None) or (wsTokenValue is None): return {"msg": "need to auth"} try: _ = WebsocketToken.use(wsTokenKey, wsTokenValue) except InvalidToken: return {"msg": "invalid token"} socketio.join_room("client_{}".format(clientID)) return {"msg": "ok"}
def client(clientID): client = Client.get(Client.id == clientID) if client.private: if client.owner != g.user: return "nothing here", 403 return render_template("client.html", client=client.toFrontendObject())
def userClients(): clients = Client.select().where(Client.owner == g.user) return render_template("/user/clients.html", clients=clients)
def getEventRange(): # asumming 5 min interval clientID = request.args['clientID'] rangeFrom = int(request.args['from']) if rangeFrom == -1: rangeFrom = getMinEventTimestamp(clientID) rangeTo = int(request.args['to']) client = Client.get(Client.id == clientID) dateFrom = fromTimestamp(rangeFrom) dateTo = fromTimestamp(rangeTo) delta = dateTo - dateFrom if client.private and (client.owner != g.user): return "", 403 if (delta.days <= 1): # range <= 1 day, return all # 288 points print("1 day query") events = (Event.select().where((Event.client_id == client) & (Event.timestamp >= dateFrom) & (Event.timestamp <= dateTo)).order_by( Event.timestamp)) elif (delta.days <= 3): # range <= 3 days, 10 minutes period # 432 points print("3 days query") events = (Event.select( SQL("(timestamp - interval (MINUTE(timestamp) mod 10) MINUTE - interval SECOND(timestamp) SECOND) AS timestamp" ), fn.AVG(Event.temperature).alias("temperature"), fn.AVG(Event.humidity).alias("humidity"), fn.AVG(Event.dustlevel).alias("dustlevel"), fn.AVG(Event.colevel).alias("colevel")).where( (Event.client_id == client) & (Event.timestamp >= dateFrom) & (Event.timestamp <= dateTo)).group_by( fn.DATE(Event.timestamp), fn.HOUR(Event.timestamp), SQL("MINUTE(timestamp) div 10")).order_by(Event.timestamp)) elif (delta.days <= 7): # range <= 1 week, 20 minutes period # 504 points print("7 days query") events = (Event.select( SQL("(timestamp - interval (MINUTE(timestamp) mod 20) MINUTE - interval SECOND(timestamp) SECOND) AS timestamp" ), fn.AVG(Event.temperature).alias("temperature"), fn.AVG(Event.humidity).alias("humidity"), fn.AVG(Event.dustlevel).alias("dustlevel"), fn.AVG(Event.colevel).alias("colevel")).where( (Event.client_id == client) & (Event.timestamp >= dateFrom) & (Event.timestamp <= dateTo)).group_by( fn.DATE(Event.timestamp), fn.HOUR(Event.timestamp), SQL("MINUTE(timestamp) div 20")).order_by(Event.timestamp)) elif (delta.days <= 30): # range <= 1 month, 2 hour period, average # 372 points per type print("30 days query") events = (Event.select( SQL("(timestamp - interval MINUTE(timestamp) MINUTE - interval SECOND(timestamp) SECOND) AS timestamp" ), fn.AVG(Event.temperature).alias("temperature"), fn.AVG(Event.humidity).alias("humidity"), fn.AVG(Event.dustlevel).alias("dustlevel"), fn.AVG(Event.colevel).alias("colevel")).where( (Event.client_id == client) & (Event.timestamp >= dateFrom) & (Event.timestamp <= dateTo)).group_by( fn.DATE(Event.timestamp), SQL("HOUR(timestamp) div 2")).order_by(Event.timestamp)) else: print(">1 month query") # range >=1 month, 1 day period, average # min 365/366 datapoints per type events = (Event.select( fn.DATE(Event.timestamp).alias("timestamp"), fn.AVG(Event.temperature).alias("temperature"), fn.AVG(Event.humidity).alias("humidity"), fn.AVG(Event.dustlevel).alias("dustlevel"), fn.AVG(Event.colevel).alias("colevel")).where( (Event.client_id == client) & (Event.timestamp >= dateFrom) & (Event.timestamp <= dateTo)).group_by( fn.DATE(Event.timestamp)).order_by(Event.timestamp)) return json.jsonify( [event.toFrontendObject(include_id=False) for event in events])