from flask import Flask, send_file, redirect, render_template import threading import requests import tomllib import logging import time with open("config.toml", "rb") as f: config = tomllib.load(f) app = Flask("velping") logging.disable(logging.CRITICAL) uptime = {} def http_ping(service): while True: print(f"[I] Pinging {service}") try: resp = requests.get(config["services"][service]) resp.raise_for_status() if ( uptime[service][config["frontend"]["pings"] - 1] != "I" and config["ntfy"]["enabled"] ): requests.post( f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}", data=f"Service {service} is online", ) uptime[service].pop(0) uptime[service].append("I") print(f"[I] Pinging {service} worked!") except Exception as e: if ( "Remote end closed connection without response" in str(e) and config["pinging"]["allow_empty_responses"] ): uptime[service].pop(0) uptime[service].append("I") print(f"[I] Pinging {service} worked!") else: if ( uptime[service][config["frontend"]["pings"] - 1] != "O" and config["ntfy"]["enabled"] ): requests.post( f"https://{config['ntfy']['server']}/{config['ntfy']['topic']}", data=f"Service {service} is offline", ) uptime[service].pop(0) uptime[service].append("O") print(f"[E] An error happened while pinging for {service}: {e}") time.sleep(config["pinging"]["seconds_between_ping"]) for service in config["services"]: uptime[service] = [] for _ in range(config["frontend"]["pings"]): uptime[service].append("?") threading.Thread( target=http_ping, args=(service,), ).start() @app.errorhandler(404) def not_found(error): return redirect("/", 308) @app.errorhandler(500) def internal_error(error): return render_template( "internal_error.xht", config=config, ), 500 @app.route("/style.css") def css(): return send_file("assets/style.css") @app.route("/") def root(): return render_template( "index.xht", config=config, services=config["services"], uptime=uptime, ), 200 app.run( port=config["frontend"]["port"], host="::", )