Skip to content

Commit

Permalink
feat(opds): recently added books
Browse files Browse the repository at this point in the history
closes gotson#327
  • Loading branch information
gotson committed Sep 28, 2020
1 parent f3fcab4 commit dd7bc9c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package org.gotson.komga.domain.persistence

import org.gotson.komga.domain.model.Book
import org.gotson.komga.domain.model.BookSearch
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable

interface BookRepository {
fun findByIdOrNull(bookId: String): Book?
fun findBySeriesId(seriesId: String): Collection<Book>
fun findAll(): Collection<Book>
fun findAll(bookSearch: BookSearch): Collection<Book>
fun findAll(bookSearch: BookSearch, pageable: Pageable): Page<Book>

fun getLibraryId(bookId: String): String?
fun findFirstIdInSeries(seriesId: String): String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import org.gotson.komga.jooq.tables.records.BookRecord
import org.jooq.Condition
import org.jooq.DSLContext
import org.jooq.impl.DSL
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageImpl
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.net.URL
import java.time.LocalDateTime
Expand All @@ -22,6 +27,10 @@ class BookDao(
private val m = Tables.MEDIA
private val d = Tables.BOOK_METADATA

private val sorts = mapOf(
"createdDate" to b.CREATED_DATE
)

override fun findByIdOrNull(bookId: String): Book? =
findByIdOrNull(dsl, bookId)

Expand Down Expand Up @@ -52,6 +61,38 @@ class BookDao(
.fetchInto(b)
.map { it.toDomain() }

override fun findAll(bookSearch: BookSearch, pageable: Pageable): Page<Book> {
val conditions = bookSearch.toCondition()

val count = dsl.selectCount()
.from(b)
.leftJoin(d).on(b.ID.eq(d.BOOK_ID))
.leftJoin(m).on(b.ID.eq(m.BOOK_ID))
.where(conditions)
.fetchOne(0, Long::class.java)

val orderBy = pageable.sort.toOrderBy(sorts)


val items = dsl.select(*b.fields())
.from(b)
.leftJoin(d).on(b.ID.eq(d.BOOK_ID))
.leftJoin(m).on(b.ID.eq(m.BOOK_ID))
.where(conditions)
.orderBy(orderBy)
.apply { if (pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) }
.fetchInto(b)
.map { it.toDomain() }

val pageSort = if (orderBy.size > 1) pageable.sort else Sort.unsorted()
return PageImpl(
items,
if (pageable.isPaged) PageRequest.of(pageable.pageNumber, pageable.pageSize, pageSort)
else PageRequest.of(0, maxOf(count.toInt(), 20), pageSort),
count.toLong()
)
}


override fun getLibraryId(bookId: String): String? =
dsl.select(b.LIBRARY_ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import org.gotson.komga.interfaces.opds.dto.OpdsLinkPageStreaming
import org.gotson.komga.interfaces.opds.dto.OpdsLinkRel
import org.gotson.komga.interfaces.opds.dto.OpdsLinkSearch
import org.gotson.komga.interfaces.opds.dto.OpenSearchDescription
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
Expand All @@ -60,6 +61,7 @@ private const val ROUTE_BASE = "/opds/v1.2/"
private const val ROUTE_CATALOG = "catalog"
private const val ROUTE_SERIES_ALL = "series"
private const val ROUTE_SERIES_LATEST = "series/latest"
private const val ROUTE_BOOKS_LATEST = "books/latest"
private const val ROUTE_LIBRARIES_ALL = "libraries"
private const val ROUTE_COLLECTIONS_ALL = "collections"
private const val ROUTE_READLISTS_ALL = "readlists"
Expand All @@ -68,6 +70,7 @@ private const val ROUTE_SEARCH = "search"

private const val ID_SERIES_ALL = "allSeries"
private const val ID_SERIES_LATEST = "latestSeries"
private const val ID_BOOKS_LATEST = "latestBooks"
private const val ID_LIBRARIES_ALL = "allLibraries"
private const val ID_COLLECTIONS_ALL = "allCollections"
private const val ID_READLISTS_ALL = "allReadLists"
Expand Down Expand Up @@ -123,6 +126,13 @@ class OpdsController(
content = "Browse latest series",
link = OpdsLinkFeedNavigation(OpdsLinkRel.SUBSECTION, "$routeBase$ROUTE_SERIES_LATEST")
),
OpdsEntryNavigation(
title = "Latest books",
updated = ZonedDateTime.now(),
id = ID_BOOKS_LATEST,
content = "Browse latest books",
link = OpdsLinkFeedNavigation(OpdsLinkRel.SUBSECTION, "$routeBase$ROUTE_BOOKS_LATEST")
),
OpdsEntryNavigation(
title = "All libraries",
updated = ZonedDateTime.now(),
Expand Down Expand Up @@ -223,6 +233,35 @@ class OpdsController(
)
}

@GetMapping(ROUTE_BOOKS_LATEST)
fun getLatestBooks(
@AuthenticationPrincipal principal: KomgaPrincipal,
@RequestHeader(name = HttpHeaders.USER_AGENT, required = false, defaultValue = "") userAgent: String
): OpdsFeed {
val bookSearch = BookSearch(
libraryIds = principal.user.getAuthorizedLibraryIds(null),
mediaStatus = setOf(Media.Status.READY)
)
val pageRequest = PageRequest.of(0, 50, Sort.by(Sort.Order.desc("createdDate")))

val entries = bookRepository.findAll(bookSearch, pageRequest)
.map { BookWithInfo(it, mediaRepository.findById(it.id), bookMetadataRepository.findById(it.id)) }
.content
.map { it.toOpdsEntry(shouldPrependBookNumbers(userAgent)) }

return OpdsFeedAcquisition(
id = ID_BOOKS_LATEST,
title = "Latest books",
updated = ZonedDateTime.now(),
author = komgaAuthor,
links = listOf(
OpdsLinkFeedNavigation(OpdsLinkRel.SELF, "$routeBase$ROUTE_BOOKS_LATEST"),
linkStart
),
entries = entries
)
}

@GetMapping(ROUTE_LIBRARIES_ALL)
fun getLibraries(
@AuthenticationPrincipal principal: KomgaPrincipal
Expand Down

0 comments on commit dd7bc9c

Please sign in to comment.