337 lines
11 KiB
Python
Raw Normal View History

2023-06-20 15:13:08 +03:00
from datetime import datetime
2023-06-02 10:08:33 +03:00
from flask import render_template, flash, redirect, url_for, request
2023-05-17 19:21:53 +03:00
from flask_login import login_required, current_user
2023-06-15 12:52:51 +03:00
from sqlalchemy import and_, or_, func, distinct
2023-05-17 19:21:53 +03:00
from app.controllers import (
register_book_verify_route,
)
from app.controllers.tags import (
set_book_tags,
)
2023-05-17 19:21:53 +03:00
from app.controllers.delete_nested_book_entities import (
delete_nested_book_entities,
)
2023-05-25 10:10:22 +03:00
from app.controllers.create_access_groups import (
create_editor_group,
create_moderator_group,
)
from app.controllers.require_permission import require_permission
2023-06-14 17:17:43 +03:00
from app.controllers.sorting import sort_by
from app.controllers.error_flashes import create_error_flash
2023-05-17 19:21:53 +03:00
from app import models as m, db, forms as f
from app.logger import log
from .bp import bp
2023-05-22 11:32:06 +03:00
@bp.route("/my_library", methods=["GET"])
2023-05-17 19:21:53 +03:00
def my_library():
if current_user.is_authenticated:
2023-05-26 16:56:04 +03:00
log(log.INFO, "Create query for my_library page for books")
2023-06-14 17:17:43 +03:00
sort = request.args.get("sort")
2023-05-26 16:56:04 +03:00
books: m.Book = (
2023-06-14 17:17:43 +03:00
db.session.query(
m.Book,
m.Book.created_at.label("created_at"),
2023-06-15 12:52:51 +03:00
func.count(distinct(m.Interpretation.id)).label(
"interpretations_count"
),
func.count(distinct(m.BookStar.id)).label("stars_count"),
2023-06-14 17:17:43 +03:00
)
.join(
2023-06-15 09:51:35 +03:00
m.BookStar,
and_(
m.BookStar.book_id == m.Book.id,
m.BookStar.is_deleted == False, # noqa: E712
),
full=True,
)
.join(
m.BookVersion,
and_(
m.BookVersion.book_id == m.Book.id,
m.BookVersion.is_deleted == False, # noqa: E712
),
2023-06-15 12:52:51 +03:00
full=True,
2023-06-15 09:51:35 +03:00
)
.join(
m.Section,
and_(
m.BookVersion.id == m.Section.version_id,
m.Section.is_deleted == False, # noqa: E712
),
full=True,
)
.join(
m.Interpretation,
and_(
m.Interpretation.section_id == m.Section.id,
m.Interpretation.is_deleted == False, # noqa: E712
),
full=True,
2023-06-14 17:17:43 +03:00
)
.join(m.BookContributor, m.BookContributor.book_id == m.Book.id, full=True)
.filter(
or_(
m.Book.user_id == current_user.id,
m.BookContributor.user_id == current_user.id,
),
m.Book.is_deleted == False, # noqa: E712
)
.group_by(m.Book.id)
)
2023-06-14 17:17:43 +03:00
pagination, books = sort_by(books, sort)
2023-05-26 16:56:04 +03:00
log(log.INFO, "Returns data for front end")
2023-05-17 19:21:53 +03:00
return render_template(
2023-05-22 11:32:06 +03:00
"book/my_library.html",
2023-06-14 17:17:43 +03:00
books=books,
2023-05-17 19:21:53 +03:00
page=pagination,
)
2023-05-26 16:56:04 +03:00
log(log.INFO, "Returns data for front end is user is anonym")
2023-05-17 19:21:53 +03:00
return render_template(
2023-05-22 11:32:06 +03:00
"book/my_library.html",
2023-05-17 19:21:53 +03:00
books=[],
)
@bp.route("/create", methods=["POST"])
@login_required
def create():
form = f.CreateBookForm()
if form.validate_on_submit():
book: m.Book = m.Book(
label=form.label.data, about=form.about.data, user_id=current_user.id
)
2023-05-17 19:21:53 +03:00
log(log.INFO, "Form submitted. Book: [%s]", book)
book.save()
2023-06-12 15:18:21 +03:00
version = m.BookVersion(semver="Active", book_id=book.id, is_active=True).save()
2023-05-25 10:10:22 +03:00
root_collection = m.Collection(
2023-05-17 19:21:53 +03:00
label="Root Collection", version_id=version.id, is_root=True
).save()
2023-05-26 10:14:21 +03:00
tags = form.tags.data or ""
set_book_tags(book, tags)
2023-05-17 19:21:53 +03:00
2023-05-25 10:10:22 +03:00
# access groups
editor_access_group = create_editor_group(book_id=book.id)
moderator_access_group = create_moderator_group(book_id=book.id)
access_groups = [editor_access_group, moderator_access_group]
for access_group in access_groups:
m.BookAccessGroups(book_id=book.id, access_group_id=access_group.id).save()
m.CollectionAccessGroups(
collection_id=root_collection.id, access_group_id=access_group.id
).save()
# -------------
2023-05-17 19:21:53 +03:00
flash("Book added!", "success")
return redirect(url_for("book.my_library"))
else:
log(log.ERROR, "Book create errors: [%s]", form.errors)
create_error_flash(form)
2023-05-17 19:21:53 +03:00
return redirect(url_for("book.my_library"))
@bp.route("/<int:book_id>/edit", methods=["POST"])
@register_book_verify_route(bp.name)
@require_permission(
entity_type=m.Permission.Entity.BOOK,
access=[m.Permission.Access.U],
entities=[m.Book],
)
2023-05-17 19:21:53 +03:00
@login_required
def edit(book_id: int):
form = f.EditBookForm()
if form.validate_on_submit():
book: m.Book = db.session.get(m.Book, book_id)
label = form.label.data
about = form.about.data
2023-05-26 10:14:21 +03:00
tags = form.tags.data or ""
set_book_tags(book, tags)
2023-05-17 19:21:53 +03:00
2023-06-20 15:13:08 +03:00
active_version: m.BookVersion = book.active_version
active_version.updated_at = datetime.now()
active_version.updated_by = current_user.id
2023-05-17 19:21:53 +03:00
book.label = label
book.about = about
log(log.INFO, "Update Book: [%s]", book)
book.save()
2023-06-20 15:13:08 +03:00
log(log.INFO, "Update version updated at: [%s]", active_version)
active_version.save()
2023-05-17 19:21:53 +03:00
flash("Success!", "success")
return redirect(url_for("book.collection_view", book_id=book_id))
else:
log(log.ERROR, "Book create errors: [%s]", form.errors)
create_error_flash(form)
2023-05-17 19:21:53 +03:00
return redirect(url_for("book.settings", book_id=book_id))
@bp.route("/<int:book_id>/delete", methods=["POST"])
2023-05-29 17:37:51 +03:00
@require_permission(
entity_type=m.Permission.Entity.BOOK,
access=[m.Permission.Access.D],
entities=[m.Book],
2023-05-29 17:37:51 +03:00
)
2023-05-17 19:21:53 +03:00
@login_required
def delete(book_id: int):
book: m.Book = db.session.get(m.Book, book_id)
if not book or book.is_deleted:
log(log.INFO, "User: [%s] is not owner of book: [%s]", current_user, book)
flash("Book not found!", "danger")
2023-05-17 19:21:53 +03:00
return redirect(url_for("book.my_library"))
book.is_deleted = True
delete_nested_book_entities(book)
log(log.INFO, "Book deleted: [%s]", book)
book.save()
flash("Success!", "success")
return redirect(url_for("book.my_library"))
@bp.route("/<int:book_id>/statistics", methods=["GET"])
def statistic_view(book_id: int):
book = db.session.get(m.Book, book_id)
2023-06-02 10:08:33 +03:00
active_tab = request.args.get("active_tab")
2023-05-17 19:21:53 +03:00
if not book or book.is_deleted:
log(log.WARNING, "Book with id [%s] not found", book_id)
flash("Book not found", "danger")
return redirect(url_for("book.my_library"))
2023-06-02 10:08:33 +03:00
return render_template("book/stat.html", book=book, active_tab=active_tab)
2023-05-22 11:32:06 +03:00
@bp.route("/favorite_books", methods=["GET"])
def favorite_books():
2023-05-22 14:17:52 +03:00
if current_user.is_authenticated:
2023-05-26 16:56:04 +03:00
log(log.INFO, "Creating query for books")
2023-06-14 17:17:43 +03:00
sort = request.args.get("sort")
2023-05-26 16:56:04 +03:00
2023-05-22 14:17:52 +03:00
books = (
db.session.query(
m.Book,
2023-06-14 17:17:43 +03:00
m.Book.created_at.label("created_at"),
2023-06-15 12:52:51 +03:00
func.count(distinct(m.Interpretation.id)).label(
"interpretations_count"
),
func.count(distinct(m.BookStar.id)).label("stars_count"),
2023-06-14 17:17:43 +03:00
)
.join(
2023-06-15 09:51:35 +03:00
m.BookStar,
and_(
m.BookStar.book_id == m.Book.id,
m.BookStar.is_deleted == False, # noqa: E712
),
full=True,
)
.join(
m.BookVersion,
and_(
m.BookVersion.book_id == m.Book.id,
m.BookVersion.is_deleted == False, # noqa: E712
),
)
.join(
m.Section,
and_(
m.BookVersion.id == m.Section.version_id,
m.Section.is_deleted == False, # noqa: E712
),
full=True,
)
.join(
m.Interpretation,
and_(
m.Interpretation.section_id == m.Section.id,
m.Interpretation.is_deleted == False, # noqa: E712
),
full=True,
2023-05-22 14:17:52 +03:00
)
.filter(
2023-06-14 17:17:43 +03:00
m.Book.id == m.BookStar.book_id,
m.BookStar.user_id == current_user.id,
m.Book.is_deleted == False, # noqa: E712
2023-05-22 14:17:52 +03:00
)
2023-06-14 17:17:43 +03:00
.group_by(m.Book.id)
2023-05-22 14:17:52 +03:00
)
2023-06-14 17:17:43 +03:00
pagination, books = sort_by(books, sort)
2023-05-26 16:56:04 +03:00
log(log.INFO, "Returns data for front end")
2023-05-22 14:17:52 +03:00
return render_template(
"book/favorite_books.html",
2023-06-14 17:17:43 +03:00
books=books,
2023-05-22 14:17:52 +03:00
page=pagination,
)
return render_template("book/favorite_books.html", books=[])
2023-05-22 11:32:06 +03:00
@bp.route("/my_contributions", methods=["GET"])
def my_contributions():
2023-05-25 16:51:42 +03:00
if current_user.is_authenticated:
2023-05-26 16:56:04 +03:00
log(log.INFO, "Creating query for interpretations")
2023-06-14 17:17:43 +03:00
sort = request.args.get("sort")
2023-05-26 16:56:04 +03:00
2023-05-25 16:51:42 +03:00
interpretations = (
2023-06-14 17:17:43 +03:00
db.session.query(
m.Interpretation,
m.Interpretation.score.label("score"),
m.Interpretation.created_at.label("created_at"),
2023-06-15 12:52:51 +03:00
func.count(distinct(m.Comment.interpretation_id)).label(
"comments_count"
),
2023-06-14 17:17:43 +03:00
)
2023-06-02 10:27:52 +03:00
.join(
2023-06-15 12:52:51 +03:00
m.Comment,
and_(
m.Comment.interpretation_id == m.Interpretation.id,
m.Comment.is_deleted == False, # noqa: E712
),
full=True,
2023-06-02 10:27:52 +03:00
)
.join(
m.InterpretationVote,
2023-06-15 12:52:51 +03:00
and_(
m.InterpretationVote.interpretation_id == m.Interpretation.id,
m.Interpretation.is_deleted == False, # noqa: E712
),
2023-06-02 10:27:52 +03:00
full=True,
2023-05-25 16:51:42 +03:00
)
.filter(
or_(
and_(
m.Comment.user_id == current_user.id,
m.Comment.is_deleted.is_(False),
),
and_(
m.Interpretation.user_id == current_user.id,
m.Interpretation.is_deleted.is_(False),
),
2023-06-02 10:27:52 +03:00
and_(
m.InterpretationVote.user_id == current_user.id,
m.InterpretationVote.interpretation_id == m.Interpretation.id,
),
),
2023-06-02 11:46:28 +03:00
m.Interpretation.is_deleted == False, # noqa: E712
2023-06-15 12:52:51 +03:00
m.Interpretation.copy_of == 0,
2023-05-22 14:17:52 +03:00
)
2023-05-25 16:51:42 +03:00
.group_by(m.Interpretation.id)
2023-05-22 14:17:52 +03:00
)
2023-06-14 17:17:43 +03:00
pagination, interpretations = sort_by(interpretations, sort)
2023-05-26 16:56:04 +03:00
log(log.INFO, "Returns data for front end")
2023-05-22 14:17:52 +03:00
2023-05-25 16:51:42 +03:00
return render_template(
"book/my_contributions.html",
2023-06-14 17:17:43 +03:00
interpretations=interpretations,
2023-05-25 16:51:42 +03:00
page=pagination,
)
return render_template("book/my_contributions.html", interpretations=[])