Skip to content
This repository was archived by the owner on Apr 26, 2023. It is now read-only.

refactoring #1

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 79 additions & 132 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,150 +1,97 @@
from typing import Dict

from os import urandom, getenv
from flask import Flask, render_template, request, redirect
import subprocess
from os import urandom, path
import re


env_file: str = ".env"


def parse_env_file():
_env_values = {}
if path.isfile(env_file):
with open(env_file) as f:
for line in f:
if line.strip().startswith('#'):
continue
key, var = line.partition("=")[::2]
_env_values[key.strip()] = var.strip()
if 'FEEDER_TAR1090_USEROUTEAPI' not in _env_values: _env_values['FEEDER_TAR1090_USEROUTEAPI'] = ''
if 'FEEDER_ULTRAFEEDER_CONFIG' not in _env_values: _env_values['FEEDER_ULTRAFEEDER_CONFIG'] = ''
if 'route' not in _env_values: _env_values['route'] = ''
if 'FEEDER_LAT' in _env_values and float(_env_values['FEEDER_LAT']) != 0.0 and \
'FEEDER_LONG' in _env_values and float(_env_values['FEEDER_LONG']) != 0.0 and \
'FEEDER_ALT' in _env_values and int(_env_values['FEEDER_ALT']) != 0:
_env_values['adv_visible'] = 'visible'
else:
_env_values['adv_visible'] = 'invisible'

return _env_values


# read the .env file and update those mentioned in the Dict passed in (and add those entries that are new)
def modify_env(values: Dict[str, str]):
if not path.isfile(env_file):
# that's not a good sign, but at least let's not throw an error
ef = open(env_file, 'w')
ef.close()
with open(env_file, 'r') as ef:
lines = ef.readlines()
for idx in range(len(lines)):
line = lines[idx]
for key in values.keys():
match = re.search(f"(^[^#]*{key}[^#]*=)[^#]*", line)
if match:
lines[idx] = f"{match.group(1)} {values[key]}\n"
values[key] = '' # so we don't write it a second time at the end
for key in values:
if values[key]:
lines.append(f"{key} = {values[key]}")
with open(env_file, "w") as ef:
ef.writelines(lines)


def restart():
# this really needs to check if we are still waiting for the previous restart
subprocess.call("/usr/bin/systemctl restart adsb-docker", shell=True)

from utils import RESTART, ENV_FILE, NETCONFIGS

app = Flask(__name__)
app.secret_key = urandom(16).hex()


@app.route('/propagateTZ')
@app.route("/propagateTZ")
def get_tz():
browser_timezone = request.args.get("tz")
env_values = parse_env_file()
env_values['FEEDER_TZ'] = browser_timezone
return render_template('index.html', env_values=env_values)
env_values = ENV_FILE.envs
env_values["FEEDER_TZ"] = browser_timezone
return render_template(
"index.html", env_values=env_values, metadata=ENV_FILE.metadata
)


@app.route('/restarting', methods=('GET', 'POST'))
@app.route("/restarting", methods=(["GET"]))
def restarting():
if request.method == 'POST':
restart()
return "done"
if request.method == 'GET':
return render_template('restarting.html', env_values=parse_env_file())
return render_template(
"restarting.html", env_values=ENV_FILE.envs, metadata=ENV_FILE.metadata
)


@app.route("/restart", methods=(["GET", "POST"]))
def restart():
if request.method == "POST":
restart = RESTART.restart_systemd()
return "restarting" if restart else "already restarting"
if request.method == "GET":
return RESTART.state


@app.route('/advanced', methods=('GET', 'POST'))
@app.route("/advanced", methods=("GET", "POST"))
def advanced():
if request.method == 'POST':
if request.form.get('tar1090') == "go":
host, port = request.server
tar1090 = request.url_root.replace(str(port), "8080")
return redirect(tar1090)

# explicitly make these empty
route = 0
net = ''
if request.form.get('route'):
route = '1'
if request.form.get('adsblol'):
if net: net += ';'
net += 'adsb,in.adsb.lol,30004,beast_reduce_plus_out;mlat,in.adsb.lol,31090,39001'
if request.form.get('adsbone'):
if net: net += ';'
net += 'adsb,feed.adsb.one,64004,beast_reduce_plus_out;mlat,feed.adsb.one,64006,39002'
if request.form.get('adsbfi'):
if net: net += ';'
net += 'adsb,feed.adsb.fi,30004,beast_reduce_plus_out;mlat,feed.adsb.fi,31090,39000'
if request.form.get('adsbx'):
if net: net += ';'
net += 'adsb,feed1.adsbexchange.com,30004,beast_reduce_plus_out;mlat,feed.adsbexchange.com,31090,39005'
if request.form.get('tat'):
if net: net += ';'
net += 'adsb,feed.theairtraffic.com,30004,beast_reduce_plus_out;mlat,feed.theairtraffic.com,31090,39004'
if request.form.get('ps'):
if net: net += ';'
net += 'adsb,feed.planespotters.net,30004,beast_reduce_plus_out;mlat,mlat.planespotters.net,31090,39003'
if net == '': # things fail if this variable is empty
net = 'adsb,in.adsb.lol,30004,beast_reduce_plus_out;mlat,in.adsb.lol,31090,39001'

