Skip to content

Commit

Permalink
feat(kobo): sync On Deck as a Kobo collection
Browse files Browse the repository at this point in the history
  • Loading branch information
gotson committed Sep 11, 2024
1 parent e72ff78 commit f07be06
Show file tree
Hide file tree
Showing 10 changed files with 569 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
CREATE TABLE SYNC_POINT_READLIST
(
SYNC_POINT_ID varchar NOT NULL,
READLIST_ID varchar NOT NULL,
READLIST_NAME varchar NOT NULL,
READLIST_CREATED_DATE datetime NOT NULL,
READLIST_LAST_MODIFIED_DATE datetime NOT NULL,
SYNCED boolean NOT NULL default false,
PRIMARY KEY (SYNC_POINT_ID, READLIST_ID),
FOREIGN KEY (SYNC_POINT_ID) REFERENCES SYNC_POINT (ID)
);

create index if not exists idx__sync_point_readlist__sync_point_id
on SYNC_POINT_READLIST (SYNC_POINT_ID);

CREATE TABLE SYNC_POINT_READLIST_BOOK
(
SYNC_POINT_ID varchar NOT NULL,
READLIST_ID varchar NOT NULL,
BOOK_ID varchar NOT NULL,
PRIMARY KEY (SYNC_POINT_ID, READLIST_ID, BOOK_ID),
FOREIGN KEY (SYNC_POINT_ID) REFERENCES SYNC_POINT (ID)
);

create index if not exists idx__sync_point_readlist_book__sync_point_id_readlist_id
on SYNC_POINT_READLIST_BOOK (SYNC_POINT_ID, READLIST_ID);

CREATE TABLE SYNC_POINT_READLIST_REMOVED_SYNCED
(
SYNC_POINT_ID varchar NOT NULL,
READLIST_ID varchar NOT NULL,
PRIMARY KEY (SYNC_POINT_ID, READLIST_ID),
FOREIGN KEY (SYNC_POINT_ID) REFERENCES SYNC_POINT (ID)
);
19 changes: 19 additions & 0 deletions komga/src/main/kotlin/org/gotson/komga/domain/model/SyncPoint.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,23 @@ data class SyncPoint(
val metadataLastModifiedDate: ZonedDateTime,
val synced: Boolean,
)

data class ReadList(
val syncPointId: String,
val readListId: String,
val readListName: String,
val createdDate: ZonedDateTime,
val lastModifiedDate: ZonedDateTime,
val synced: Boolean,
) {
companion object {
const val ON_DECK_ID = "KOMGA-ONDECK"
}

data class Book(
val syncPointId: String,
val readListId: String,
val bookId: String,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ interface SyncPointRepository {
search: BookSearch,
): SyncPoint

fun addOnDeck(
syncPointId: String,
user: KomgaUser,
filterOnLibraryIds: Collection<String>?,
)

fun findByIdOrNull(syncPointId: String): SyncPoint?

fun findBooksById(
Expand Down Expand Up @@ -49,12 +55,50 @@ interface SyncPointRepository {
pageable: Pageable,
): Page<SyncPoint.Book>

fun findReadListsById(
syncPointId: String,
onlyNotSynced: Boolean,
pageable: Pageable,
): Page<SyncPoint.ReadList>

fun findReadListsAdded(
fromSyncPointId: String,
toSyncPointId: String,
onlyNotSynced: Boolean,
pageable: Pageable,
): Page<SyncPoint.ReadList>

fun findReadListsChanged(
fromSyncPointId: String,
toSyncPointId: String,
onlyNotSynced: Boolean,
pageable: Pageable,
): Page<SyncPoint.ReadList>

fun findReadListsRemoved(
fromSyncPointId: String,
toSyncPointId: String,
onlyNotSynced: Boolean,
pageable: Pageable,
): Page<SyncPoint.ReadList>

fun findBookIdsByReadListIds(
syncPointId: String,
readListIds: Collection<String>,
): List<SyncPoint.ReadList.Book>

fun markBooksSynced(
syncPointId: String,
forRemovedBooks: Boolean,
bookIds: Collection<String>,
)

fun markReadListsSynced(
syncPointId: String,
forRemovedReadLists: Boolean,
readListIds: Collection<String>,
)

fun deleteByUserId(userId: String)

fun deleteByUserIdAndApiKeyIds(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,24 @@ class SyncPointLifecycle(
user: KomgaUser,
apiKeyId: String?,
libraryIds: List<String>?,
): SyncPoint =
syncPointRepository.create(
user,
apiKeyId,
BookSearch(
libraryIds = user.getAuthorizedLibraryIds(libraryIds),
mediaStatus = setOf(Media.Status.READY),
mediaProfile = listOf(MediaProfile.EPUB),
deleted = false,
),
)
): SyncPoint {
val authorizedLibraryIds = user.getAuthorizedLibraryIds(libraryIds)
val syncPoint =
syncPointRepository.create(
user,
apiKeyId,
BookSearch(
libraryIds = authorizedLibraryIds,
mediaStatus = setOf(Media.Status.READY),
mediaProfile = listOf(MediaProfile.EPUB),
deleted = false,
),
)

syncPointRepository.addOnDeck(syncPoint.id, user, authorizedLibraryIds)

return syncPoint
}

/**
* Retrieve a page of un-synced books and mark them as synced.
Expand Down Expand Up @@ -83,4 +90,35 @@ class SyncPointLifecycle(
): Page<SyncPoint.Book> =
syncPointRepository.findBooksReadProgressChanged(fromSyncPointId, toSyncPointId, true, pageable)
.also { page -> syncPointRepository.markBooksSynced(toSyncPointId, false, page.content.map { it.bookId }) }

fun takeReadLists(
toSyncPointId: String,
pageable: Pageable,
): Page<SyncPoint.ReadList> =
syncPointRepository.findReadListsById(toSyncPointId, true, pageable)
.also { page -> syncPointRepository.markReadListsSynced(toSyncPointId, false, page.content.map { it.readListId }) }

fun takeReadListsAdded(
fromSyncPointId: String,
toSyncPointId: String,
pageable: Pageable,
): Page<SyncPoint.ReadList> =
syncPointRepository.findReadListsAdded(fromSyncPointId, toSyncPointId, true, pageable)
.also { page -> syncPointRepository.markReadListsSynced(toSyncPointId, false, page.content.map { it.readListId }) }

fun takeReadListsChanged(
fromSyncPointId: String,
toSyncPointId: String,
pageable: Pageable,
): Page<SyncPoint.ReadList> =
syncPointRepository.findReadListsChanged(fromSyncPointId, toSyncPointId, true, pageable)
.also { page -> syncPointRepository.markReadListsSynced(toSyncPointId, false, page.content.map { it.readListId }) }

fun takeReadListsRemoved(
fromSyncPointId: String,
toSyncPointId: String,
pageable: Pageable,
): Page<SyncPoint.ReadList> =
syncPointRepository.findReadListsRemoved(fromSyncPointId, toSyncPointId, true, pageable)
.also { page -> syncPointRepository.markReadListsSynced(toSyncPointId, true, page.content.map { it.readListId }) }
}
Loading

0 comments on commit f07be06

Please sign in to comment.