From 5b3015619d8f63f47d0afc98ac7e75162070a6a0 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 5 Feb 2022 15:36:18 +0100 Subject: [PATCH] Save book read status on edit in books table --- cps/editbooks.py | 36 ++++++++++++++++++------------------ cps/helper.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ cps/web.py | 47 +++++++---------------------------------------- 3 files changed, 73 insertions(+), 58 deletions(-) diff --git a/cps/editbooks.py b/cps/editbooks.py index 03cbc233..4948c2dc 100755 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -1151,24 +1151,24 @@ def table_get_custom_enum(c_id): def edit_list_book(param): vals = request.form.to_dict() book = calibre_db.get_book(vals['pk']) - ret = "" - if param =='series_index': + # ret = "" + if param == 'series_index': edit_book_series_index(vals['value'], book) ret = Response(json.dumps({'success': True, 'newValue': book.series_index}), mimetype='application/json') - elif param =='tags': + elif param == 'tags': edit_book_tags(vals['value'], book) ret = Response(json.dumps({'success': True, 'newValue': ', '.join([tag.name for tag in book.tags])}), mimetype='application/json') - elif param =='series': + elif param == 'series': edit_book_series(vals['value'], book) ret = Response(json.dumps({'success': True, 'newValue': ', '.join([serie.name for serie in book.series])}), mimetype='application/json') - elif param =='publishers': + elif param == 'publishers': edit_book_publisher(vals['value'], book) - ret = Response(json.dumps({'success': True, + ret = Response(json.dumps({'success': True, 'newValue': ', '.join([publisher.name for publisher in book.publishers])}), mimetype='application/json') - elif param =='languages': + elif param == 'languages': invalid = list() edit_book_languages(vals['value'], book, invalid=invalid) if invalid: @@ -1179,9 +1179,9 @@ def edit_list_book(param): lang_names = list() for lang in book.languages: lang_names.append(isoLanguages.get_language_name(get_locale(), lang.lang_code)) - ret = Response(json.dumps({'success': True, 'newValue': ', '.join(lang_names)}), + ret = Response(json.dumps({'success': True, 'newValue': ', '.join(lang_names)}), mimetype='application/json') - elif param =='author_sort': + elif param == 'author_sort': book.author_sort = vals['value'] ret = Response(json.dumps({'success': True, 'newValue': book.author_sort}), mimetype='application/json') @@ -1191,27 +1191,27 @@ def edit_list_book(param): helper.update_dir_structure(book.id, config.config_calibre_dir) ret = Response(json.dumps({'success': True, 'newValue': book.title}), mimetype='application/json') - elif param =='sort': + elif param == 'sort': book.sort = vals['value'] ret = Response(json.dumps({'success': True, 'newValue': book.sort}), mimetype='application/json') - elif param =='comments': + elif param == 'comments': edit_book_comments(vals['value'], book) ret = Response(json.dumps({'success': True, 'newValue': book.comments[0].text}), mimetype='application/json') - elif param =='authors': + elif param == 'authors': input_authors, __, renamed = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true") helper.update_dir_structure(book.id, config.config_calibre_dir, input_authors[0], renamed_author=renamed) ret = Response(json.dumps({'success': True, 'newValue': ' & '.join([author.replace('|',',') for author in input_authors])}), mimetype='application/json') - elif param =='is_archived': - change_archived_books(book.id, vals['value']=="True") + elif param == 'is_archived': + change_archived_books(book.id, vals['value'] == "True") ret = "" - elif param =='read_status': - # ToDo save - ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), - mimetype='application/json') + elif param == 'read_status': + ret = helper.edit_book_read_status(book.id, vals['value'] == "True") + if ret: + return ret, 400 elif param.startswith("custom_column_"): new_val = dict() new_val[param] = vals['value'] diff --git a/cps/helper.py b/cps/helper.py index 150fb85c..b5495930 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -35,6 +35,7 @@ from flask import send_from_directory, make_response, redirect, abort, url_for from flask_babel import gettext as _ from flask_login import current_user from sqlalchemy.sql.expression import true, false, and_, text, func +from sqlalchemy.exc import InvalidRequestError, OperationalError from werkzeug.datastructures import Headers from werkzeug.security import generate_password_hash from markupsafe import escape @@ -289,6 +290,53 @@ def get_sorted_author(value): value2 = value return value2 +def edit_book_read_status(book_id, read_status=None): + if not config.config_read_column: + book = ub.session.query(ub.ReadBook).filter(and_(ub.ReadBook.user_id == int(current_user.id), + ub.ReadBook.book_id == book_id)).first() + if book: + if read_status is None: + if book.read_status == ub.ReadBook.STATUS_FINISHED: + book.read_status = ub.ReadBook.STATUS_UNREAD + else: + book.read_status = ub.ReadBook.STATUS_FINISHED + else: + book.read_status = ub.ReadBook.STATUS_FINISHED if read_status else ub.ReadBook.STATUS_UNREAD + else: + readBook = ub.ReadBook(user_id=current_user.id, book_id = book_id) + readBook.read_status = ub.ReadBook.STATUS_FINISHED + book = readBook + if not book.kobo_reading_state: + kobo_reading_state = ub.KoboReadingState(user_id=current_user.id, book_id=book_id) + kobo_reading_state.current_bookmark = ub.KoboBookmark() + kobo_reading_state.statistics = ub.KoboStatistics() + book.kobo_reading_state = kobo_reading_state + ub.session.merge(book) + ub.session_commit("Book {} readbit toggled".format(book_id)) + else: + try: + calibre_db.update_title_sort(config) + book = calibre_db.get_filtered_book(book_id) + read_status = getattr(book, 'custom_column_' + str(config.config_read_column)) + if len(read_status): + if read_status is None: + read_status[0].value = not read_status[0].value + else: + read_status[0].value = read_status is True + calibre_db.session.commit() + else: + cc_class = db.cc_classes[config.config_read_column] + new_cc = cc_class(value=read_status or 1, book=book_id) + calibre_db.session.add(new_cc) + calibre_db.session.commit() + except (KeyError, AttributeError): + log.error(u"Custom Column No.%d is not existing in calibre database", config.config_read_column) + return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column) + except (OperationalError, InvalidRequestError) as e: + calibre_db.session.rollback() + log.error(u"Read status could not set: {}".format(e)) + return "Read status could not set: {}".format(e), 400 + return "" # Deletes a book fro the local filestorage, returns True if deleting is successfull, otherwise false def delete_book_file(book, calibrepath, book_format=None): diff --git a/cps/web.py b/cps/web.py index 018c0002..6d33f809 100644 --- a/cps/web.py +++ b/cps/web.py @@ -50,7 +50,8 @@ from . import calibre_db, kobo_sync_status from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download from .helper import check_valid_domain, render_task_status, check_email, check_username, \ get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \ - send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password, valid_email + send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password, valid_email, \ + edit_book_read_status from .pagination import Pagination from .redirect import redirect_back from .usermanagement import login_required_if_no_ano @@ -154,46 +155,12 @@ def bookmark(book_id, book_format): @web.route("/ajax/toggleread/", methods=['POST']) @login_required def toggle_read(book_id): - if not config.config_read_column: - book = ub.session.query(ub.ReadBook).filter(and_(ub.ReadBook.user_id == int(current_user.id), - ub.ReadBook.book_id == book_id)).first() - if book: - if book.read_status == ub.ReadBook.STATUS_FINISHED: - book.read_status = ub.ReadBook.STATUS_UNREAD - else: - book.read_status = ub.ReadBook.STATUS_FINISHED - else: - readBook = ub.ReadBook(user_id=current_user.id, book_id = book_id) - readBook.read_status = ub.ReadBook.STATUS_FINISHED - book = readBook - if not book.kobo_reading_state: - kobo_reading_state = ub.KoboReadingState(user_id=current_user.id, book_id=book_id) - kobo_reading_state.current_bookmark = ub.KoboBookmark() - kobo_reading_state.statistics = ub.KoboStatistics() - book.kobo_reading_state = kobo_reading_state - ub.session.merge(book) - ub.session_commit("Book {} readbit toggled".format(book_id)) + message = edit_book_read_status(book_id) + if message: + return message, 400 else: - try: - calibre_db.update_title_sort(config) - book = calibre_db.get_filtered_book(book_id) - read_status = getattr(book, 'custom_column_' + str(config.config_read_column)) - if len(read_status): - read_status[0].value = not read_status[0].value - calibre_db.session.commit() - else: - cc_class = db.cc_classes[config.config_read_column] - new_cc = cc_class(value=1, book=book_id) - calibre_db.session.add(new_cc) - calibre_db.session.commit() - except (KeyError, AttributeError): - log.error(u"Custom Column No.%d is not existing in calibre database", config.config_read_column) - return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column), 400 - except (OperationalError, InvalidRequestError) as e: - calibre_db.session.rollback() - log.error(u"Read status could not set: {}".format(e)) - return "Read status could not set: {}".format(e), 400 - return "" + return message + @web.route("/ajax/togglearchived/", methods=['POST']) @login_required