Source code for app.views.public

"""
app.views.public
================
"""

from __future__ import annotations

import typing as t
from datetime import datetime

from flask import (
    Blueprint,
    current_app,
    redirect,
    render_template,
    request,
    send_from_directory,
    url_for,
)
from werkzeug import Response

from app.extensions import sitemap
from app.models import Post, User
from app.views.forms import EmptyForm

blueprint = Blueprint("public", __name__)


[docs] @blueprint.route("/", methods=["GET", "POST"]) def index() -> str: """App's index page. The index will show all the posts with the most recent first. ``JOIN`` is used so that the author information from the user table is available in the result. :return: Rendered index template. """ page = request.args.get("page", 1, type=int) # noinspection PyUnresolvedReferences query = Post.query.order_by(Post.created.desc()) posts = query.paginate( page=page, per_page=current_app.config["POSTS_PER_PAGE"], error_out=False, ) return render_template( "public/index.html", posts=posts.items, next_url=( url_for("index", page=posts.next_num) if posts.has_next else None ), prev_url=( url_for("index", page=posts.prev_num) if posts.has_prev else None ), )
[docs] @sitemap.register_generator def sitemap_index() -> ( t.Generator[tuple[str, dict[str, t.Any], datetime, str, float], None, None] ): """Add index to sitemap. :return: Generator yielding data for sitemap. """ yield ( "index", {}, datetime.now(), current_app.config["SITEMAP_CHANGEFREQ"], 0.7, )
[docs] @blueprint.route("/profile/<username>", methods=["GET", "POST"]) def profile(username: str) -> str | Response: """Render user's profile page. :param username: Username of registered user. :return: Rendered profile template. """ user = User.resolve_all_names(username=username) if user.username != username: return redirect(url_for("public.profile", username=user.username)) form = EmptyForm() user = User.query.filter_by(username=username).first() page = request.args.get("page", 1, type=int) # noinspection PyUnresolvedReferences query = user.posts.order_by(Post.created.desc()) posts = query.paginate( page=page, per_page=current_app.config["POSTS_PER_PAGE"], error_out=False, ) return render_template( "public/profile.html", posts=posts.items, username=username, user=user, form=form, next_url=( url_for("public.profile", username=username, page=posts.next_num) if posts.has_next else None ), prev_url=( url_for("public.profile", username=username, page=posts.prev_num) if posts.has_prev else None ), )
[docs] @sitemap.register_generator def sitemap_user() -> ( t.Generator[tuple[str, dict[str, t.Any], datetime, str, float], None, None] ): """Generate user URLs for sitemap. :return: Generator yielding data for sitemap. """ users = User.query.all() for user in users: if user.authorized: yield ( "public.profile", {"username": user.username}, datetime.now(), current_app.config["SITEMAP_CHANGEFREQ"], 0.7, )
[docs] @blueprint.route("/favicon.ico") def favicon() -> Response: """Endpoint for the app's favicon. :return: Response object. """ path = current_app.config["UPLOAD_PATH"] / "favicon.ico" return send_from_directory( path.parent if path.is_file() else path.parent.parent, path.name, mimetype="image/vnd.microsoft.icon", )