forked from purplebored/purplebored.pl
97
src/pbpl/views/home.py
Normal file
97
src/pbpl/views/home.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Home routes"""
|
||||
|
||||
import typing as t
|
||||
|
||||
import flask
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
import pbpl.forms.prow as form_pow
|
||||
import pbpl.forms.text as text_form
|
||||
from pbpl.db import db
|
||||
from pbpl.models import TextModel
|
||||
|
||||
from .bp import Bp
|
||||
|
||||
home: Bp = Bp("home", __name__)
|
||||
|
||||
__all__: t.Tuple[str] = ("home",)
|
||||
|
||||
|
||||
@home.get("/", ishtml=True)
|
||||
@home.csp("img-src $self; script-src $internal $wasm; style-src $internal; form-action $self; connect-src $self; manifest-src $self")
|
||||
def index() -> str:
|
||||
"""Home page"""
|
||||
|
||||
nonce: str = form_pow.proof_of_work_protect_session("home.index/text")
|
||||
|
||||
return flask.render_template(
|
||||
"home/index.j2",
|
||||
form=text_form.TextForm(),
|
||||
texts=TextModel.query.all(),
|
||||
pow_nonce=nonce,
|
||||
)
|
||||
|
||||
|
||||
@home.post("/")
|
||||
@home.csp("img-src $self; script-src $internal; style-src $internal")
|
||||
def text() -> Response:
|
||||
"""Post some text"""
|
||||
|
||||
form: text_form.FlaskForm = text_form.TextForm()
|
||||
|
||||
if not form.validate_on_submit(): # type: ignore
|
||||
flask.flash("Invalid form data/form", "error")
|
||||
flask.abort(400)
|
||||
|
||||
if form.text.data is None:
|
||||
flask.flash("Invalid form text", "error")
|
||||
flask.abort(400)
|
||||
|
||||
if form.pow_solution.data is None or not form_pow.proof_of_work_verify_session(
|
||||
"home.index/text",
|
||||
form.pow_solution.data,
|
||||
):
|
||||
flask.flash("Invalid Proof-of-Work solution", "error")
|
||||
flask.abort(403)
|
||||
|
||||
db.session.add(TextModel(text=form.text.data))
|
||||
db.session.commit()
|
||||
|
||||
flask.flash("Your text has been saved")
|
||||
return flask.redirect(flask.url_for("home.index"))
|
||||
|
||||
|
||||
@home.get("/manifest.json")
|
||||
@home.csp("manifest-src $self; img-src $self")
|
||||
@home.cache("30d")
|
||||
def manifest() -> t.Any:
|
||||
"""Manifest file"""
|
||||
return flask.jsonify( # type: ignore
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/web-manifest-combined.json",
|
||||
"short_name": "Example page",
|
||||
"name": "Example page",
|
||||
"description": "This is an example description",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicon.ico",
|
||||
"sizes": "256x256",
|
||||
"type": "image/vnd.microsoft.icon",
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#fbfbfb",
|
||||
"background_color": "#121212",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@home.get("/favicon.ico")
|
||||
@home.csp("img-src $self")
|
||||
@home.cache("30d")
|
||||
def favicon() -> Response:
|
||||
"""Website icon"""
|
||||
return flask.send_from_directory("static", "favicon.ico")
|
||||
Reference in New Issue
Block a user