mirror of
https://github.com/gotson/komga.git
synced 2026-05-09 05:10:19 +02:00
fix(api): better handling of tachiyomi tracking
read progress returns the last book read in a continuous fashion don't mark books as unread when tachiyomi updates progress, only read
This commit is contained in:
parent
571d54a526
commit
a7ab0da025
8 changed files with 158 additions and 101 deletions
|
|
@ -0,0 +1,96 @@
|
||||||
|
package org.gotson.komga.infrastructure.jooq
|
||||||
|
|
||||||
|
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto
|
||||||
|
import org.gotson.komga.interfaces.rest.persistence.ReadProgressDtoRepository
|
||||||
|
import org.gotson.komga.jooq.Tables
|
||||||
|
import org.jooq.Condition
|
||||||
|
import org.jooq.DSLContext
|
||||||
|
import org.jooq.Record
|
||||||
|
import org.jooq.Record2
|
||||||
|
import org.jooq.impl.DSL.rowNumber
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class ReadProgressDtoDao(
|
||||||
|
private val dsl: DSLContext
|
||||||
|
) : ReadProgressDtoRepository {
|
||||||
|
|
||||||
|
private val rlb = Tables.READLIST_BOOK
|
||||||
|
private val b = Tables.BOOK
|
||||||
|
private val d = Tables.BOOK_METADATA
|
||||||
|
private val r = Tables.READ_PROGRESS
|
||||||
|
|
||||||
|
override fun getProgressBySeries(seriesId: String, userId: String): TachiyomiReadProgressDto {
|
||||||
|
val indexedReadProgress = dsl.select(
|
||||||
|
rowNumber().over().orderBy(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()
|
||||||
|
.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))
|
||||||
|
.from(b)
|
||||||
|
.leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId))
|
||||||
|
.where(b.SERIES_ID.eq(seriesId))
|
||||||
|
.fetch()
|
||||||
|
.first()
|
||||||
|
|
||||||
|
return booksCountToDto(booksCountRecord, indexedReadProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getProgressByReadList(readListId: String, userId: String): TachiyomiReadProgressDto {
|
||||||
|
val indexedReadProgress = dsl.select(
|
||||||
|
rowNumber().over().orderBy(rlb.NUMBER),
|
||||||
|
r.COMPLETED,
|
||||||
|
)
|
||||||
|
.from(b)
|
||||||
|
.leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId))
|
||||||
|
.leftJoin(rlb).on(b.ID.eq(rlb.BOOK_ID))
|
||||||
|
.where(rlb.READLIST_ID.eq(readListId))
|
||||||
|
.orderBy(rlb.NUMBER)
|
||||||
|
.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))
|
||||||
|
.from(b)
|
||||||
|
.leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId))
|
||||||
|
.leftJoin(rlb).on(b.ID.eq(rlb.BOOK_ID))
|
||||||
|
.where(rlb.READLIST_ID.eq(readListId))
|
||||||
|
.fetch()
|
||||||
|
.first()
|
||||||
|
|
||||||
|
return booksCountToDto(booksCountRecord, indexedReadProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun booksCountToDto(booksCountRecord: Record, indexedReadProgress: List<Record2<Int, Boolean>>): 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,
|
||||||
|
lastReadContinuousIndex = lastReadContinuousIndex,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readProgressCondition(userId: String): Condition = r.USER_ID.eq(userId).or(r.USER_ID.isNull)
|
||||||
|
}
|
||||||
|
|
@ -18,14 +18,14 @@ import org.gotson.komga.infrastructure.swagger.PageableWithoutSortAsQueryParam
|
||||||
import org.gotson.komga.interfaces.rest.dto.BookDto
|
import org.gotson.komga.interfaces.rest.dto.BookDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListCreationDto
|
import org.gotson.komga.interfaces.rest.dto.ReadListCreationDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListDto
|
import org.gotson.komga.interfaces.rest.dto.ReadListDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListProgressDto
|
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListRequestResultDto
|
import org.gotson.komga.interfaces.rest.dto.ReadListRequestResultDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListUpdateDto
|
import org.gotson.komga.interfaces.rest.dto.ReadListUpdateDto
|
||||||
|
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressUpdateDto
|
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressUpdateDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.restrictUrl
|
import org.gotson.komga.interfaces.rest.dto.restrictUrl
|
||||||
import org.gotson.komga.interfaces.rest.dto.toDto
|
import org.gotson.komga.interfaces.rest.dto.toDto
|
||||||
import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository
|
import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository
|
||||||
import org.gotson.komga.interfaces.rest.persistence.ReadListDtoRepository
|
import org.gotson.komga.interfaces.rest.persistence.ReadProgressDtoRepository
|
||||||
import org.springframework.data.domain.Page
|
import org.springframework.data.domain.Page
|
||||||
import org.springframework.data.domain.PageRequest
|
import org.springframework.data.domain.PageRequest
|
||||||
import org.springframework.data.domain.Pageable
|
import org.springframework.data.domain.Pageable
|
||||||
|
|
@ -41,6 +41,7 @@ import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PatchMapping
|
import org.springframework.web.bind.annotation.PatchMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
|
@ -59,7 +60,7 @@ class ReadListController(
|
||||||
private val readListRepository: ReadListRepository,
|
private val readListRepository: ReadListRepository,
|
||||||
private val readListLifecycle: ReadListLifecycle,
|
private val readListLifecycle: ReadListLifecycle,
|
||||||
private val bookDtoRepository: BookDtoRepository,
|
private val bookDtoRepository: BookDtoRepository,
|
||||||
private val readListDtoRepository: ReadListDtoRepository,
|
private val readProgressDtoRepository: ReadProgressDtoRepository,
|
||||||
private val bookLifecycle: BookLifecycle,
|
private val bookLifecycle: BookLifecycle,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
@ -242,18 +243,18 @@ class ReadListController(
|
||||||
?.restrictUrl(!principal.user.roleAdmin)
|
?.restrictUrl(!principal.user.roleAdmin)
|
||||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||||
|
|
||||||
@GetMapping("{id}/read-progress")
|
@GetMapping("{id}/read-progress/tachiyomi")
|
||||||
fun getReadProgress(
|
fun getReadProgress(
|
||||||
@PathVariable id: String,
|
@PathVariable id: String,
|
||||||
@AuthenticationPrincipal principal: KomgaPrincipal
|
@AuthenticationPrincipal principal: KomgaPrincipal
|
||||||
): ReadListProgressDto =
|
): TachiyomiReadProgressDto =
|
||||||
readListRepository.findByIdOrNull(id, principal.user.getAuthorizedLibraryIds(null))?.let { readList ->
|
readListRepository.findByIdOrNull(id, principal.user.getAuthorizedLibraryIds(null))?.let { readList ->
|
||||||
readListDtoRepository.getProgress(readList.id, principal.user.id)
|
readProgressDtoRepository.getProgressByReadList(readList.id, principal.user.id)
|
||||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||||
|
|
||||||
@PatchMapping("{id}/read-progress/tachiyomi")
|
@PutMapping("{id}/read-progress/tachiyomi")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
fun markReadProgress(
|
fun markReadProgressTachiyomi(
|
||||||
@PathVariable id: String,
|
@PathVariable id: String,
|
||||||
@Valid @RequestBody readProgress: TachiyomiReadProgressUpdateDto,
|
@Valid @RequestBody readProgress: TachiyomiReadProgressUpdateDto,
|
||||||
@AuthenticationPrincipal principal: KomgaPrincipal
|
@AuthenticationPrincipal principal: KomgaPrincipal
|
||||||
|
|
@ -264,12 +265,8 @@ class ReadListController(
|
||||||
principal.user.id,
|
principal.user.id,
|
||||||
principal.user.getAuthorizedLibraryIds(null),
|
principal.user.getAuthorizedLibraryIds(null),
|
||||||
UnpagedSorted(Sort.by(Sort.Order.asc("readList.number")))
|
UnpagedSorted(Sort.by(Sort.Order.asc("readList.number")))
|
||||||
).forEachIndexed { index, book ->
|
).filterIndexed { index, _ -> index < readProgress.lastBookRead }
|
||||||
if (index < readProgress.lastBookRead)
|
.forEach { book -> bookLifecycle.markReadProgressCompleted(book.id, principal.user) }
|
||||||
bookLifecycle.markReadProgressCompleted(book.id, principal.user)
|
|
||||||
else
|
|
||||||
bookLifecycle.deleteReadProgress(book.id, principal.user)
|
|
||||||
}
|
|
||||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,12 @@ import org.gotson.komga.interfaces.rest.dto.BookDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.CollectionDto
|
import org.gotson.komga.interfaces.rest.dto.CollectionDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.SeriesDto
|
import org.gotson.komga.interfaces.rest.dto.SeriesDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.SeriesMetadataUpdateDto
|
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.TachiyomiReadProgressUpdateDto
|
||||||
import org.gotson.komga.interfaces.rest.dto.restrictUrl
|
import org.gotson.komga.interfaces.rest.dto.restrictUrl
|
||||||
import org.gotson.komga.interfaces.rest.dto.toDto
|
import org.gotson.komga.interfaces.rest.dto.toDto
|
||||||
import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository
|
import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository
|
||||||
|
import org.gotson.komga.interfaces.rest.persistence.ReadProgressDtoRepository
|
||||||
import org.gotson.komga.interfaces.rest.persistence.SeriesDtoRepository
|
import org.gotson.komga.interfaces.rest.persistence.SeriesDtoRepository
|
||||||
import org.springframework.core.io.FileSystemResource
|
import org.springframework.core.io.FileSystemResource
|
||||||
import org.springframework.data.domain.Page
|
import org.springframework.data.domain.Page
|
||||||
|
|
@ -57,6 +59,7 @@ import org.springframework.web.bind.annotation.GetMapping
|
||||||
import org.springframework.web.bind.annotation.PatchMapping
|
import org.springframework.web.bind.annotation.PatchMapping
|
||||||
import org.springframework.web.bind.annotation.PathVariable
|
import org.springframework.web.bind.annotation.PathVariable
|
||||||
import org.springframework.web.bind.annotation.PostMapping
|
import org.springframework.web.bind.annotation.PostMapping
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping
|
||||||
import org.springframework.web.bind.annotation.RequestBody
|
import org.springframework.web.bind.annotation.RequestBody
|
||||||
import org.springframework.web.bind.annotation.RequestMapping
|
import org.springframework.web.bind.annotation.RequestMapping
|
||||||
import org.springframework.web.bind.annotation.RequestParam
|
import org.springframework.web.bind.annotation.RequestParam
|
||||||
|
|
@ -81,7 +84,8 @@ class SeriesController(
|
||||||
private val bookLifecycle: BookLifecycle,
|
private val bookLifecycle: BookLifecycle,
|
||||||
private val bookRepository: BookRepository,
|
private val bookRepository: BookRepository,
|
||||||
private val bookDtoRepository: BookDtoRepository,
|
private val bookDtoRepository: BookDtoRepository,
|
||||||
private val collectionRepository: SeriesCollectionRepository
|
private val collectionRepository: SeriesCollectionRepository,
|
||||||
|
private val readProgressDtoRepository: ReadProgressDtoRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@PageableAsQueryParam
|
@PageableAsQueryParam
|
||||||
|
|
@ -364,29 +368,6 @@ class SeriesController(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PatchMapping("{seriesId}/read-progress/tachiyomi")
|
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
|
||||||
fun markReadProgress(
|
|
||||||
@PathVariable seriesId: String,
|
|
||||||
@Valid @RequestBody readProgress: TachiyomiReadProgressUpdateDto,
|
|
||||||
@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"))),
|
|
||||||
).forEachIndexed { index, book ->
|
|
||||||
if (index < readProgress.lastBookRead)
|
|
||||||
bookLifecycle.markReadProgressCompleted(book.id, principal.user)
|
|
||||||
else
|
|
||||||
bookLifecycle.deleteReadProgress(book.id, principal.user)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("{seriesId}/read-progress")
|
@DeleteMapping("{seriesId}/read-progress")
|
||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
fun markAsUnread(
|
fun markAsUnread(
|
||||||
|
|
@ -402,6 +383,35 @@ class SeriesController(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("{seriesId}/read-progress/tachiyomi")
|
||||||
|
fun getReadProgressTachiyomi(
|
||||||
|
@PathVariable seriesId: String,
|
||||||
|
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||||
|
): TachiyomiReadProgressDto =
|
||||||
|
seriesRepository.getLibraryId(seriesId)?.let {
|
||||||
|
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN)
|
||||||
|
return readProgressDtoRepository.getProgressBySeries(seriesId, principal.user.id)
|
||||||
|
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||||
|
|
||||||
|
@PutMapping("{seriesId}/read-progress/tachiyomi")
|
||||||
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
|
fun markReadProgressTachiyomi(
|
||||||
|
@PathVariable seriesId: String,
|
||||||
|
@Valid @RequestBody readProgress: TachiyomiReadProgressUpdateDto,
|
||||||
|
@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"))),
|
||||||
|
).filterIndexed { index, _ -> index < readProgress.lastBookRead }
|
||||||
|
.forEach { book -> bookLifecycle.markReadProgressCompleted(book.id, principal.user) }
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("{seriesId}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
|
@GetMapping("{seriesId}/file", produces = [MediaType.APPLICATION_OCTET_STREAM_VALUE])
|
||||||
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
|
@PreAuthorize("hasRole('$ROLE_FILE_DOWNLOAD')")
|
||||||
fun getSeriesFile(
|
fun getSeriesFile(
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,6 @@ data class ReadListDto(
|
||||||
val filtered: Boolean
|
val filtered: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ReadListProgressDto(
|
|
||||||
val booksCount: Int,
|
|
||||||
val booksReadCount: Int,
|
|
||||||
val booksUnreadCount: Int,
|
|
||||||
val booksInProgressCount: Int,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun ReadList.toDto() =
|
fun ReadList.toDto() =
|
||||||
ReadListDto(
|
ReadListDto(
|
||||||
id = id,
|
id = id,
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
package org.gotson.komga.interfaces.rest.dto
|
|
||||||
|
|
||||||
import org.gotson.komga.infrastructure.jooq.BOOKS_IN_PROGRESS_COUNT
|
|
||||||
import org.gotson.komga.infrastructure.jooq.BOOKS_READ_COUNT
|
|
||||||
import org.gotson.komga.infrastructure.jooq.BOOKS_UNREAD_COUNT
|
|
||||||
import org.gotson.komga.infrastructure.jooq.SeriesDtoDao
|
|
||||||
import org.gotson.komga.interfaces.rest.persistence.ReadListDtoRepository
|
|
||||||
import org.gotson.komga.jooq.Tables
|
|
||||||
import org.jooq.Condition
|
|
||||||
import org.jooq.DSLContext
|
|
||||||
import org.springframework.stereotype.Component
|
|
||||||
|
|
||||||
@Component
|
|
||||||
class ReadListDtoDao(
|
|
||||||
private val dsl: DSLContext
|
|
||||||
) : ReadListDtoRepository {
|
|
||||||
|
|
||||||
private val rl = Tables.READLIST
|
|
||||||
private val rlb = Tables.READLIST_BOOK
|
|
||||||
private val b = Tables.BOOK
|
|
||||||
private val r = Tables.READ_PROGRESS
|
|
||||||
|
|
||||||
override fun getProgress(readListId: String, userId: String): ReadListProgressDto {
|
|
||||||
|
|
||||||
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))
|
|
||||||
.from(b)
|
|
||||||
.leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(readProgressCondition(userId))
|
|
||||||
.leftJoin(rlb).on(b.ID.eq(rlb.BOOK_ID))
|
|
||||||
.where(rlb.READLIST_ID.eq(readListId))
|
|
||||||
.fetch()
|
|
||||||
.first()
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
return ReadListProgressDto(
|
|
||||||
booksCount = booksUnreadCount + booksReadCount + booksInProgressCount,
|
|
||||||
booksUnreadCount = booksUnreadCount,
|
|
||||||
booksInProgressCount = booksInProgressCount,
|
|
||||||
booksReadCount = booksReadCount,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun readProgressCondition(userId: String): Condition = r.USER_ID.eq(userId).or(r.USER_ID.isNull)
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.gotson.komga.interfaces.rest.dto
|
||||||
|
|
||||||
|
data class TachiyomiReadProgressDto(
|
||||||
|
val booksCount: Int,
|
||||||
|
val booksReadCount: Int,
|
||||||
|
val booksUnreadCount: Int,
|
||||||
|
val booksInProgressCount: Int,
|
||||||
|
val lastReadContinuousIndex: Int,
|
||||||
|
)
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package org.gotson.komga.interfaces.rest.persistence
|
|
||||||
|
|
||||||
import org.gotson.komga.interfaces.rest.dto.ReadListProgressDto
|
|
||||||
|
|
||||||
interface ReadListDtoRepository {
|
|
||||||
fun getProgress(readListId: String, userId: String,): ReadListProgressDto
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.gotson.komga.interfaces.rest.persistence
|
||||||
|
|
||||||
|
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressDto
|
||||||
|
|
||||||
|
interface ReadProgressDtoRepository {
|
||||||
|
fun getProgressBySeries(seriesId: String, userId: String,): TachiyomiReadProgressDto
|
||||||
|
fun getProgressByReadList(readListId: String, userId: String,): TachiyomiReadProgressDto
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue