diff --git a/api/authentication.py b/api/authentication.py index 0aa80dd..0ad9b04 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -74,3 +74,20 @@ def verify(): lib.utils.sendVerificationMail(user.display_name, user.email, code) resp = {'error': 'Server could not find code, creating new one and sending email'} return Response(json.dumps(resp), status=500, mimetype='application/json') + +@authentication.route('/authentication/get-user-devices', methods=['GET']) +def uploadReadings(): + uid = request.headers.get('UID') + if uid is None: + resp = {'error': 'UID not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + # Save all the measurements + doc = firestore.client().collection(u'devices').document(uid).get() + if doc.exists: + list = doc.to_dict()['devices'] + data = list + else: + data = [] + res = {'devices': data} + return Response(json.dumps(res), status=200, mimetype='application/json') diff --git a/api/data.py b/api/data.py index f140548..629cf53 100644 --- a/api/data.py +++ b/api/data.py @@ -1,5 +1,6 @@ import time import json +from datetime import datetime, time, timedelta from flask import Response, Blueprint, request from firebase_admin import firestore @@ -7,17 +8,19 @@ data = Blueprint('data', __name__) @data.route('/readings/save', methods=['POST']) def uploadReadings(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') + # Check that measurements are provided body = request.json if body is None: resp = {'error': 'Invalid request - please provide a body'} return Response(json.dumps(resp), status=400, mimetype='application/json') - body['timestamp'] = time.time() + body['timestamp'] = datetime.now().timestamp() + # Save all the measurements doc = firestore.client().collection(u'readings').document(deviceId).get() if doc.exists: list = doc.to_dict()['data'] @@ -25,15 +28,15 @@ def uploadReadings(): data = list else: data = [body] - upload = {'data': data} firestore.client().collection(u'readings').document(deviceId).set(upload) + resp = {'success': 'Data saved'} return Response(json.dumps(resp), status=200, mimetype='application/json') @data.route('/readings/getall', methods=['GET']) def getAllReadings(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -46,3 +49,108 @@ def getAllReadings(): results = {'data': data} return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/location/last', methods=['GET']) +def getLastLocation(): + deviceId = request.headers.get('Device-ID') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + data = doc.to_dict()['data'] + lastEntry = data[-1] + lat = lastEntry['latitude'] + lon = lastEntry['longitude'] + else: + lat = -1.0 + lon = -1.0 + + results = {'latitude': lat, 'longitude': lon} + return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/steps/today', methods=['GET']) +def getStepsToday(): + deviceId = request.headers.get('Device-ID') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + data = doc.to_dict()['data'] + lastEntry = data[-1] + steps = lastEntry['cumulative_steps_today'] + else: + steps = 0 + + results = {'cumulative_steps_today': steps} + return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/steps/last-five-days', methods=['GET']) +def getStepsLastFiveDays(): + deviceId = request.headers.get('Device-ID') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + upcomingMidnight = datetime.combine(datetime.today(), time.min) + timedelta(days=1) + doc = firestore.client().collection(u'readings').document(deviceId).get() + + if doc.exists: + data = doc.to_dict()['data'] + listOfDailySteps = [] + + for i in range(0, 5): + found = False + previousMidnight = upcomingMidnight - timedelta(days=1) + print(previousMidnight.timestamp()) + steps = 0 + for reading in reversed(data): + if reading['timestamp'] <= upcomingMidnight.timestamp() and reading['timestamp'] >= previousMidnight.timestamp() and not found: + steps = reading['cumulative_steps_today'] + found = True + listOfDailySteps.append(steps) + upcomingMidnight = previousMidnight + else: + listOfDailySteps = [0] * 5 + + results = {'daily_steps': listOfDailySteps} + return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/metrics-summary', methods=['GET']) +def getMetricsSummary(): + deviceId = request.headers.get('Device-ID') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + upcomingMidnight = datetime.combine(datetime.today(), time.min) + timedelta(days=1) + lastMidnight = datetime.combine(datetime.today(), time.min) + doc = firestore.client().collection(u'readings').document(deviceId).get() + + if doc.exists: + allData = doc.to_dict()['data'] + currentDayData = [x for x in allData if x['timestamp'] <= upcomingMidnight.timestamp() and x['timestamp'] >= lastMidnight.timestamp()] + if len(currentDayData) >= 1: + maxAirTemp = max(currentDayData, key=lambda x: x['air_temp'])['air_temp'] + maxSkinTemp = max(currentDayData, key=lambda x: x['skin_temp'])['skin_temp'] + maxHumidity = max(currentDayData, key=lambda x: x['humidity'])['humidity'] + minAirTemp = min(currentDayData, key=lambda x: x['air_temp'])['air_temp'] + minSkinTemp = min(currentDayData, key=lambda x: x['skin_temp'])['skin_temp'] + minHumidity = min(currentDayData, key=lambda x: x['humidity'])['humidity'] + results = { + 'last_air_temp': currentDayData[-1]['air_temp'], 'min_air_temp': minAirTemp, 'max_air_temp': maxAirTemp, + 'last_skin_temp': currentDayData[-1]['skin_temp'], 'min_skin_temp': minSkinTemp, 'max_skin_temp': maxSkinTemp, + 'last_humidity': currentDayData[-1]['humidity'], 'min_humidity': minHumidity, 'max_humidity': maxHumidity + } + return Response(json.dumps(results), status=200, mimetype='application/json') + else: + return Response(json.dumps({'error': 'Could not get data from database'}), status=500, mimetype='application/json') + else: + return Response(json.dumps({'error': 'Could not get data from database'}), status=500, mimetype='application/json') + + + + diff --git a/lib/utils.py b/lib/utils.py index ba7fbbf..2488e41 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -1,7 +1,7 @@ from random import randint from flask import current_app from flask_mail import Mail, Message -from firebase_admin import auth, firestore +from firebase_admin import firestore def sendMail(subject, sender, recipients, body): mail = Mail(current_app) @@ -24,10 +24,3 @@ def sendVerificationMail(name, email, code): body = '''Hey {}! Thank you for signing up for BarkFinder. In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) sendMail(subject, sender, recipients, body) - -def userLoggedInAndVerfied(token): - # Need frontend to test this - # decoded_token = auth.verify_id_token(token) - # uid = decoded_token['uid'] - # isVerified = auth.get_user(uid).email_verified - return True #placeholder \ No newline at end of file diff --git a/main.py b/main.py index fc5d5fb..779d57e 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,6 @@ app = Flask(__name__) app.register_blueprint(authentication) app.register_blueprint(data) - # Initialize Mail instance app.config['MAIL_SERVER'] = MAIL_SERVER app.config['MAIL_PORT'] = MAIL_PORT