modify_env({'FEEDER_TAR1090_USEROUTEAPI': route,
'FEEDER_ULTRAFEEDER_CONFIG': net})
return redirect('/restarting')
env_values = parse_env_file()
env_values['route'] = 'checked' if env_values['FEEDER_TAR1090_USEROUTEAPI'] == '1' else ''
env_values['adsblol'] = 'checked' if 'adsb.lol' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
env_values['adsbone'] = 'checked' if 'adsb.one' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
env_values['adsbfi'] = 'checked' if 'adsb.fi' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
env_values['adsbx'] = 'checked' if 'adsbexchange' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
env_values['tat'] = 'checked' if 'theairtraffic' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
env_values['ps'] = 'checked' if 'planespotters' in env_values['FEEDER_ULTRAFEEDER_CONFIG'] else ''
return render_template('advanced.html', env_values=env_values)


@app.route('/', methods=('GET', 'POST'))
if request.method == "POST":
return handle_advanced_post_request()
env_values = ENV_FILE.envs
if RESTART.lock.locked():
return redirect("/restarting")
return render_template(
"advanced.html", env_values=env_values, metadata=ENV_FILE.metadata
)


def handle_advanced_post_request():
if request.form.get("tar1090") == "go":
host, port = request.server
tar1090 = request.url_root.replace(str(port), "8080")
return redirect(tar1090)
print("request_form", request.form)

ENV_FILE.update(
{
"FEEDER_TAR1090_USEROUTEAPI": "1" if request.form.get("route") else "0",
"MLAT_PRIVACY": "--privacy" if request.form.get("privacy") else "",
}
)
net = ENV_FILE.generate_ultrafeeder_config(request.form)
ENV_FILE.update({"FEEDER_ULTRAFEEDER_CONFIG": net})
return redirect("/restarting")


@app.route("/", methods=("GET", "POST"))
def setup():
message = ''
if request.args.get("success"):
return redirect("/advanced")
env_values = parse_env_file()
if request.method == 'POST':
lat = request.form['lat']
lng = request.form['lng']
alt = request.form['alt']
form_timezone = request.form['form_timezone']

if lat and lng and alt and form_timezone:
# write local config file
modify_env({'FEEDER_LAT': lat,
'FEEDER_LONG': lng,
'FEEDER_ALT': alt,
'FEEDER_TZ': form_timezone})
return redirect('/restarting')

return render_template('index.html', env_values=env_values, message=message)
if RESTART.lock.locked():
return redirect("/restarting")

if request.method == "POST":
lat, lng, alt, form_timezone, mlat_name = (
request.form[key]
for key in ["lat", "lng", "alt", "form_timezone", "mlat_name"]
)

if all([lat, lng, alt, form_timezone]):
ENV_FILE.update(
{
"FEEDER_LAT": lat,
"FEEDER_LONG": lng,
"FEEDER_ALT_M": alt,
"FEEDER_TZ": form_timezone,
"MLAT_SITE_NAME": mlat_name,
}
)
return redirect("/restarting")

return render_template(
"index.html", env_values=ENV_FILE.envs, metadata=ENV_FILE.metadata
)


