Skip to content

Commit

Permalink
feat(api): on deck books
Browse files Browse the repository at this point in the history
related to #131
  • Loading branch information
gotson committed Jun 8, 2020
1 parent f5948bd commit 1b6a030
Show file tree
Hide file tree
Showing 5 changed files with 259 additions and 137 deletions.
Expand Up @@ -35,6 +35,7 @@ class BookDtoDao(
private val d = Tables.BOOK_METADATA
private val r = Tables.READ_PROGRESS
private val a = Tables.BOOK_METADATA_AUTHOR
private val s = Tables.SERIES

private val mediaFields = m.fields().filterNot { it.name == m.THUMBNAIL.name }.toTypedArray()

Expand Down Expand Up @@ -86,6 +87,43 @@ class BookDtoDao(

override fun findNextInSeries(bookId: Long, userId: Long): BookDto? = findSibling(bookId, userId, next = true)


override fun findOnDeck(libraryIds: Collection<Long>, userId: Long, pageable: Pageable): Page<BookDto> {
val conditions = if (libraryIds.isEmpty()) DSL.trueCondition() else s.LIBRARY_ID.`in`(libraryIds)

val seriesIds = dsl.select(s.ID)
.from(s)
.leftJoin(b).on(s.ID.eq(b.SERIES_ID))
.leftJoin(r).on(b.ID.eq(r.BOOK_ID))
.and(readProgressCondition(userId))
.where(conditions)
.groupBy(s.ID)
.having(SeriesDtoDao.countUnread.ge(1.toBigDecimal()))
.and(SeriesDtoDao.countRead.ge(1.toBigDecimal()))
.and(SeriesDtoDao.countInProgress.eq(0.toBigDecimal()))
.orderBy(DSL.max(r.LAST_MODIFIED_DATE).desc())
.fetchInto(Long::class.java)

val dtos = seriesIds
.drop(pageable.pageNumber * pageable.pageSize)
.take(pageable.pageSize)
.mapNotNull { seriesId ->
selectBase(userId)
.where(b.SERIES_ID.eq(seriesId))
.and(r.COMPLETED.isNull)
.orderBy(d.NUMBER_SORT.asc())
.limit(1)
.fetchAndMap()
.firstOrNull()
}

return PageImpl(
dtos,
PageRequest.of(pageable.pageNumber, pageable.pageSize, pageable.sort),
seriesIds.size.toLong()
)
}

private fun readProgressCondition(userId: Long): Condition = r.USER_ID.eq(userId).or(r.USER_ID.isNull)

private fun findSibling(bookId: Long, userId: Long, next: Boolean): BookDto? {
Expand Down
Expand Up @@ -34,20 +34,22 @@ class SeriesDtoDao(
private val dsl: DSLContext
) : SeriesDtoRepository {

private val s = Tables.SERIES
private val b = Tables.BOOK
private val d = Tables.SERIES_METADATA
private val r = Tables.READ_PROGRESS
companion object {
private val s = Tables.SERIES
private val b = Tables.BOOK
private val d = Tables.SERIES_METADATA
private val r = Tables.READ_PROGRESS

val countUnread: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isNull, 1).otherwise(0))
val countRead: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0))
val countInProgress: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0))
}

private val groupFields = arrayOf(
*s.fields(),
*d.fields()
)

val countUnread: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isNull, 1).otherwise(0))
val countRead: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isTrue, 1).otherwise(0))
val countInProgress: AggregateFunction<BigDecimal> = DSL.sum(DSL.`when`(r.COMPLETED.isFalse, 1).otherwise(0))

private val sorts = mapOf(
"metadata.titleSort" to DSL.lower(d.TITLE_SORT),
"createdDate" to s.CREATED_DATE,
Expand Down
Expand Up @@ -124,6 +124,22 @@ class BookController(
).map { it.restrictUrl(!principal.user.roleAdmin) }
}

@Operation(description = "Return first unread book of series with at least one book read and no books in progress.")
@PageableWithoutSortAsQueryParam
@GetMapping("api/v1/books/ondeck")
fun getBooksOnDeck(
@AuthenticationPrincipal principal: KomgaPrincipal,
@Parameter(hidden = true) page: Pageable
): Page<BookDto> {
val libraryIds = if (principal.user.sharedAllLibraries) emptyList<Long>() else principal.user.sharedLibrariesIds

return bookDtoRepository.findOnDeck(
libraryIds,
principal.user.id,
page
).map { it.restrictUrl(!principal.user.roleAdmin) }
}


@GetMapping("api/v1/books/{bookId}")
fun getOneBook(
Expand Down
Expand Up @@ -10,4 +10,5 @@ interface BookDtoRepository {
fun findByIdOrNull(bookId: Long, userId: Long): BookDto?
fun findPreviousInSeries(bookId: Long, userId: Long): BookDto?
fun findNextInSeries(bookId: Long, userId: Long): BookDto?
fun findOnDeck(libraryIds: Collection<Long>, userId: Long, pageable: Pageable): Page<BookDto>
}

0 comments on commit 1b6a030

Please sign in to comment.