Source code for dyndns.webapp

"""Initialize the Flask app."""

from __future__ import annotations

import inspect

import flask

from dyndns.config import get_config
from dyndns.dns_updates import catch_errors, delete_dns_record, update_dns_record
from dyndns.html_template import RestructuredText, template_base, template_usage
from dyndns.log import Update, UpdatesDB, msg

app = flask.Flask(__name__)


[docs] @app.route("/update-by-path/<secret>/<fqdn>") @app.route("/update-by-path/<secret>/<fqdn>/<ip_1>") @app.route("/update-by-path/<secret>/<fqdn>/<ip_1>/<ip_2>") def update_by_path( secret: str, fqdn: str, ip_1: str | None = None, ip_2: str | None = None ) -> str: return catch_errors( update_dns_record, secret=secret, fqdn=fqdn, ip_1=ip_1, ip_2=ip_2 )
[docs] @app.route("/update-by-query") def update_by_query_string() -> str: args = flask.request.args # Returns ImmutableMultiDict([('secret', '12345678'), ...]) # dict(args): # {'secret': ['12345678'], kwargs = inspect.getfullargspec(update_dns_record).args input_args = {} for key, arg in args.items(): input_args[key] = arg if key not in kwargs: return msg( 'Unknown query string argument: "{}"'.format(key), "PARAMETER_ERROR", ) return catch_errors(update_dns_record, **input_args)
[docs] @app.route("/delete-by-path/<secret>/<fqdn>") def delete_by_path(secret: str, fqdn: str) -> str: return catch_errors(delete_dns_record, secret=secret, fqdn=fqdn)
[docs] @app.route("/") def home(): config = False try: config = get_config() except Exception: pass if not config: configuration = RestructuredText.read_to_html("configuration.rst") else: configuration = "" content = flask.render_template( "home.html", usage=template_usage(), configuration=configuration, about=RestructuredText.read_to_html("about.rst"), ) return template_base("dyndns", content)
[docs] @app.route("/about") def about() -> str: return template_base( "About", RestructuredText.read_to_html("about.rst", remove_heading=True), )
[docs] @app.route("/docs/installation") def docs_installation() -> str: return template_base( "Installation", RestructuredText.read_to_html("installation.rst", remove_heading=True), )
[docs] @app.route("/docs/configuration") def docs_configuration() -> str: return template_base( "Configuration", RestructuredText.read_to_html("configuration.rst", remove_heading=True), )
[docs] @app.route("/docs/usage") def docs_usage() -> str: return template_base("Usage", template_usage(remove_heading=True))
[docs] @app.route("/statistics/updates-by-fqdn") def statistics_updates_by_fqdn() -> str: db = UpdatesDB() out: list[str] = [] for fqdn in db.get_fqdns(): rows = db.get_updates_by_fqdn(fqdn) table: str = flask.render_template( "table-updates-by-fqdn.html", fqdn=fqdn, rows=rows ) out.append(table) return template_base("Updates by FQDN", "\n".join(out))
[docs] @app.route("/statistics/latest-submissions") def statistics_latest_submissions() -> str: db = UpdatesDB() results: list[Update] = [] db.cursor.execute("SELECT * FROM updates ORDER BY update_time DESC " "LIMIT 50;") rows = db.cursor.fetchall() for row in rows: results.append(db.normalize_row(row)) content: str = flask.render_template("table-latest-submissions.html", rows=results) return template_base("Latest submissions", content)
if __name__ == "__main__": app.run()