From 9d92b2594d5b32df1963671871185fb76b4e7d30 Mon Sep 17 00:00:00 2001 From: Gauthier Roebroeck Date: Fri, 3 Sep 2021 19:38:54 +0800 Subject: [PATCH] feat(api): read progress v2 for Tachiyomi uses numberSort instead of index of book in series --- .../komga/infrastructure/jooq/BookDtoDao.kt | 12 +- .../infrastructure/jooq/ReadProgressDtoDao.kt | 107 +++++++++++++----- .../komga/infrastructure/jooq/SeriesDtoDao.kt | 27 ++--- .../komga/interfaces/rest/SeriesController.kt | 72 +++++++++--- .../komga/interfaces/rest/dto/SeriesDto.kt | 5 - .../dto/TachiyomiReadProgressUpdateDto.kt | 11 ++ .../rest/dto/TachiyomiReadProgressV2Dto.kt | 9 ++ .../persistence/ReadProgressDtoRepository.kt | 2 + 8 files changed, 174 insertions(+), 71 deletions(-) create mode 100644 komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressUpdateDto.kt create mode 100644 komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressV2Dto.kt diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt index 5b7b7af3d..a72e638f6 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/BookDtoDao.kt @@ -17,6 +17,7 @@ import org.gotson.komga.jooq.tables.records.BookMetadataRecord import org.gotson.komga.jooq.tables.records.BookRecord import org.gotson.komga.jooq.tables.records.MediaRecord import org.gotson.komga.jooq.tables.records.ReadProgressRecord +import org.jooq.AggregateFunction import org.jooq.Condition import org.jooq.DSLContext import org.jooq.Record @@ -31,6 +32,7 @@ import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.stereotype.Component +import java.math.BigDecimal import java.net.URL @Component @@ -48,6 +50,10 @@ class BookDtoDao( private val rlb = Tables.READLIST_BOOK private val bt = Tables.BOOK_METADATA_TAG + private val countUnread: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isNull, 1).otherwise(0)) + private val countRead: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0)) + private val countInProgress: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0)) + private val sorts = mapOf( "name" to b.NAME.collate(SqliteUdfDataSource.collationUnicode3), "created" to b.CREATED_DATE, @@ -169,9 +175,9 @@ class BookDtoDao( .leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId)) .apply { filterOnLibraryIds?.let { where(s.LIBRARY_ID.`in`(it)) } } .groupBy(s.ID) - .having(SeriesDtoDao.countUnread.ge(inline(1.toBigDecimal()))) - .and(SeriesDtoDao.countRead.ge(inline(1.toBigDecimal()))) - .and(SeriesDtoDao.countInProgress.eq(inline(0.toBigDecimal()))) + .having(countUnread.ge(inline(1.toBigDecimal()))) + .and(countRead.ge(inline(1.toBigDecimal()))) + .and(countInProgress.eq(inline(0.toBigDecimal()))) .orderBy(DSL.max(r.LAST_MODIFIED_DATE).desc()) .fetchInto(String::class.java) diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/ReadProgressDtoDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/ReadProgressDtoDao.kt index 5bd92c406..5ffac33ae 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/ReadProgressDtoDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/ReadProgressDtoDao.kt @@ -1,14 +1,17 @@ package org.gotson.komga.infrastructure.jooq import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto +import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressV2Dto import org.gotson.komga.interfaces.rest.persistence.ReadProgressDtoRepository import org.gotson.komga.jooq.Tables +import org.jooq.AggregateFunction import org.jooq.Condition import org.jooq.DSLContext -import org.jooq.Record import org.jooq.Record2 +import org.jooq.impl.DSL import org.jooq.impl.DSL.rowNumber import org.springframework.stereotype.Component +import java.math.BigDecimal @Component class ReadProgressDtoDao( @@ -20,6 +23,10 @@ class ReadProgressDtoDao( private val d = Tables.BOOK_METADATA private val r = Tables.READ_PROGRESS + private val countUnread: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isNull, 1).otherwise(0)) + private val countRead: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0)) + private val countInProgress: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0)) + override fun findProgressBySeries(seriesId: String, userId: String): TachiyomiReadProgressDto { val indexedReadProgress = dsl.select( rowNumber().over().orderBy(d.NUMBER_SORT), @@ -33,19 +40,46 @@ class ReadProgressDtoDao( .fetch() .toList() - val booksCountRecord = dsl - .select(SeriesDtoDao.countUnread.`as`(BOOKS_UNREAD_COUNT)) - .select(SeriesDtoDao.countRead.`as`(BOOKS_READ_COUNT)) - .select(SeriesDtoDao.countInProgress.`as`(BOOKS_IN_PROGRESS_COUNT)) + val booksCount = getSeriesBooksCount(seriesId, userId) + + return booksCountToDto(booksCount, indexedReadProgress.lastRead() ?: 0) + } + + override fun findProgressV2BySeries(seriesId: String, userId: String): TachiyomiReadProgressV2Dto { + val numberSortReadProgress = dsl.select( + d.NUMBER_SORT, + r.COMPLETED, + ) .from(b) .leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId)) + .leftJoin(d).on(b.ID.eq(d.BOOK_ID)) .where(b.SERIES_ID.eq(seriesId)) + .orderBy(d.NUMBER_SORT) .fetch() - .first() + .toList() - return booksCountToDto(booksCountRecord, indexedReadProgress) + val booksCount = getSeriesBooksCount(seriesId, userId) + + return booksCountToDtoV2(booksCount, numberSortReadProgress.lastRead() ?: 0F) } + private fun getSeriesBooksCount(seriesId: String, userId: String) = dsl + .select(countUnread.`as`(BOOKS_UNREAD_COUNT)) + .select(countRead.`as`(BOOKS_READ_COUNT)) + .select(countInProgress.`as`(BOOKS_IN_PROGRESS_COUNT)) + .from(b) + .leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId)) + .where(b.SERIES_ID.eq(seriesId)) + .fetch() + .first() + .map { + BooksCount( + unreadCount = it.get(BOOKS_UNREAD_COUNT, Int::class.java), + readCount = it.get(BOOKS_READ_COUNT, Int::class.java), + inProgressCount = it.get(BOOKS_IN_PROGRESS_COUNT, Int::class.java), + ) + } + override fun findProgressByReadList(readListId: String, userId: String): TachiyomiReadProgressDto { val indexedReadProgress = dsl.select( rowNumber().over().orderBy(rlb.NUMBER), @@ -60,9 +94,9 @@ class ReadProgressDtoDao( .toList() val booksCountRecord = dsl - .select(SeriesDtoDao.countUnread.`as`(BOOKS_UNREAD_COUNT)) - .select(SeriesDtoDao.countRead.`as`(BOOKS_READ_COUNT)) - .select(SeriesDtoDao.countInProgress.`as`(BOOKS_IN_PROGRESS_COUNT)) + .select(countUnread.`as`(BOOKS_UNREAD_COUNT)) + .select(countRead.`as`(BOOKS_READ_COUNT)) + .select(countInProgress.`as`(BOOKS_IN_PROGRESS_COUNT)) .from(b) .leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId)) .leftJoin(rlb).on(b.ID.eq(rlb.BOOK_ID)) @@ -70,27 +104,46 @@ class ReadProgressDtoDao( .fetch() .first() - return booksCountToDto(booksCountRecord, indexedReadProgress) + val booksCount = BooksCount( + unreadCount = booksCountRecord.get(BOOKS_UNREAD_COUNT, Int::class.java), + readCount = booksCountRecord.get(BOOKS_READ_COUNT, Int::class.java), + inProgressCount = booksCountRecord.get(BOOKS_IN_PROGRESS_COUNT, Int::class.java), + ) + + return booksCountToDto(booksCount, indexedReadProgress.lastRead() ?: 0) } - private fun booksCountToDto(booksCountRecord: Record, indexedReadProgress: List>): TachiyomiReadProgressDto { - val booksUnreadCount = booksCountRecord.get(BOOKS_UNREAD_COUNT, Int::class.java) - val booksReadCount = booksCountRecord.get(BOOKS_READ_COUNT, Int::class.java) - val booksInProgressCount = booksCountRecord.get(BOOKS_IN_PROGRESS_COUNT, Int::class.java) - - val lastReadContinuousIndex = indexedReadProgress - .takeWhile { it.component2() == true } - .lastOrNull() - ?.component1() ?: 0 - - return TachiyomiReadProgressDto( - booksCount = booksUnreadCount + booksReadCount + booksInProgressCount, - booksUnreadCount = booksUnreadCount, - booksInProgressCount = booksInProgressCount, - booksReadCount = booksReadCount, + private fun booksCountToDto(booksCount: BooksCount, lastReadContinuousIndex: Int): TachiyomiReadProgressDto = + TachiyomiReadProgressDto( + booksCount = booksCount.totalCount, + booksUnreadCount = booksCount.unreadCount, + booksInProgressCount = booksCount.inProgressCount, + booksReadCount = booksCount.readCount, lastReadContinuousIndex = lastReadContinuousIndex, ) - } + + private fun booksCountToDtoV2(booksCount: BooksCount, lastReadContinuousNumberSort: Float): TachiyomiReadProgressV2Dto = + TachiyomiReadProgressV2Dto( + booksCount = booksCount.totalCount, + booksUnreadCount = booksCount.unreadCount, + booksInProgressCount = booksCount.inProgressCount, + booksReadCount = booksCount.readCount, + lastReadContinuousNumberSort = lastReadContinuousNumberSort, + ) private fun readProgressCondition(userId: String): Condition = r.USER_ID.eq(userId).or(r.USER_ID.isNull) + + private fun List>.lastRead(): T? = + this.takeWhile { it.component2() == true } + .lastOrNull() + ?.component1() + + private data class BooksCount( + val unreadCount: Int, + val readCount: Int, + val inProgressCount: Int, + ) { + val totalCount + get() = unreadCount + readCount + inProgressCount + } } diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/SeriesDtoDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/SeriesDtoDao.kt index 7280454a4..d7957350d 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/SeriesDtoDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/SeriesDtoDao.kt @@ -18,7 +18,6 @@ import org.gotson.komga.jooq.Tables import org.gotson.komga.jooq.tables.records.BookMetadataAggregationRecord import org.gotson.komga.jooq.tables.records.SeriesMetadataRecord import org.gotson.komga.jooq.tables.records.SeriesRecord -import org.jooq.AggregateFunction import org.jooq.Condition import org.jooq.DSLContext import org.jooq.Record @@ -34,7 +33,6 @@ import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Pageable import org.springframework.data.domain.Sort import org.springframework.stereotype.Component -import java.math.BigDecimal import java.net.URL private val logger = KotlinLogging.logger {} @@ -50,22 +48,15 @@ class SeriesDtoDao( private val luceneHelper: LuceneHelper, ) : SeriesDtoRepository { - companion object { - private val s = Tables.SERIES - private val d = Tables.SERIES_METADATA - private val r = Tables.READ_PROGRESS - private val rs = Tables.READ_PROGRESS_SERIES - private val cs = Tables.COLLECTION_SERIES - private val g = Tables.SERIES_METADATA_GENRE - private val st = Tables.SERIES_METADATA_TAG - private val bma = Tables.BOOK_METADATA_AGGREGATION - private val bmaa = Tables.BOOK_METADATA_AGGREGATION_AUTHOR - private val bmat = Tables.BOOK_METADATA_AGGREGATION_TAG - - val countUnread: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isNull, 1).otherwise(0)) - val countRead: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0)) - val countInProgress: AggregateFunction = DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0)) - } + private val s = Tables.SERIES + private val d = Tables.SERIES_METADATA + private val rs = Tables.READ_PROGRESS_SERIES + private val cs = Tables.COLLECTION_SERIES + private val g = Tables.SERIES_METADATA_GENRE + private val st = Tables.SERIES_METADATA_TAG + private val bma = Tables.BOOK_METADATA_AGGREGATION + private val bmaa = Tables.BOOK_METADATA_AGGREGATION_AUTHOR + private val bmat = Tables.BOOK_METADATA_AGGREGATION_TAG private val groupFields = arrayOf( *s.fields(), diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/SeriesController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/SeriesController.kt index d71bc521e..0121b1968 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/SeriesController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/SeriesController.kt @@ -44,6 +44,8 @@ import org.gotson.komga.interfaces.rest.dto.SeriesDto import org.gotson.komga.interfaces.rest.dto.SeriesMetadataUpdateDto import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressUpdateDto +import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressUpdateV2Dto +import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressV2Dto import org.gotson.komga.interfaces.rest.dto.restrictUrl import org.gotson.komga.interfaces.rest.dto.toDto import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository @@ -81,7 +83,7 @@ import javax.validation.Valid private val logger = KotlinLogging.logger {} @RestController -@RequestMapping("api/v1/series", produces = [MediaType.APPLICATION_JSON_VALUE]) +@RequestMapping("api", produces = [MediaType.APPLICATION_JSON_VALUE]) class SeriesController( private val taskReceiver: TaskReceiver, private val seriesRepository: SeriesRepository, @@ -104,7 +106,7 @@ class SeriesController( `in` = ParameterIn.QUERY, name = "search_regex", schema = Schema(type = "string") ) ) - @GetMapping + @GetMapping("v1/series") fun getAllSeries( @AuthenticationPrincipal principal: KomgaPrincipal, @RequestParam(name = "search", required = false) searchTerm: String?, @@ -173,7 +175,7 @@ class SeriesController( `in` = ParameterIn.QUERY, name = "search_regex", schema = Schema(type = "string") ) ) - @GetMapping("alphabetical-groups") + @GetMapping("v1/series/alphabetical-groups") fun getAlphabeticalGroups( @AuthenticationPrincipal principal: KomgaPrincipal, @RequestParam(name = "search", required = false) searchTerm: String?, @@ -220,7 +222,7 @@ class SeriesController( @Operation(description = "Return recently added or updated series.") @PageableWithoutSortAsQueryParam - @GetMapping("/latest") + @GetMapping("v1/series//latest") fun getLatestSeries( @AuthenticationPrincipal principal: KomgaPrincipal, @RequestParam(name = "library_id", required = false) libraryIds: List?, @@ -250,7 +252,7 @@ class SeriesController( @Operation(description = "Return newly added series.") @PageableWithoutSortAsQueryParam - @GetMapping("/new") + @GetMapping("v1/series/new") fun getNewSeries( @AuthenticationPrincipal principal: KomgaPrincipal, @RequestParam(name = "library_id", required = false) libraryIds: List?, @@ -280,7 +282,7 @@ class SeriesController( @Operation(description = "Return recently updated series, but not newly added ones.") @PageableWithoutSortAsQueryParam - @GetMapping("/updated") + @GetMapping("v1/series/updated") fun getUpdatedSeries( @AuthenticationPrincipal principal: KomgaPrincipal, @RequestParam(name = "library_id", required = false) libraryIds: List?, @@ -308,7 +310,7 @@ class SeriesController( ).map { it.restrictUrl(!principal.user.roleAdmin) } } - @GetMapping("{seriesId}") + @GetMapping("v1/series/{seriesId}") fun getOneSeries( @AuthenticationPrincipal principal: KomgaPrincipal, @PathVariable(name = "seriesId") id: String @@ -319,7 +321,7 @@ class SeriesController( } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) @ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))]) - @GetMapping(value = ["{seriesId}/thumbnail"], produces = [MediaType.IMAGE_JPEG_VALUE]) + @GetMapping(value = ["v1/series/{seriesId}/thumbnail"], produces = [MediaType.IMAGE_JPEG_VALUE]) fun getSeriesThumbnail( @AuthenticationPrincipal principal: KomgaPrincipal, @PathVariable(name = "seriesId") seriesId: String @@ -334,7 +336,7 @@ class SeriesController( @PageableAsQueryParam @AuthorsAsQueryParam - @GetMapping("{seriesId}/books") + @GetMapping("v1/series/{seriesId}/books") fun getAllBooksBySeries( @AuthenticationPrincipal principal: KomgaPrincipal, @PathVariable(name = "seriesId") seriesId: String, @@ -375,7 +377,7 @@ class SeriesController( ).map { it.restrictUrl(!principal.user.roleAdmin) } } - @GetMapping("{seriesId}/collections") + @GetMapping("v1/series/{seriesId}/collections") fun getAllCollectionsBySeries( @AuthenticationPrincipal principal: KomgaPrincipal, @PathVariable(name = "seriesId") seriesId: String @@ -388,7 +390,7 @@ class SeriesController( .map { it.toDto() } } - @PostMapping("{seriesId}/analyze") + @PostMapping("v1/series/{seriesId}/analyze") @PreAuthorize("hasRole('$ROLE_ADMIN')") @ResponseStatus(HttpStatus.ACCEPTED) fun analyze(@PathVariable seriesId: String) { @@ -397,7 +399,7 @@ class SeriesController( } } - @PostMapping("{seriesId}/metadata/refresh") + @PostMapping("v1/series/{seriesId}/metadata/refresh") @PreAuthorize("hasRole('$ROLE_ADMIN')") @ResponseStatus(HttpStatus.ACCEPTED) fun refreshMetadata(@PathVariable seriesId: String) { @@ -408,7 +410,7 @@ class SeriesController( taskReceiver.refreshSeriesLocalArtwork(seriesId, priority = HIGH_PRIORITY) } - @PatchMapping("{seriesId}/metadata") + @PatchMapping("v1/series/{seriesId}/metadata") @PreAuthorize("hasRole('$ROLE_ADMIN')") @ResponseStatus(HttpStatus.NO_CONTENT) fun updateMetadata( @@ -454,7 +456,7 @@ class SeriesController( } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) @Operation(description = "Mark all book for series as read") - @PostMapping("{seriesId}/read-progress") + @PostMapping("v1/series/{seriesId}/read-progress") @ResponseStatus(HttpStatus.NO_CONTENT) fun markAsRead( @PathVariable seriesId: String, @@ -468,7 +470,7 @@ class SeriesController( } @Operation(description = "Mark all book for series as unread") - @DeleteMapping("{seriesId}/read-progress") + @DeleteMapping("v1/series/{seriesId}/read-progress") @ResponseStatus(HttpStatus.NO_CONTENT) fun markAsUnread( @PathVariable seriesId: String, @@ -481,7 +483,8 @@ class SeriesController( seriesLifecycle.deleteReadProgress(seriesId, principal.user) } - @GetMapping("{seriesId}/read-progress/tachiyomi") + @Deprecated("Use v2 for proper handling of chapter number with numberSort") + @GetMapping("v1/series/{seriesId}/read-progress/tachiyomi") fun getReadProgressTachiyomi( @PathVariable seriesId: String, @AuthenticationPrincipal principal: KomgaPrincipal, @@ -491,7 +494,18 @@ class SeriesController( return readProgressDtoRepository.findProgressBySeries(seriesId, principal.user.id) } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) - @PutMapping("{seriesId}/read-progress/tachiyomi") + @GetMapping("v2/series/{seriesId}/read-progress/tachiyomi") + fun getReadProgressTachiyomiV2( + @PathVariable seriesId: String, + @AuthenticationPrincipal principal: KomgaPrincipal, + ): TachiyomiReadProgressV2Dto = + seriesRepository.getLibraryId(seriesId)?.let { + if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN) + return readProgressDtoRepository.findProgressV2BySeries(seriesId, principal.user.id) + } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + + @Deprecated("Use v2 for proper handling of chapter number with numberSort") + @PutMapping("v1/series/{seriesId}/read-progress/tachiyomi") @ResponseStatus(HttpStatus.NO_CONTENT) fun markReadProgressTachiyomi( @PathVariable seriesId: String, @@ -513,7 +527,29 @@ class SeriesController( } } - @GetMapping("{seriesId}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE]) + @PutMapping("v2/series/{seriesId}/read-progress/tachiyomi") + @ResponseStatus(HttpStatus.NO_CONTENT) + fun markReadProgressTachiyomiV2( + @PathVariable seriesId: String, + @RequestBody readProgress: TachiyomiReadProgressUpdateV2Dto, + @AuthenticationPrincipal principal: KomgaPrincipal, + ) { + seriesRepository.getLibraryId(seriesId)?.let { + if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN) + } ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + + bookDtoRepository.findAll( + BookSearchWithReadProgress(seriesIds = listOf(seriesId)), + principal.user.id, + UnpagedSorted(Sort.by(Sort.Order.asc("metadata.numberSort"))), + ).toList().filter { book -> book.metadata.numberSort <= readProgress.lastBookNumberSortRead } + .forEach { book -> + if (book.readProgress?.completed != true) + bookLifecycle.markReadProgressCompleted(book.id, principal.user) + } + } + + @GetMapping("v1/series/{seriesId}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE]) @PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')") fun getSeriesFile( @AuthenticationPrincipal principal: KomgaPrincipal, diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/SeriesDto.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/SeriesDto.kt index 1c501d4cd..69062d344 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/SeriesDto.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/SeriesDto.kt @@ -3,7 +3,6 @@ package org.gotson.komga.interfaces.rest.dto import com.fasterxml.jackson.annotation.JsonFormat import java.time.LocalDate import java.time.LocalDateTime -import javax.validation.constraints.PositiveOrZero data class SeriesDto( val id: String, @@ -71,7 +70,3 @@ data class BookMetadataAggregationDto( @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss") val lastModified: LocalDateTime ) - -data class TachiyomiReadProgressUpdateDto( - @get:PositiveOrZero val lastBookRead: Int, -) diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressUpdateDto.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressUpdateDto.kt new file mode 100644 index 000000000..139e4b2ec --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressUpdateDto.kt @@ -0,0 +1,11 @@ +package org.gotson.komga.interfaces.rest.dto + +import javax.validation.constraints.PositiveOrZero + +data class TachiyomiReadProgressUpdateDto( + @get:PositiveOrZero val lastBookRead: Int, +) + +data class TachiyomiReadProgressUpdateV2Dto( + val lastBookNumberSortRead: Float, +) diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressV2Dto.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressV2Dto.kt new file mode 100644 index 000000000..1ede7781d --- /dev/null +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/dto/TachiyomiReadProgressV2Dto.kt @@ -0,0 +1,9 @@ +package org.gotson.komga.interfaces.rest.dto + +data class TachiyomiReadProgressV2Dto( + val booksCount: Int, + val booksReadCount: Int, + val booksUnreadCount: Int, + val booksInProgressCount: Int, + val lastReadContinuousNumberSort: Float, +) diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/persistence/ReadProgressDtoRepository.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/persistence/ReadProgressDtoRepository.kt index c2fd2c183..9d08b34ad 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/persistence/ReadProgressDtoRepository.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/persistence/ReadProgressDtoRepository.kt @@ -1,8 +1,10 @@ package org.gotson.komga.interfaces.rest.persistence import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto +import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressV2Dto interface ReadProgressDtoRepository { fun findProgressBySeries(seriesId: String, userId: String,): TachiyomiReadProgressDto + fun findProgressV2BySeries(seriesId: String, userId: String,): TachiyomiReadProgressV2Dto fun findProgressByReadList(readListId: String, userId: String,): TachiyomiReadProgressDto }