diff --git a/cps/static/css/style.css b/cps/static/css/style.css index f0ea4cb1..7f053629 100644 --- a/cps/static/css/style.css +++ b/cps/static/css/style.css @@ -53,3 +53,8 @@ span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: te .spinner2 {margin:0 41%;} .block-label {display: block;} + +#remove-from-shelves .btn, +#shelf-action-errors { + margin-left: 5px; +} diff --git a/cps/static/js/details.js b/cps/static/js/details.js new file mode 100644 index 00000000..ba45da17 --- /dev/null +++ b/cps/static/js/details.js @@ -0,0 +1,39 @@ +$( document ).ready(function() { + $("#have_read_form").ajaxForm(); +}); + +$("#have_read_cb").on("change", function() { + $(this).closest("form").submit(); +}); + +$(document).on("click", "[data-shelf-action]", function (e) { + e.preventDefault(); + + $.get(this.href) + .done(() => { + const $this = $(this); + switch ($this.data("shelf-action")) { + case "add": + $("#remove-from-shelves").append(` ${this.textContent}`); + break; + case "remove": + $("#add-to-shelves").append(`
  • ${this.textContent}
  • `); + break; + } + this.parentNode.removeChild(this); + }) + .fail(xhr => { + const $msg = $("", { "class": "text-danger"}).text(xhr.responseText); + $("#shelf-action-status").html($msg); + + setTimeout(() => { + $msg.remove(); + }, 10000); + }); +}); \ No newline at end of file diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 6d6ecdab..37cdd01f 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -185,41 +185,62 @@ {% if g.user.shelf.all() or g.public_shelfes %} {% endif %} @@ -233,19 +254,12 @@ {% endif %} - + {% endblock %} {% block js %} - + {% endblock %} diff --git a/cps/templates/layout.html b/cps/templates/layout.html index 1833df5c..0dd9583e 100644 --- a/cps/templates/layout.html +++ b/cps/templates/layout.html @@ -99,17 +99,17 @@ {% for message in get_flashed_messages(with_categories=True) %} {%if message[0] == "error" %} -
    +
    {{ message[1] }}
    {%endif%} {%if message[0] == "info" %} -
    +
    {{ message[1] }}
    {%endif%} {%if message[0] == "success" %} -
    +
    {{ message[1] }}
    {%endif%} diff --git a/cps/web.py b/cps/web.py index dbcaa5bd..32a3d3e4 100755 --- a/cps/web.py +++ b/cps/web.py @@ -1949,45 +1949,80 @@ def send_to_kindle(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: + return redirect(url_for('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) - return redirect(url_for('index')) - maxOrder = ub.session.query(func.max(ub.BookShelf.order)).filter(ub.BookShelf.shelf == shelf_id).first() + if not request.is_xhr: + return redirect(url_for('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: + return redirect(url_for('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) - return redirect(url_for('index')) + if not request.is_xhr: + return redirect(url_for('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] - if (shelf.is_public and current_user.role_edit_shelfs()) or not shelf.is_public: - ins = ub.BookShelf(shelf=shelf.id, book_id=book_id, order=maxOrder + 1) - ub.session.add(ins) - ub.session.commit() + + 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") return redirect(request.environ["HTTP_REFERER"]) - else: - app.logger.info("User is not allowed to edit public shelfs") - return redirect(url_for('index')) + return "", 204 @app.route("/shelf/remove//") @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('index')) + return "Invalid shelf specified", 400 + if not shelf.is_public and not shelf.user_id == int(current_user.id) \ or (shelf.is_public and current_user.role_edit_shelfs()): - app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name) - return redirect(url_for('index')) + if not request.is_xhr: + app.logger.info("Sorry you are not allowed to remove a book from this shelf: %s" % shelf.name) + return redirect(url_for('index')) + return "Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name, 403 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('index')) + return "Book already removed from shelf", 410 + ub.session.delete(book_shelf) ub.session.commit() - flash(_(u"Book has been removed from shelf: %(sname)s", sname=shelf.name), category="success") - return redirect(request.environ["HTTP_REFERER"]) + + 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 @app.route("/shelf/create", methods=["GET", "POST"])