server/fgs/views.py

108 lines
3.5 KiB
Python

from . import app, db
from .flatten import flatten, unflatten
from .jwt import jwt_required
from .model import *
from flask import g, jsonify, request, abort
from sqlalchemy import func
from geopy.distance import geodesic
from datetime import datetime, timedelta
@app.route('/')
def index():
return 'Hello, world!'
@app.route('/login', methods=['POST'])
def login():
username = request.form.get('username')
password = request.form.get('password')
if username is None or password is None: abort(400)
user = User.query.filter_by(username=username).first()
if user is None or not user.check_password(password): abort(400)
return jsonify({ 'token': user.get_jwt().decode() })
@app.route('/me')
@jwt_required
def me():
return jsonify({ 'username' : g.user.username })
@app.route('/collars')
@jwt_required
def collars():
active_collars = []
for collar in Collar.query.filter_by(active=True).all():
max_point = DataPoint.query.filter_by(collar_id=collar.id).\
order_by(DataPoint.datetime.desc()).\
first()
active_collars.append(
{'id': collar.id, 'name': collar.name, 'pos':
{'longitude': max_point.longitude, 'latitude': max_point.latitude}}
)
return jsonify(active_collars)
@app.route('/collars/stats/distance')
@jwt_required
def collars_distance():
active_collars = []
for collar in Collar.query.filter_by(active=True).all():
coords = DataPoint.query.filter_by(collar_id=collar.id).\
order_by(DataPoint.datetime.desc())
distance_kilometers = 0
coords_pairs = list(map(lambda e : (e.longitude, e.latitude), coords))
if len(coords_pairs) < 1: continue
coord_last = coords_pairs.pop(0)
for coord in coords_pairs:
distance_kilometers += geodesic(coord_last,coord).km
coord_last = coord
active_collars.append(
{'id': collar.id, 'name': collar.name,
'distance': distance_kilometers }
)
return jsonify(active_collars)
@app.route('/collars/<int:id>/history')
@jwt_required
def collar_history(id):
collar = Collar.query.filter_by(id=id).first()
if collar is None: abort(404)
data_points = DataPoint.query.\
filter_by(collar_id=id).\
order_by(DataPoint.datetime.desc()).\
all()
return jsonify([point.to_dict() for point in data_points])
@app.route('/collars/<int:id>/details')
@jwt_required
def collar_detail(id):
collar = Collar.query.filter_by(id=id).first()
if collar is None: abort(404)
# get stimulus activation reports from within last 24 hours
since = datetime.now() - timedelta(hours=24)
stimulus_points = StimulusActivation.query.\
filter_by(collar_id=id).\
filter(StimulusActivation.datetime < since).\
order_by(StimulusActivation.datetime.desc())
n_stimulus = stimulus_points.count()
return jsonify({'id': collar.id, 'name': collar.name, 'stimilus': n_stimulus, 'boundary': unflatten(collar.boundary) })
@app.route('/collars/<int:id>/boundary/set', methods=['POST'])
@jwt_required
def collar_set_boundary(id):
collar = Collar.query.filter_by(id=id).first()
if collar is None: abort(404)
new_boundary = flatten(request.json)
if collar.boundary is not None:
db.session.delete(collar.boundary)
collar.boundary = new_boundary
db.session.add(new_boundary)
db.session.commit()
return jsonify({})