Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Sync custom column read state with kobo #2997

Open
wants to merge 1 commit into
base: Develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions cps/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions cps/config_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion cps/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,7 +768,7 @@ def generate_linked_query(self, config_read_column, database):
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):
Expand Down
26 changes: 25 additions & 1 deletion cps/kobo.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
from sqlalchemy import func
from sqlalchemy.sql.expression import and_, or_
from sqlalchemy.exc import StatementError
from sqlalchemy.sql import select
import requests


Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions cps/templates/config_edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ <h4 class="panel-title">
<input type="number" min="1" max="65535" class="form-control" name="config_external_port" id="config_external_port" value="{% if config.config_external_port != None %}{{ config.config_external_port }}{% endif %}" autocomplete="off" required>
</div>
</div>
<div data-related="kobo-settings">
<div class="form-group" style="margin-left:10px;">
<label for="config_kobo_read_column_sync_user">{{_('User for Calibre Read Column')}}</label>
<select name="config_kobo_read_column_sync_user" id="config_kobo_read_column_sync_user" class="form-control">
{% for user in users %}
<option value="{{user.id}}" {% if user.id == config.config_kobo_read_column_sync_user %}selected{% endif %}>{{user.name}}</option>"
{% endfor %}
</select>
</div>
</div>
{% endif %}
{% if feature_support['goodreads'] %}
<div class="form-group">
Expand Down