@@ -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
936977def 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