diff --git a/cps/kobo.py b/cps/kobo.py index d019e918..f114706f 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -82,6 +82,7 @@ CONNECTION_SPECIFIC_HEADERS = [ "transfer-encoding", ] + def get_kobo_activated(): return config.config_kobo_sync @@ -152,30 +153,35 @@ def HandleSyncRequest(): # in case of external changes (e.g: adding a book through Calibre). calibre_db.reconnect_db(config, ub.app_DB_path) - if sync_token.books_last_id > -1: - changed_entries = ( - calibre_db.session.query(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) - .join(db.Data).outerjoin(ub.ArchivedBook, db.Books.id == ub.ArchivedBook.book_id) - .filter(db.Books.last_modified >= sync_token.books_last_modified) - .filter(db.Books.id>sync_token.books_last_id) - .filter(db.Data.format.in_(KOBO_FORMATS)) - .order_by(db.Books.last_modified) - .order_by(db.Books.id) - .limit(SYNC_ITEM_LIMIT) - ) - else: - changed_entries = ( - calibre_db.session.query(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) + changed_entries = ( + calibre_db.session.query(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) .join(db.Data).outerjoin(ub.ArchivedBook, db.Books.id == ub.ArchivedBook.book_id) .filter(db.Books.last_modified > sync_token.books_last_modified) .filter(db.Data.format.in_(KOBO_FORMATS)) .order_by(db.Books.last_modified) .order_by(db.Books.id) - .limit(SYNC_ITEM_LIMIT) + ) + + if sync_token.books_last_id > -1: + changed_entries = changed_entries.filter(db.Books.id > sync_token.books_last_id) + + only_kobo_shelfs = ( + calibre_db.session.query(ub.Shelf) + .filter(ub.Shelf.user_id == current_user.id) + .filter(ub.Shelf.kobo_sync) + .count() + ) > 0 + + if only_kobo_shelfs: + changed_entries = ( + changed_entries.join(ub.BookShelf, db.Books.id == ub.BookShelf.book_id) + .join(ub.Shelf) + .filter(ub.Shelf.kobo_sync) + .distinct() ) reading_states_in_new_entitlements = [] - for book in changed_entries: + for book in changed_entries.limit(SYNC_ITEM_LIMIT): formats = [data.format for data in book.Books.data] if not 'KEPUB' in formats and config.config_kepubifypath and 'EPUB' in formats: helper.convert_book_format(book.Books.id, config.config_calibre_dir, 'EPUB', 'KEPUB', current_user.nickname) @@ -238,7 +244,7 @@ def HandleSyncRequest(): }) new_reading_state_last_modified = max(new_reading_state_last_modified, kobo_reading_state.last_modified) - sync_shelves(sync_token, sync_results) + sync_shelves(sync_token, sync_results, only_kobo_shelfs=only_kobo_shelfs) sync_token.books_last_created = new_books_last_created sync_token.books_last_modified = new_books_last_modified @@ -392,7 +398,7 @@ def get_metadata(book): book_uuid = book.uuid metadata = { - "Categories": ["00000000-0000-0000-0000-000000000001",], + "Categories": ["00000000-0000-0000-0000-000000000001", ], # "Contributors": get_author(book), "CoverImageId": book_uuid, "CrossRevisionId": book_uuid, @@ -599,7 +605,7 @@ def HandleTagRemoveItem(tag_id): # Add new, changed, or deleted shelves to the sync_results. # Note: Public shelves that aren't owned by the user aren't supported. -def sync_shelves(sync_token, sync_results): +def sync_shelves(sync_token, sync_results, only_kobo_shelfs=False): new_tags_last_modified = sync_token.tags_last_modified for shelf in ub.session.query(ub.ShelfArchive).filter(func.datetime(ub.ShelfArchive.last_modified) > sync_token.tags_last_modified, @@ -615,8 +621,28 @@ def sync_shelves(sync_token, sync_results): } }) - for shelf in ub.session.query(ub.Shelf).filter(func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, - ub.Shelf.user_id == current_user.id): + extra_filters = [] + if only_kobo_shelfs: + for shelf in ub.session.query(ub.Shelf).filter( + func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, + ub.Shelf.user_id == current_user.id, + not ub.Shelf.kobo_sync + ): + sync_results.append({ + "DeletedTag": { + "Tag": { + "Id": shelf.uuid, + "LastModified": convert_to_kobo_timestamp_string(shelf.last_modified) + } + } + }) + extra_filters.append(ub.Shelf.kobo_sync) + + for shelf in ub.session.query(ub.Shelf).filter( + func.datetime(ub.Shelf.last_modified) > sync_token.tags_last_modified, + ub.Shelf.user_id == current_user.id, + *extra_filters + ): if not shelf_lib.check_shelf_view_permissions(shelf): continue diff --git a/cps/shelf.py b/cps/shelf.py index 5c6037ac..bde61e00 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -239,6 +239,12 @@ def create_edit_shelf(shelf, title, page, shelf_id=False): shelf.is_public = 1 else: shelf.is_public = 0 + + if "kobo_sync" in to_save: + shelf.kobo_sync = True + else: + shelf.kobo_sync = False + if check_shelf_is_unique(shelf, to_save, shelf_id): shelf.name = to_save["title"] # shelf.last_modified = datetime.utcnow() diff --git a/cps/templates/shelf_edit.html b/cps/templates/shelf_edit.html index 934efe2b..98acbdf8 100644 --- a/cps/templates/shelf_edit.html +++ b/cps/templates/shelf_edit.html @@ -13,6 +13,11 @@ {{_('Share with Everyone')}} +
+ +
{% endif %} {% if shelf.id != None %} diff --git a/cps/ub.py b/cps/ub.py index 1969ef53..e540f107 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -268,6 +268,7 @@ class Shelf(Base): name = Column(String) is_public = Column(Integer, default=0) user_id = Column(Integer, ForeignKey('user.id')) + kobo_sync = Column(Boolean, default=False) books = relationship("BookShelf", backref="ub_shelf", cascade="all, delete-orphan", lazy="dynamic") created = Column(DateTime, default=datetime.datetime.utcnow) last_modified = Column(DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow) @@ -504,6 +505,15 @@ def migrate_Database(session): for book_shelf in session.query(BookShelf).all(): book_shelf.date_added = datetime.datetime.now() session.commit() + + try: + session.query(exists().where(Shelf.kobo_sync)).scalar() + except exc.OperationalError: + with engine.connect() as conn: + + conn.execute("ALTER TABLE shelf ADD column 'kobo_sync' BOOLEAN DEFAULT false") + session.commit() + try: # Handle table exists, but no content cnt = session.query(Registration).count()