diff --git a/main.py b/main.py index ed5c864..fc80da2 100644 --- a/main.py +++ b/main.py @@ -1,6 +1,4 @@ -""" -Main Flask-based app for Slinky -""" +"""Main Flask-based app for Slinky.""" from flask import Flask, Response, render_template from werkzeug.middleware.proxy_fix import ProxyFix @@ -15,10 +13,10 @@ app.register_blueprint(slinky_webapp) @app.route("/") @protect def index() -> Response: - """ - Index/Landing page + """Index/Landing page. Returns: str: string of page content + """ return Response(render_template("index.html"), 200) diff --git a/slinky/web.py b/slinky/web.py index a9c010a..ff52871 100644 --- a/slinky/web.py +++ b/slinky/web.py @@ -1,12 +1,11 @@ -""" -Web component -""" +"""Web component.""" import logging import os -from datetime import datetime +import pathlib +from datetime import UTC, datetime from functools import wraps -from typing import Any, Callable +from typing import Callable import yaml from flask import Blueprint, Response, render_template, request @@ -18,22 +17,18 @@ from slinky import Slinky, random_string slinky_webapp = Blueprint("webapp", __name__, template_folder="templates") -with open("config.yaml", encoding="utf-8-sig") as conffile: +with pathlib.Path("config.yaml").open(encoding="utf-8-sig") as conffile: cfg = yaml.safe_load(conffile) class DelForm(FlaskForm): - """ - Delete form definition - """ + """Delete form definition.""" delete = HiddenField("delete") class AddForm(FlaskForm): - """ - Add form definition - """ + """Add form definition.""" shortcode = StringField( "Shortcode", @@ -79,18 +74,18 @@ class AddForm(FlaskForm): def protect(func: Callable[..., Response]) -> Callable[..., Response]: - """ - Decorator that will protect the admin interface + """Protect the admin interface. Args: func (Callable): Wrapped function Returns: Callable: Function wrapper + """ @wraps(func) - def check_ip(*args: Any, **kwargs: Any) -> Response: + def check_ip(*args: ..., **kwargs: ...) -> Response: remote_addr = request.remote_addr if "x-forwarded-for" in request.headers: @@ -99,10 +94,7 @@ def protect(func: Callable[..., Response]) -> Callable[..., Response]: if "x-real-ip" in request.headers: remote_addr = request.headers["x-real-ip"] - if ( - os.environ.get("FLASK_ENV", "") != "development" - and remote_addr not in cfg["allowed_ips"] - ): + if os.environ.get("FLASK_ENV", "") != "development" and remote_addr not in cfg["allowed_ips"]: logging.warning("Protected URL access attempt from %s", remote_addr) return Response("Not found", 404) return func(*args, **kwargs) @@ -112,28 +104,32 @@ def protect(func: Callable[..., Response]) -> Callable[..., Response]: @slinky_webapp.route("/", strict_slashes=False) def try_path_as_shortcode(path: str) -> Response: - """ - Try the initial path as a shortcode, redirect if found + """Try the initial path as a shortcode, redirect if found. Returns: Response: redirect if found, otherwise 404 + """ + path = path.strip("/") should_redirect = True slinky = Slinky(cfg["db"]) shortcode = slinky.get_by_shortcode(path) + if shortcode.url: if shortcode.fixed_views == 0: logging.warning("Shortcode out of views") should_redirect = False elif shortcode.fixed_views > 0: slinky.remove_view(shortcode.id) - if datetime.fromisoformat(shortcode.expiry) < datetime.now(): + if datetime.fromisoformat(shortcode.expiry).astimezone(UTC) < datetime.now(UTC): logging.warning("Shortcode expired") should_redirect = False if should_redirect: return Response( - "Redirecting...", status=302, headers={"location": shortcode.url} + "Redirecting...", + status=302, + headers={"location": shortcode.url}, ) return Response("Not found", 404) @@ -142,11 +138,11 @@ def try_path_as_shortcode(path: str) -> Response: @slinky_webapp.route("/_/add", methods=["GET", "POST"]) @protect def add() -> Response: - """ - Create and add a new shorturl + """Create and add a new shorturl. Returns: Response: HTTP response + """ slinky = Slinky(cfg["db"]) @@ -207,11 +203,11 @@ def add() -> Response: @slinky_webapp.route("/_/list", methods=["GET", "POST"]) @protect def lister() -> Response: - """ - List the shortcodes, URLs, etc. + """List the shortcodes, URLs, etc. Returns: Response: HTTP response + """ form = DelForm(meta={"csrf": False}) slinky = Slinky(cfg["db"]) @@ -227,17 +223,17 @@ def lister() -> Response: @slinky_webapp.route("/_/edit/", methods=["GET", "POST"]) @protect -def edit(id: int) -> Response: # pylint: disable=invalid-name,redefined-builtin - """ - Edit the shortcode. +def edit(shortcut_id: int) -> Response: # pylint: disable=invalid-name,redefined-builtin + """Edit the shortcode. Returns: Response: HTTP response + """ form = DelForm(meta={"csrf": False}) slinky = Slinky(cfg["db"]) - logging.debug("Editing: %d", id) + logging.debug("Editing: %d", shortcut_id) if form.is_submitted(): slinky.delete_by_shortcode(form.delete.data.strip())