forum/api/api.py

133 lines
4.6 KiB
Python

from http import HTTPStatus
from flask import Flask, Response, config, json, jsonify, request, request_started
from uuid import uuid4
import sqlite3
import numbers
from flask import g
import open3d
import numpy
DATABASE = './forum.db'
TERRAIN_MODEL = './terrain.glb'
def get_db():
db = getattr(g, '__database', None)
if db is None:
db = g.__database = sqlite3.connect(DATABASE)
return db
app = Flask(__name__)
terrain_mesh = open3d.io.read_triangle_mesh('./terrain.glb')
terrain_mesh = open3d.t.geometry.TriangleMesh.from_legacy(terrain_mesh)
print('loaded terrain mesh')
scene = open3d.t.geometry.RaycastingScene()
_ = scene.add_triangles(terrain_mesh)
print('created raycasting scene')
@app.teardown_appcontext
def close_connection(_):
db = getattr(g, '__database', None)
if db is not None:
db.close()
print("Connected to SQLite database")
@app.route('/api/message')
def get_messages():
cur = get_db().cursor()
res = cur.execute("SELECT message_id, position, message FROM message")
messages = jsonify(list(map(lambda m: {'message_id': m[0], 'position': json.loads(m[1]), 'message': m[2]}, res.fetchall())))
return messages
@app.route('/api/new_message', methods=['POST'])
def new_message():
db = get_db()
cur = db.cursor()
position = list(json.loads(request.form['position']))
if len(position) != 3:
return Response(status=HTTPStatus.BAD_REQUEST)
for elem in position:
if not isinstance(elem, numbers.Number):
return Response(status=HTTPStatus.BAD_REQUEST)
query_point = open3d.core.Tensor([position], dtype=open3d.core.Dtype.Float32)
unsigned_distance = scene.compute_distance(query_point)
print(unsigned_distance)
if unsigned_distance > 0.25:
return Response(status=HTTPStatus.BAD_REQUEST)
position = json.dumps(position)
message = str(request.form['message'])
token = request.form['token']
res = cur.execute(f"SELECT user_id FROM user WHERE token='{token}'")
res = res.fetchone()
if res is not None:
(user_id,) = res
id = str(uuid4())
cur.execute("INSERT INTO message VALUES(?, ?, ?, ?)", (id, user_id, position, message));
db.commit()
return Response(status=HTTPStatus.NO_CONTENT)
else:
return Response(status=HTTPStatus.BAD_REQUEST)
@app.route('/api/gen_token')
def gen_token():
db = get_db()
cur = db.cursor()
id = str(uuid4())
token = str(uuid4())
cur.execute("INSERT INTO user VALUES(?, ?)", (id, token));
db.commit()
return { 'token': token }
@app.route('/api/remove_message', methods=['DELETE'])
def remove_message():
db = get_db()
cur = db.cursor()
token = request.form['token']
message_id = request.form['message_id']
res = cur.execute("SELECT user_id FROM user WHERE token= ?", (token,))
res = res.fetchone()
if res is not None:
(user_id,) = res
res = cur.execute("SELECT message_id, user_id FROM message WHERE message_id= ?", (message_id,))
res = res.fetchone()
if res is not None:
(message_id, message_user_id) = res
if message_user_id == user_id:
cur.execute("DELETE FROM message WHERE message_id= ?", (message_id,))
db.commit()
return Response(status=HTTPStatus.NO_CONTENT)
else:
return Response(status=HTTPStatus.UNAUTHORIZED)
else:
return Response(status=HTTPStatus.BAD_REQUEST)
else:
return Response(status=HTTPStatus.BAD_REQUEST)
@app.route('/api/edit_message', methods=['PUT'])
def edit_message():
db = get_db()
cur = db.cursor()
token = request.form['token']
message_id = request.form['message_id']
new_message = request.form['message']
res = cur.execute("SELECT user_id FROM user WHERE token = ?", (token,))
res = res.fetchone()
if res is not None and new_message is not None:
(user_id,) = res
res = cur.execute("SELECT message_id, user_id FROM message WHERE message_id= ?", (message_id,))
res = res.fetchone()
if res is not None:
(message_id, message_user_id) = res
if message_user_id == user_id:
cur.execute("UPDATE message SET message = ? WHERE message_id= ?", (new_message, message_id));
db.commit()
return Response(status=HTTPStatus.NO_CONTENT)
else:
return Response(status=HTTPStatus.UNAUTHORIZED)
else:
return Response(status=HTTPStatus.BAD_REQUEST)
else:
return Response(status=HTTPStatus.BAD_REQUEST)