89 lines
2.6 KiB
Python
89 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""ButtonTask v2 web configurator (Flask).
|
|
|
|
Application factory that wires together the modular blueprints:
|
|
- auth : login / logout / session
|
|
- api : buttons, layout, background, feedback, settings, icons
|
|
- network : Ethernet configuration via nmcli
|
|
- updater : OTA software update with rollback
|
|
|
|
Reads/writes the same JSON config used by the Qt5 application.
|
|
"""
|
|
import os
|
|
import time
|
|
|
|
from flask import Flask, g, jsonify, render_template, request
|
|
|
|
from api import api_bp
|
|
from auth import auth_bp, load_or_create_secret, login_required
|
|
from config_store import list_icons, load_config
|
|
from network import network_bp
|
|
from system_info import apply_saved_brightness, record_request, system_bp
|
|
from updater import current_version, updater_bp
|
|
|
|
|
|
def create_app():
|
|
app = Flask(__name__, template_folder="templates", static_folder="static")
|
|
app.secret_key = load_or_create_secret()
|
|
app.config.update(
|
|
SESSION_COOKIE_HTTPONLY=True,
|
|
SESSION_COOKIE_SAMESITE="Lax",
|
|
PERMANENT_SESSION_LIFETIME=60 * 60 * 8, # 8 hours
|
|
MAX_CONTENT_LENGTH=512 * 1024 * 1024, # 512 MB upload cap (OTA packages)
|
|
)
|
|
|
|
app.register_blueprint(auth_bp)
|
|
app.register_blueprint(api_bp)
|
|
app.register_blueprint(network_bp)
|
|
app.register_blueprint(updater_bp)
|
|
app.register_blueprint(system_bp)
|
|
|
|
# Restore LCD brightness from config (best-effort; needs bt-brightness + sudoers).
|
|
apply_saved_brightness()
|
|
|
|
@app.before_request
|
|
def _request_start():
|
|
g._req_start = time.time()
|
|
|
|
@app.after_request
|
|
def _request_log(response):
|
|
started = getattr(g, "_req_start", None)
|
|
if started is not None:
|
|
record_request(
|
|
request.method,
|
|
request.path,
|
|
response.status_code,
|
|
(time.time() - started) * 1000.0,
|
|
request.remote_addr or "",
|
|
)
|
|
return response
|
|
|
|
@app.route("/")
|
|
@login_required
|
|
def index():
|
|
cfg = load_config()
|
|
return render_template("index.html", config=cfg, icons=list_icons(),
|
|
version=current_version())
|
|
|
|
@app.route("/healthz")
|
|
def healthz():
|
|
# Unauthenticated, lightweight: used by the OTA health-check.
|
|
return jsonify({"ok": True, "ts": time.time(),
|
|
"version": current_version().get("version")})
|
|
|
|
return app
|
|
|
|
|
|
app = create_app()
|
|
|
|
|
|
def main():
|
|
cfg = load_config()
|
|
port = int(cfg.get("settings", {}).get("webPort", 8080))
|
|
host = os.environ.get("BUTTONTASK_HOST", "0.0.0.0")
|
|
app.run(host=host, port=port, debug=False)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|