2024-02-11 03:03:23 +00:00
|
|
|
"""
|
|
|
|
@file api.py
|
|
|
|
@brief API for 3lips.
|
|
|
|
@author 30hours
|
|
|
|
"""
|
2024-02-01 14:50:24 +00:00
|
|
|
|
2024-02-05 13:43:59 +00:00
|
|
|
from flask import Flask, Response, render_template, request, redirect, jsonify, send_from_directory
|
2024-02-01 14:50:24 +00:00
|
|
|
import os
|
2024-02-05 13:43:59 +00:00
|
|
|
import requests
|
2024-02-09 08:50:13 +00:00
|
|
|
import time
|
2024-02-09 14:47:13 +00:00
|
|
|
import asyncio
|
2024-03-17 07:56:53 +00:00
|
|
|
import yaml
|
2024-02-09 08:50:13 +00:00
|
|
|
|
2024-02-09 14:47:13 +00:00
|
|
|
from common.Message import Message
|
2024-02-01 14:50:24 +00:00
|
|
|
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
2024-03-17 07:56:53 +00:00
|
|
|
# init config file
|
|
|
|
try:
|
2024-03-18 10:55:12 +00:00
|
|
|
with open('config/config.yml', 'r') as file:
|
|
|
|
config = yaml.safe_load(file)
|
|
|
|
radar_data = config['radar']
|
2024-03-26 12:43:20 +00:00
|
|
|
map_data = config['map']
|
|
|
|
config_data = config
|
2024-03-17 07:56:53 +00:00
|
|
|
except FileNotFoundError:
|
2024-03-18 10:55:12 +00:00
|
|
|
print("Error: Configuration file not found.")
|
2024-03-17 07:56:53 +00:00
|
|
|
except yaml.YAMLError as e:
|
2024-03-18 10:55:12 +00:00
|
|
|
print("Error reading YAML configuration:", e)
|
2024-03-17 07:56:53 +00:00
|
|
|
|
2024-02-01 14:50:24 +00:00
|
|
|
# store state data
|
2024-03-17 07:56:53 +00:00
|
|
|
servers = []
|
|
|
|
for radar in radar_data:
|
|
|
|
if radar['name'] and radar['url']:
|
|
|
|
servers.append({'name': radar['name'], 'url': radar['url']})
|
|
|
|
|
2024-02-01 14:50:24 +00:00
|
|
|
associators = [
|
|
|
|
{"name": "ADSB Associator", "id": "adsb-associator"}
|
|
|
|
]
|
2024-03-17 07:56:53 +00:00
|
|
|
|
2024-03-05 11:51:07 +00:00
|
|
|
localisations = [
|
2024-03-14 01:05:15 +00:00
|
|
|
{"name": "Ellipse Parametric (Mean)", "id": "ellipse-parametric-mean"},
|
|
|
|
{"name": "Ellipse Parametric (Min)", "id": "ellipse-parametric-min"},
|
|
|
|
{"name": "Ellipsoid Parametric (Mean)", "id": "ellipsoid-parametric-mean"},
|
|
|
|
{"name": "Ellipsoid Parametric (Min)", "id": "ellipsoid-parametric-min"},
|
2024-03-10 08:51:58 +00:00
|
|
|
{"name": "Spherical Intersection", "id": "spherical-intersection"}
|
2024-02-04 10:47:40 +00:00
|
|
|
]
|
2024-03-17 07:56:53 +00:00
|
|
|
|
2024-02-04 10:47:40 +00:00
|
|
|
adsbs = [
|
2024-03-26 12:43:20 +00:00
|
|
|
{"name": map_data['tar1090'], "url": map_data['tar1090']},
|
2024-02-04 10:47:40 +00:00
|
|
|
{"name": "None", "url": ""}
|
2024-02-01 14:50:24 +00:00
|
|
|
]
|
|
|
|
|
2024-03-17 07:56:53 +00:00
|
|
|
# store valid ids
|
|
|
|
valid = {}
|
|
|
|
valid['servers'] = [item['url'] for item in servers]
|
|
|
|
valid['associators'] = [item['id'] for item in associators]
|
|
|
|
valid['localisations'] = [item['id'] for item in localisations]
|
|
|
|
valid['adsbs'] = [item['url'] for item in adsbs]
|
|
|
|
|
2024-02-10 02:18:08 +00:00
|
|
|
# message received callback
|
|
|
|
async def callback_message_received(msg):
|
2024-03-18 10:55:12 +00:00
|
|
|
print(f"Callback: Received message in main.py: {msg}", flush=True)
|
2024-02-10 02:18:08 +00:00
|
|
|
|
2024-02-09 14:47:13 +00:00
|
|
|
# init messaging
|
2024-02-10 02:18:08 +00:00
|
|
|
message_api_request = Message('event', 6969)
|
2024-02-09 14:47:13 +00:00
|
|
|
|
2024-02-01 14:50:24 +00:00
|
|
|
@app.route("/")
|
|
|
|
def index():
|
2024-03-18 10:55:12 +00:00
|
|
|
return render_template("index.html", servers=servers, \
|
|
|
|
associators=associators, localisations=localisations, adsbs=adsbs)
|
2024-02-01 14:50:24 +00:00
|
|
|
|
|
|
|
# serve static files from the /app/public folder
|
|
|
|
@app.route('/public/<path:file>')
|
|
|
|
def serve_static(file):
|
2024-03-18 10:55:12 +00:00
|
|
|
base_dir = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
public_folder = os.path.join(base_dir, 'public')
|
|
|
|
return send_from_directory(public_folder, file)
|
2024-02-01 14:50:24 +00:00
|
|
|
|
|
|
|
@app.route("/api")
|
|
|
|
def api():
|
2024-03-18 10:55:12 +00:00
|
|
|
api = request.query_string.decode('utf-8')
|
|
|
|
# input protection
|
|
|
|
servers_api = request.args.getlist('server')
|
|
|
|
associators_api = request.args.getlist('associator')
|
|
|
|
localisations_api = request.args.getlist('localisation')
|
|
|
|
adsbs_api = request.args.getlist('adsb')
|
|
|
|
if not all(item in valid['servers'] for item in servers_api):
|
|
|
|
return 'Invalid server'
|
|
|
|
if not all(item in valid['associators'] for item in associators_api):
|
|
|
|
return 'Invalid associator'
|
|
|
|
if not all(item in valid['localisations'] for item in localisations_api):
|
|
|
|
return 'Invalid localisation'
|
|
|
|
if not all(item in valid['adsbs'] for item in adsbs_api):
|
|
|
|
return 'Invalid ADSB'
|
|
|
|
# send to event handler
|
|
|
|
try:
|
|
|
|
reply_chunks = message_api_request.send_message(api)
|
|
|
|
reply = ''.join(reply_chunks)
|
|
|
|
print(reply, flush=True)
|
|
|
|
return reply
|
|
|
|
except Exception as e:
|
|
|
|
reply = "Exception: " + str(e)
|
|
|
|
return jsonify(error=reply), 500
|
2024-02-01 14:50:24 +00:00
|
|
|
|
2024-02-04 12:08:48 +00:00
|
|
|
@app.route("/map/<path:file>")
|
|
|
|
def serve_map(file):
|
2024-03-18 10:55:12 +00:00
|
|
|
base_dir = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
public_folder = os.path.join(base_dir, 'map')
|
|
|
|
return send_from_directory(public_folder, file)
|
2024-02-01 14:50:24 +00:00
|
|
|
|
2024-02-09 08:50:13 +00:00
|
|
|
# handle /cesium/ specifically
|
2024-02-05 13:43:59 +00:00
|
|
|
@app.route('/cesium/')
|
|
|
|
def serve_cesium_index():
|
2024-03-18 10:55:12 +00:00
|
|
|
return redirect('/cesium/index.html')
|
2024-02-05 13:43:59 +00:00
|
|
|
|
|
|
|
@app.route('/cesium/<path:file>')
|
|
|
|
def serve_cesium_content(file):
|
2024-03-18 10:55:12 +00:00
|
|
|
apache_url = 'http://cesium-apache/' + file
|
|
|
|
try:
|
|
|
|
response = requests.get(apache_url)
|
|
|
|
if response.status_code == 200:
|
|
|
|
return Response(response.content, content_type=response.headers['content-type'])
|
|
|
|
response.raise_for_status()
|
|
|
|
except requests.exceptions.RequestException as e:
|
|
|
|
print(f"Error fetching content from Apache server: {e}")
|
|
|
|
return Response('Error fetching content from Apache server', status=500, content_type='text/plain')
|
2024-02-05 13:43:59 +00:00
|
|
|
|
2024-03-26 12:43:20 +00:00
|
|
|
# output config file
|
|
|
|
@app.route('/config')
|
|
|
|
def config():
|
|
|
|
return config_data
|
|
|
|
|
2024-02-01 14:50:24 +00:00
|
|
|
if __name__ == "__main__":
|
2024-03-18 10:55:12 +00:00
|
|
|
app.run()
|