if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
2 changes: 2 additions & 0 deletions requirements.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyyaml
flask
22 changes: 22 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#
# This file is autogenerated by pip-compile with Python 3.11
# by the following command:
#
# pip-compile
#
click==8.1.3
# via flask
flask==2.2.3
# via -r requirements.in
itsdangerous==2.1.2
# via flask
jinja2==3.1.2
# via flask
markupsafe==2.1.2
# via
# jinja2
# werkzeug
pyyaml==6.0
# via -r requirements.in
werkzeug==2.2.3
# via flask
18 changes: 10 additions & 8 deletions templates/advanced.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,24 @@ <h1>{% block title %} Setup optional parameters {% endblock %}</h1>
<p>
<form method="post">
<div class="row">
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="route" id="route" {{ env_values['route'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="privacy" id="privacy" {{ metadata['privacy'] }}/>
<label for="privacy" class="mb-3 col-sm-11">Enable privacy flag (ON = does not show on <a href="https://map.adsb.lol/syncmap/">public aggregator maps</a>)</label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="route" id="route" {{ metadata['route'] }}/>
<label for="route" class="mb-3 col-sm-11">Use adsb.lol Route API to show flight routes when known.</label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsblol" id="adsblol" {{ env_values['adsblol'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsblol" id="adsblol" {{ metadata['adsblol'] }}/>
<label for="adsblol" class="mb-3 col-sm-11">Submit your data to <a href="https://adsb.lol/privacy-license/">adsb.lol</a></label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="ps" id="ps" {{ env_values['ps'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="ps" id="ps" {{ metadata['ps'] }}/>
<label for="ps" class="mb-3 col-sm-11">Submit your data to <a href="https://www.planespotters.net/legal/privacypolicy/">planespotters.net</a></label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbone" id="adsbone" {{ env_values['adsbone'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbone" id="adsbone" {{ metadata['adsbone'] }}/>
<label for="adsbone" class="mb-3 col-sm-11">Submit your data to <a href="https://adsb.one/privacy-license/">adsb.one</a> <small>(please note that this site is missing a clear data/privacy policy)</small></label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="tat" id="tat" {{ env_values['tat'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="tat" id="tat" {{ metadata['tat'] }}/>
<label for="tat" class="mb-3 col-sm-11">Submit your data to <a href="https://theairtraffic.com/privacy-license/">TheAirTraffic.com</a> <small>(please note that this site is missing a clear data/privacy policy)</small></label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbfi" id="adsbfi" {{ env_values['adsbfi'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbfi" id="adsbfi" {{ metadata['adsbfi'] }}/>
<label for="adsbfi" class="mb-3 col-sm-11">Submit your data to <a href="https://adsb.fi/">adsb.fi</a> <small>(please note that this site is missing a clear data/privacy policy)</small></label><br/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbx" id="adsbx" {{ env_values['adsbx'] }}/>
<input type="checkbox" style="height: 1.4em;" class="mb-3 col-sm-1" name="adsbx" id="adsbx" {{ metadata['adsbx'] }}/>
<label for="adsbx" class="mb-3 col-sm-11">Submit your data to <a href="https://adsbexchange.com/legal-and-privacy/">ADSBExchange</a> <br/><small>(please note that this site has been aquired by a private equity company with unknown plans for the data submitted; it does, however, provide the best MLAT coverage of all the sites listed)</small></label><br/>
</div>
<div class="form-group {{ env_values['adv_visible'] }}">
<div class="form-group {{ 'visible' if metadata['adv_visible'] else 'invisible' }}">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
<p>{{ message }} </p>
Expand Down
3 changes: 1 addition & 2 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active {{ env_values['adv_visible'] }}">
<li class="nav-item active {{ 'visible' if metadata['adv_visible'] else 'invisible' }}">
<a class="nav-link" href="{{ url_for('advanced') }}">Optional Feature Setup</a>
</li>
</ul>
Expand All @@ -36,4 +36,3 @@
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>

16 changes: 13 additions & 3 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,37 @@
{% block content %}
<h1>{% block title %} Setup required parameters {% endblock %}</h1>

<p>You can use <a href="https://www.freemaptools.com/elevation-finder.htm">this tool</a> to find your lat / long / altitude</p>

</a></p>
<form method="post">
<div class="form-group">
<label for="mlat_name">Station Name (shows up on public maps if enabled later)</label>
<input type="text" name="mlat_name"
required
placeholder="my-awesome-antenna-AMS" class="form-control"
value="{{ env_values['MLAT_SITE_NAME'] }}"></input>
</div>
<div class="form-group">
<label for="lat">Latitude</label>
<input type="text" name="lat"
required
placeholder="Antenna latitude" class="form-control"
value="{{ env_values['FEEDER_READSB_LAT'] }}"></input>
value="{{ env_values['FEEDER_LAT'] }}"></input>
</div>
<div class="form-group">
<label for="lng">Longitude</label>
<input type="text" name="lng"
required
placeholder="Antenna longitude" class="form-control"
value="{{ env_values['FEEDER_READSB_LONG'] }}"></input>
value="{{ env_values['FEEDER_LONG'] }}"></input>
</div>
<div class="form-group">
<label for="alt">Altitude above mean sealevel in meters</label>
<input type="text" name="alt"
required
placeholder="Antenna MSL altitude (in m)" class="form-control"
value="{{ env_values['FEEDER_READSB_ALT'] }}"></input>
value="{{ env_values['FEEDER_ALT_M'] }}"></input>
</div>
<div class="form-group">
<label for="tz">Timzone</label>
Expand Down
Loading