feat(api): mark read progress for read lists with Tachiyomi format

This commit is contained in:
Gauthier Roebroeck 2021-05-10 17:54:16 +08:00
parent 82af4b3bbf
commit 0177ee3e08
4 changed files with 101 additions and 1 deletions

View file

@ -9,6 +9,7 @@ import org.gotson.komga.domain.model.DuplicateNameException
import org.gotson.komga.domain.model.ROLE_ADMIN
import org.gotson.komga.domain.model.ReadList
import org.gotson.komga.domain.persistence.ReadListRepository
import org.gotson.komga.domain.service.BookLifecycle
import org.gotson.komga.domain.service.ReadListLifecycle
import org.gotson.komga.infrastructure.jooq.UnpagedSorted
import org.gotson.komga.infrastructure.language.toIndexedMap
@ -17,11 +18,14 @@ import org.gotson.komga.infrastructure.swagger.PageableWithoutSortAsQueryParam
import org.gotson.komga.interfaces.rest.dto.BookDto
import org.gotson.komga.interfaces.rest.dto.ReadListCreationDto
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.ReadListUpdateDto
import org.gotson.komga.interfaces.rest.dto.TachiyomiReadProgressUpdateDto
import org.gotson.komga.interfaces.rest.dto.restrictUrl
import org.gotson.komga.interfaces.rest.dto.toDto
import org.gotson.komga.interfaces.rest.persistence.BookDtoRepository
import org.gotson.komga.interfaces.rest.persistence.ReadListDtoRepository
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
@ -54,7 +58,9 @@ private val logger = KotlinLogging.logger {}
class ReadListController(
private val readListRepository: ReadListRepository,
private val readListLifecycle: ReadListLifecycle,
private val bookDtoRepository: BookDtoRepository
private val bookDtoRepository: BookDtoRepository,
private val readListDtoRepository: ReadListDtoRepository,
private val bookLifecycle: BookLifecycle,
) {
@PageableWithoutSortAsQueryParam
@ -235,4 +241,35 @@ class ReadListController(
)
?.restrictUrl(!principal.user.roleAdmin)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@GetMapping("{id}/read-progress")
fun getReadProgress(
@PathVariable id: String,
@AuthenticationPrincipal principal: KomgaPrincipal
): ReadListProgressDto =
readListRepository.findByIdOrNull(id, principal.user.getAuthorizedLibraryIds(null))?.let { readList ->
readListDtoRepository.getProgress(readList.id, principal.user.id)
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
@PatchMapping("{id}/read-progress/tachiyomi")
@ResponseStatus(HttpStatus.NO_CONTENT)
fun markReadProgress(
@PathVariable id: String,
@Valid @RequestBody readProgress: TachiyomiReadProgressUpdateDto,
@AuthenticationPrincipal principal: KomgaPrincipal
) {
readListRepository.findByIdOrNull(id, principal.user.getAuthorizedLibraryIds(null))?.let { readList ->
bookDtoRepository.findByReadListId(
readList.id,
principal.user.id,
principal.user.getAuthorizedLibraryIds(null),
UnpagedSorted(Sort.by(Sort.Order.asc("readList.number")))
).forEachIndexed { index, book ->
if (index < readProgress.lastBookRead)
bookLifecycle.markReadProgressCompleted(book.id, principal.user)
else
bookLifecycle.deleteReadProgress(book.id, principal.user)
}
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
}
}

View file

@ -18,6 +18,13 @@ data class ReadListDto(
val filtered: Boolean
)
data class ReadListProgressDto(
val booksCount: Int,
val booksReadCount: Int,
val booksUnreadCount: Int,
val booksInProgressCount: Int,
)
fun ReadList.toDto() =
ReadListDto(
id = id,

View file

@ -0,0 +1,49 @@
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)
}

View file

@ -0,0 +1,7 @@
package org.gotson.komga.interfaces.rest.persistence
import org.gotson.komga.interfaces.rest.dto.ReadListProgressDto
interface ReadListDtoRepository {
fun getProgress(readListId: String, userId: String,): ReadListProgressDto
}