From 72c4e84344caa24695dd86a7c4636274608d8bd9 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 5 Feb 2024 23:01:05 +1100 Subject: [PATCH] Feature: Sync custom column read state with kobo --- cps/admin.py | 4 ++++ cps/config_sql.py | 1 + cps/db.py | 2 +- cps/kobo.py | 26 +++++++++++++++++++++++++- cps/templates/config_edit.html | 10 ++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/cps/admin.py b/cps/admin.py index fa29759e..57dc3704 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -244,8 +244,11 @@ def db_configuration(): @login_required @admin_required def configuration(): + all_user = ub.session.query(ub.User) + all_user = all_user.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) return render_title_template("config_edit.html", config=config, + users=all_user.all(), provider=oauthblueprints, feature_support=feature_support, title=_("Basic Configuration"), page="config") @@ -1760,6 +1763,7 @@ def _configuration_update_helper(): reboot_required |= _config_checkbox_int(to_save, "config_kobo_sync") _config_int(to_save, "config_external_port") _config_checkbox_int(to_save, "config_kobo_proxy") + _config_int(to_save, "config_kobo_read_column_sync_user") if "config_upload_formats" in to_save: to_save["config_upload_formats"] = ','.join( diff --git a/cps/config_sql.py b/cps/config_sql.py index c4f94b4e..bd774437 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -120,6 +120,7 @@ class _Settings(_Base): config_login_type = Column(Integer, default=0) config_kobo_proxy = Column(Boolean, default=False) + config_kobo_read_column_sync_user = Column(Integer, default=1) config_ldap_provider_url = Column(String, default='example.org') config_ldap_port = Column(SmallInteger, default=389) diff --git a/cps/db.py b/cps/db.py index ceb692ec..f80933cb 100644 --- a/cps/db.py +++ b/cps/db.py @@ -768,7 +768,7 @@ class CalibreDB: else: try: read_column = cc_classes[config_read_column] - query = (self.session.query(database, ub.ArchivedBook.is_archived, read_column.value) + query = (self.session.query(database, ub.ArchivedBook.is_archived, read_column.value.label("read_status")) .select_from(Books) .outerjoin(read_column, read_column.book == Books.id)) except (KeyError, AttributeError, IndexError): diff --git a/cps/kobo.py b/cps/kobo.py index 00e40b49..27a68a51 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -41,7 +41,6 @@ from werkzeug.datastructures import Headers from sqlalchemy import func from sqlalchemy.sql.expression import and_, or_ from sqlalchemy.exc import StatementError -from sqlalchemy.sql import select import requests @@ -797,6 +796,15 @@ def HandleStateRequest(book_uuid): and new_book_read_status != book_read.read_status: book_read.times_started_reading += 1 book_read.last_time_started_reading = datetime.datetime.utcnow() + if current_user.id == config.config_kobo_read_column_sync_user: + if new_book_read_status == ub.ReadBook.STATUS_FINISHED: + log.info(f"Syncing new read status to Calibre: Book \ + ({calibre_db.get_book(book.id).title}) -> Finished") + helper.edit_book_read_status(book.id, True) + elif new_book_read_status == ub.ReadBook.STATUS_UNREAD: + log.info(f"Syncing new read status to Calibre: Book \ + ({calibre_db.get_book(book.id).title}) -> Unread") + helper.edit_book_read_status(book.id, False) book_read.read_status = new_book_read_status update_results_response["StatusInfoResult"] = {"Result": "Success"} except (KeyError, TypeError, ValueError, StatementError): @@ -842,6 +850,22 @@ def get_or_create_reading_state(book_id): kobo_reading_state.current_bookmark = ub.KoboBookmark() kobo_reading_state.statistics = ub.KoboStatistics() book_read.kobo_reading_state = kobo_reading_state + + # While the custom read column is set, the read_status field can be outdated so update it now + if config.config_read_column and current_user.id == config.config_kobo_read_column_sync_user: + read_column_table = db.cc_classes[config.config_read_column] + query = calibre_db.session.query(read_column_table.value).filter(read_column_table.book == book_id).one_or_none() + if query: + # Reading state cant be repr in the custom col so leave those as is + if book_read.read_status == ub.ReadBook.STATUS_FINISHED and not query.value: + book_read.read_status = ub.ReadBook.STATUS_UNREAD + book_read.kobo_reading_state.last_modified = datetime.datetime.utcnow() + log.info(f"Syncing new read status to Kobo: Book ({calibre_db.get_book(book_id).title}) -> Finished") + elif book_read.read_status == ub.ReadBook.STATUS_UNREAD and query.value: + book_read.read_status = ub.ReadBook.STATUS_FINISHED + book_read.kobo_reading_state.last_modified = datetime.datetime.utcnow() + log.info(f"Syncing new read status to Kobo: Book ({calibre_db.get_book(book_id).title}) -> Unread") + ub.session.add(book_read) ub.session_commit() return book_read.kobo_reading_state diff --git a/cps/templates/config_edit.html b/cps/templates/config_edit.html index d83831db..64605017 100644 --- a/cps/templates/config_edit.html +++ b/cps/templates/config_edit.html @@ -150,6 +150,16 @@ +
+
+ + +
+
{% endif %} {% if feature_support['goodreads'] %}