4230226716
Fixes reader button visible in detail view Fix formats to convert (added htmlz) Fix logger in updater Added request "v3" of github api on update Fix quotes parameter on external calls E-Mail logger working more stable (also on python3) Routing fixes Change import in ub
352 lines
17 KiB
Python
352 lines
17 KiB
Python
#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
|
|
# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11,
|
|
# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh,
|
|
# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe,
|
|
# ruben-herold, marblepebble, JackED42, SiphonSquirrel,
|
|
# apetresc, nanu-c, mutschler
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
from flask import Blueprint, request, flash, redirect, url_for
|
|
from cps import ub, searched_ids
|
|
from flask_babel import gettext as _
|
|
from sqlalchemy.sql.expression import func, or_
|
|
from flask_login import login_required, current_user
|
|
from web import render_title_template
|
|
from cps import app
|
|
import db
|
|
|
|
shelf = Blueprint('shelf', __name__)
|
|
|
|
@shelf.route("/shelf/add/<int:shelf_id>/<int:book_id>")
|
|
@login_required
|
|
def add_to_shelf(shelf_id, book_id):
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
|
|
if shelf is None:
|
|
app.logger.info("Invalid shelf specified")
|
|
if not request.is_xhr:
|
|
flash(_(u"Invalid shelf specified"), category="error")
|
|
return redirect(url_for('web.index'))
|
|
return "Invalid shelf specified", 400
|
|
|
|
if not shelf.is_public and not shelf.user_id == int(current_user.id):
|
|
app.logger.info("Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name)
|
|
if not request.is_xhr:
|
|
flash(_(u"Sorry you are not allowed to add a book to the the shelf: %(shelfname)s", shelfname=shelf.name),
|
|
category="error")
|
|
return redirect(url_for('web.index'))
|
|
return "Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name, 403
|
|
|
|
if shelf.is_public and not current_user.role_edit_shelfs():
|
|
app.logger.info("User is not allowed to edit public shelves")
|
|
if not request.is_xhr:
|
|
flash(_(u"You are not allowed to edit public shelves"), category="error")
|
|
return redirect(url_for('web.index'))
|
|
return "User is not allowed to edit public shelves", 403
|
|
|
|
book_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id,
|
|
ub.BookShelf.book_id == book_id).first()
|
|
if book_in_shelf:
|
|
app.logger.info("Book is already part of the shelf: %s" % shelf.name)
|
|
if not request.is_xhr:
|
|
flash(_(u"Book is already part of the shelf: %(shelfname)s", shelfname=shelf.name), category="error")
|
|
return redirect(url_for('web.index'))
|
|
return "Book is already part of the shelf: %s" % shelf.name, 400
|
|
|
|
maxOrder = ub.session.query(func.max(ub.BookShelf.order)).filter(ub.BookShelf.shelf == shelf_id).first()
|
|
if maxOrder[0] is None:
|
|
maxOrder = 0
|
|
else:
|
|
maxOrder = maxOrder[0]
|
|
|
|
ins = ub.BookShelf(shelf=shelf.id, book_id=book_id, order=maxOrder + 1)
|
|
ub.session.add(ins)
|
|
ub.session.commit()
|
|
if not request.is_xhr:
|
|
flash(_(u"Book has been added to shelf: %(sname)s", sname=shelf.name), category="success")
|
|
if "HTTP_REFERER" in request.environ:
|
|
return redirect(request.environ["HTTP_REFERER"])
|
|
else:
|
|
return redirect(url_for('web.index'))
|
|
return "", 204
|
|
|
|
|
|
@shelf.route("/shelf/massadd/<int:shelf_id>")
|
|
@login_required
|
|
def search_to_shelf(shelf_id):
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
|
|
if shelf is None:
|
|
app.logger.info("Invalid shelf specified")
|
|
flash(_(u"Invalid shelf specified"), category="error")
|
|
return redirect(url_for('web.index'))
|
|
|
|
if not shelf.is_public and not shelf.user_id == int(current_user.id):
|
|
app.logger.info("You are not allowed to add a book to the the shelf: %s" % shelf.name)
|
|
flash(_(u"You are not allowed to add a book to the the shelf: %(name)s", name=shelf.name), category="error")
|
|
return redirect(url_for('web.index'))
|
|
|
|
if shelf.is_public and not current_user.role_edit_shelfs():
|
|
app.logger.info("User is not allowed to edit public shelves")
|
|
flash(_(u"User is not allowed to edit public shelves"), category="error")
|
|
return redirect(url_for('web.index'))
|
|
|
|
if current_user.id in searched_ids and searched_ids[current_user.id]:
|
|
books_for_shelf = list()
|
|
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).all()
|
|
if books_in_shelf:
|
|
book_ids = list()
|
|
for book_id in books_in_shelf:
|
|
book_ids.append(book_id.book_id)
|
|
for id in searched_ids[current_user.id]:
|
|
if id not in book_ids:
|
|
books_for_shelf.append(id)
|
|
else:
|
|
books_for_shelf = searched_ids[current_user.id]
|
|
|
|
if not books_for_shelf:
|
|
app.logger.info("Books are already part of the shelf: %s" % shelf.name)
|
|
flash(_(u"Books are already part of the shelf: %(name)s", name=shelf.name), category="error")
|
|
return redirect(url_for('web.index'))
|
|
|
|
maxOrder = ub.session.query(func.max(ub.BookShelf.order)).filter(ub.BookShelf.shelf == shelf_id).first()
|
|
if maxOrder[0] is None:
|
|
maxOrder = 0
|
|
else:
|
|
maxOrder = maxOrder[0]
|
|
|
|
for book in books_for_shelf:
|
|
maxOrder = maxOrder + 1
|
|
ins = ub.BookShelf(shelf=shelf.id, book_id=book, order=maxOrder)
|
|
ub.session.add(ins)
|
|
ub.session.commit()
|
|
flash(_(u"Books have been added to shelf: %(sname)s", sname=shelf.name), category="success")
|
|
else:
|
|
flash(_(u"Could not add books to shelf: %(sname)s", sname=shelf.name), category="error")
|
|
return redirect(url_for('web.index'))
|
|
|
|
|
|
@shelf.route("/shelf/remove/<int:shelf_id>/<int:book_id>")
|
|
@login_required
|
|
def remove_from_shelf(shelf_id, book_id):
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
|
|
if shelf is None:
|
|
app.logger.info("Invalid shelf specified")
|
|
if not request.is_xhr:
|
|
return redirect(url_for('web.index'))
|
|
return "Invalid shelf specified", 400
|
|
|
|
# if shelf is public and use is allowed to edit shelfs, or if shelf is private and user is owner
|
|
# allow editing shelfs
|
|
# result shelf public user allowed user owner
|
|
# false 1 0 x
|
|
# true 1 1 x
|
|
# true 0 x 1
|
|
# false 0 x 0
|
|
|
|
if (not shelf.is_public and shelf.user_id == int(current_user.id)) \
|
|
or (shelf.is_public and current_user.role_edit_shelfs()):
|
|
book_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id,
|
|
ub.BookShelf.book_id == book_id).first()
|
|
|
|
if book_shelf is None:
|
|
app.logger.info("Book already removed from shelf")
|
|
if not request.is_xhr:
|
|
return redirect(url_for('web.index'))
|
|
return "Book already removed from shelf", 410
|
|
|
|
ub.session.delete(book_shelf)
|
|
ub.session.commit()
|
|
|
|
if not request.is_xhr:
|
|
flash(_(u"Book has been removed from shelf: %(sname)s", sname=shelf.name), category="success")
|
|
return redirect(request.environ["HTTP_REFERER"])
|
|
return "", 204
|
|
else:
|
|
app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name)
|
|
if not request.is_xhr:
|
|
flash(_(u"Sorry you are not allowed to remove a book from this shelf: %(sname)s", sname=shelf.name),
|
|
category="error")
|
|
return redirect(url_for('web.index'))
|
|
return "Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name, 403
|
|
|
|
|
|
|
|
@shelf.route("/shelf/create", methods=["GET", "POST"])
|
|
@login_required
|
|
def create_shelf():
|
|
shelf = ub.Shelf()
|
|
if request.method == "POST":
|
|
to_save = request.form.to_dict()
|
|
if "is_public" in to_save:
|
|
shelf.is_public = 1
|
|
shelf.name = to_save["title"]
|
|
shelf.user_id = int(current_user.id)
|
|
existing_shelf = ub.session.query(ub.Shelf).filter(
|
|
or_((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1),
|
|
(ub.Shelf.name == to_save["title"]) & (ub.Shelf.user_id == int(current_user.id)))).first()
|
|
if existing_shelf:
|
|
flash(_(u"A shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
|
|
else:
|
|
try:
|
|
ub.session.add(shelf)
|
|
ub.session.commit()
|
|
flash(_(u"Shelf %(title)s created", title=to_save["title"]), category="success")
|
|
except Exception:
|
|
flash(_(u"There was an error"), category="error")
|
|
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"create a shelf"), page="shelfcreate")
|
|
else:
|
|
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"create a shelf"), page="shelfcreate")
|
|
|
|
|
|
@shelf.route("/shelf/edit/<int:shelf_id>", methods=["GET", "POST"])
|
|
@login_required
|
|
def edit_shelf(shelf_id):
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
|
|
if request.method == "POST":
|
|
to_save = request.form.to_dict()
|
|
existing_shelf = ub.session.query(ub.Shelf).filter(
|
|
or_((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1),
|
|
(ub.Shelf.name == to_save["title"]) & (ub.Shelf.user_id == int(current_user.id)))).filter(
|
|
ub.Shelf.id != shelf_id).first()
|
|
if existing_shelf:
|
|
flash(_(u"A shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
|
|
else:
|
|
shelf.name = to_save["title"]
|
|
if "is_public" in to_save:
|
|
shelf.is_public = 1
|
|
else:
|
|
shelf.is_public = 0
|
|
try:
|
|
ub.session.commit()
|
|
flash(_(u"Shelf %(title)s changed", title=to_save["title"]), category="success")
|
|
except Exception:
|
|
flash(_(u"There was an error"), category="error")
|
|
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit")
|
|
else:
|
|
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit")
|
|
|
|
|
|
@shelf.route("/shelf/delete/<int:shelf_id>")
|
|
@login_required
|
|
def delete_shelf(shelf_id):
|
|
cur_shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
|
|
deleted = None
|
|
if current_user.role_admin():
|
|
deleted = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).delete()
|
|
else:
|
|
if (not cur_shelf.is_public and cur_shelf.user_id == int(current_user.id)) \
|
|
or (cur_shelf.is_public and current_user.role_edit_shelfs()):
|
|
deleted = ub.session.query(ub.Shelf).filter(ub.or_(ub.and_(ub.Shelf.user_id == int(current_user.id),
|
|
ub.Shelf.id == shelf_id),
|
|
ub.and_(ub.Shelf.is_public == 1,
|
|
ub.Shelf.id == shelf_id))).delete()
|
|
|
|
if deleted:
|
|
ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).delete()
|
|
ub.session.commit()
|
|
app.logger.info(_(u"successfully deleted shelf %(name)s", name=cur_shelf.name, category="success"))
|
|
return redirect(url_for('web.index'))
|
|
|
|
|
|
@shelf.route("/shelf/<int:shelf_id>")
|
|
@login_required
|
|
def show_shelf(shelf_id):
|
|
if current_user.is_anonymous:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.is_public == 1, ub.Shelf.id == shelf_id).first()
|
|
else:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.or_(ub.and_(ub.Shelf.user_id == int(current_user.id),
|
|
ub.Shelf.id == shelf_id),
|
|
ub.and_(ub.Shelf.is_public == 1,
|
|
ub.Shelf.id == shelf_id))).first()
|
|
result = list()
|
|
# user is allowed to access shelf
|
|
if shelf:
|
|
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).order_by(
|
|
ub.BookShelf.order.asc()).all()
|
|
for book in books_in_shelf:
|
|
cur_book = db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
|
if cur_book:
|
|
result.append(cur_book)
|
|
else:
|
|
app.logger.info('Not existing book %s in shelf %s deleted' % (book.book_id, shelf.id))
|
|
ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book.book_id).delete()
|
|
ub.session.commit()
|
|
return render_title_template('shelf.html', entries=result, title=_(u"Shelf: '%(name)s'", name=shelf.name),
|
|
shelf=shelf, page="shelf")
|
|
else:
|
|
flash(_(u"Error opening shelf. Shelf does not exist or is not accessible"), category="error")
|
|
return redirect(url_for("web.index"))
|
|
|
|
|
|
@shelf.route("/shelfdown/<int:shelf_id>")
|
|
@login_required
|
|
def show_shelf_down(shelf_id):
|
|
if current_user.is_anonymous:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.is_public == 1, ub.Shelf.id == shelf_id).first()
|
|
else:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.or_(ub.and_(ub.Shelf.user_id == int(current_user.id),
|
|
ub.Shelf.id == shelf_id),
|
|
ub.and_(ub.Shelf.is_public == 1,
|
|
ub.Shelf.id == shelf_id))).first()
|
|
result = list()
|
|
# user is allowed to access shelf
|
|
if shelf:
|
|
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).order_by(
|
|
ub.BookShelf.order.asc()).all()
|
|
for book in books_in_shelf:
|
|
cur_book = db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
|
if cur_book:
|
|
result.append(cur_book)
|
|
else:
|
|
app.logger.info('Not existing book %s in shelf %s deleted' % (book.book_id, shelf.id))
|
|
ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book.book_id).delete()
|
|
ub.session.commit()
|
|
return render_title_template('shelfdown.html', entries=result, title=_(u"Shelf: '%(name)s'", name=shelf.name),
|
|
shelf=shelf, page="shelf")
|
|
else:
|
|
flash(_(u"Error opening shelf. Shelf does not exist or is not accessible"), category="error")
|
|
return redirect(url_for("web.index"))
|
|
|
|
@shelf.route("/shelf/order/<int:shelf_id>", methods=["GET", "POST"])
|
|
@login_required
|
|
def order_shelf(shelf_id):
|
|
if request.method == "POST":
|
|
to_save = request.form.to_dict()
|
|
books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).order_by(
|
|
ub.BookShelf.order.asc()).all()
|
|
counter = 0
|
|
for book in books_in_shelf:
|
|
setattr(book, 'order', to_save[str(book.book_id)])
|
|
counter += 1
|
|
ub.session.commit()
|
|
if current_user.is_anonymous:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.is_public == 1, ub.Shelf.id == shelf_id).first()
|
|
else:
|
|
shelf = ub.session.query(ub.Shelf).filter(ub.or_(ub.and_(ub.Shelf.user_id == int(current_user.id),
|
|
ub.Shelf.id == shelf_id),
|
|
ub.and_(ub.Shelf.is_public == 1,
|
|
ub.Shelf.id == shelf_id))).first()
|
|
result = list()
|
|
if shelf:
|
|
books_in_shelf2 = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \
|
|
.order_by(ub.BookShelf.order.asc()).all()
|
|
for book in books_in_shelf2:
|
|
cur_book = db.session.query(db.Books).filter(db.Books.id == book.book_id).first()
|
|
result.append(cur_book)
|
|
return render_title_template('shelf_order.html', entries=result,
|
|
title=_(u"Change order of Shelf: '%(name)s'", name=shelf.name),
|
|
shelf=shelf, page="shelforder")
|