Skip to content

Commit 48599fe

Browse files
Merge pull request #511 from Domoel/main
Enhancement: Implement full two-way deletion sync for shelves + Make archiving on device deletion conditional
2 parents de93350 + 3d06da4 commit 48599fe

2 files changed

Lines changed: 56 additions & 7 deletions

File tree

CONTRIBUTORS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
CONTRIBUTORS
22

33
This file is automatically generated. DO NOT EDIT MANUALLY.
4+
45
Generated on: 2025-09-02T16:32:33.527271Z
56

67
Upstream project: https://github.com/janeczku/calibre-web
@@ -305,6 +306,7 @@ Copyright (C) 2024-2025 Calibre-Web Automated contributors
305306
- zikasak (3 commits)
306307
- chad3814 (2 commits)
307308
- coissac (2 commits)
309+
- deadbone (2 commits)
308310
- FennyFatal (2 commits)
309311
- tseho (2 commits)
310312
- Valenth (2 commits)

cps/kobo.py

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,51 @@ def HandleSyncRequest():
150150

151151
new_archived_last_modified = datetime.min
152152
sync_results = []
153-
154-
# We reload the book database so that the user gets a fresh view of the library
155-
# in case of external changes (e.g: adding a book through Calibre).
153+
156154
calibre_db.reconnect_db(config, ub.app_DB_path)
155+
156+
157+
# Two-Way-Sync Deletion Logic
158+
if current_user.kobo_only_shelves_sync:
159+
try:
160+
# Check all books that are on Kobo according to the database
161+
synced_books_query = ub.session.query(ub.KoboSyncedBooks.book_id).filter(ub.KoboSyncedBooks.user_id == current_user.id)
162+
synced_book_ids = {item.book_id for item in synced_books_query}
163+
164+
# Check all books currently on a Kobo Sync shelf
165+
allowed_books_query = (ub.session.query(ub.BookShelf.book_id)
166+
.join(ub.Shelf, ub.BookShelf.shelf == ub.Shelf.id)
167+
.filter(ub.Shelf.user_id == current_user.id, ub.Shelf.kobo_sync == True))
168+
allowed_book_ids = {item.book_id for item in allowed_books_query}
169+
170+
# Spot the difference: books that need to be deleted
171+
books_to_delete_ids = synced_book_ids - allowed_book_ids
172+
173+
if books_to_delete_ids:
174+
log.info(f"Kobo Sync: Found {len(books_to_delete_ids)} books to remove from device for user {current_user.name}")
175+
176+
# Go through the “To be deleted” list
177+
for book_id in books_to_delete_ids:
178+
book = calibre_db.get_book(book_id)
179+
if book:
180+
# Create a “Remove” command for the Kobo
181+
entitlement = {
182+
"BookEntitlement": create_book_entitlement(book, archived=True),
183+
"BookMetadata": get_metadata(book),
184+
}
185+
sync_results.append({"ChangedEntitlement": entitlement})
186+
187+
# Remove all books from the tracking table in one go
188+
if books_to_delete_ids:
189+
ub.session.query(ub.KoboSyncedBooks).filter(
190+
ub.KoboSyncedBooks.user_id == current_user.id,
191+
ub.KoboSyncedBooks.book_id.in_(books_to_delete_ids)
192+
).delete(synchronize_session=False)
193+
ub.session_commit()
194+
195+
except Exception as e:
196+
log.error(f"Kobo Sync: Error during deletion logic: {e}")
197+
ub.session.rollback()
157198

158199
only_kobo_shelves = current_user.kobo_only_shelves_sync
159200

@@ -934,16 +975,22 @@ def TopLevelEndpoint():
934975
@kobo.route("/v1/library/<book_uuid>", methods=["DELETE"])
935976
@requires_kobo_auth
936977
def HandleBookDeletionRequest(book_uuid):
937-
log.info("Kobo book delete request received for book %s" % book_uuid)
978+
log.info("Kobo book delete request received for book %s", book_uuid)
938979
book = calibre_db.get_book_by_uuid(book_uuid)
939980
if not book:
940981
log.info("Book %s not found in database", book_uuid)
941982
return redirect_or_proxy_request()
942983

943984
book_id = book.id
944-
is_archived = kobo_sync_status.change_archived_books(book_id, True)
945-
if is_archived:
946-
kobo_sync_status.remove_synced_book(book_id)
985+
# If the user has shelf sync enabled, do nothing.
986+
# The book will be removed from the device on the next sync.
987+
if current_user.kobo_only_shelves_sync:
988+
pass
989+
# Otherwise, archive the book if the user has permission to see archived books.
990+
elif current_user.check_visibility(32768):
991+
kobo_sync_status.change_archived_books(book_id, True)
992+
993+
kobo_sync_status.remove_synced_book(book_id)
947994
return "", 204
948995

949996

0 commit comments

Comments
 (0)