mirror of
https://github.com/gotson/komga.git
synced 2026-05-07 12:01:40 +02:00
fix duplicates in v2 api for series release years
This commit is contained in:
parent
a08c78c95f
commit
ac2d3346b4
6 changed files with 81 additions and 35 deletions
|
|
@ -234,7 +234,7 @@
|
|||
"/api/v1/age-ratings": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/genres instead. Deprecated since 1.x.0",
|
||||
"description": "Use GET /v2/age-ratings instead. Deprecated since 1.x.0",
|
||||
"operationId": "getAgeRatings_1",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -4760,7 +4760,7 @@
|
|||
"/api/v1/publishers": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/genres instead. Deprecated since 1.x.0",
|
||||
"description": "Use GET /v2/publishers instead. Deprecated since 1.x.0",
|
||||
"operationId": "getPublishers_1",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -6575,8 +6575,8 @@
|
|||
"/api/v1/series/release-dates": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/genres instead. Deprecated since 1.x.0",
|
||||
"operationId": "getSeriesReleaseDates_1",
|
||||
"description": "Use GET /v2/series/release-years instead. Deprecated since 1.x.0",
|
||||
"operationId": "getSeriesReleaseDates",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
|
|
@ -7675,7 +7675,7 @@
|
|||
"/api/v1/tags": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0",
|
||||
"description": "Use GET /v2/tags instead. Deprecated since 1.x.0",
|
||||
"operationId": "getTags_1",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -7735,7 +7735,7 @@
|
|||
"/api/v1/tags/book": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0",
|
||||
"description": "Use GET /v2/tags instead. Deprecated since 1.x.0",
|
||||
"operationId": "getBookTags",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -7803,7 +7803,7 @@
|
|||
"/api/v1/tags/series": {
|
||||
"get": {
|
||||
"deprecated": true,
|
||||
"description": "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0",
|
||||
"description": "Use GET /v2/tags instead. Deprecated since 1.x.0",
|
||||
"operationId": "getSeriesTags",
|
||||
"parameters": [
|
||||
{
|
||||
|
|
@ -8736,10 +8736,10 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"/api/v2/series/release-dates": {
|
||||
"/api/v2/series/release-years": {
|
||||
"get": {
|
||||
"description": "Can be filtered by various criteria",
|
||||
"operationId": "getSeriesReleaseDates",
|
||||
"operationId": "getSeriesReleaseYears",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "query",
|
||||
|
|
@ -8812,7 +8812,7 @@
|
|||
"description": "Bad Request"
|
||||
}
|
||||
},
|
||||
"summary": "List series release dates",
|
||||
"summary": "List series release years",
|
||||
"tags": [
|
||||
"Referential metadata"
|
||||
]
|
||||
|
|
@ -15342,4 +15342,4 @@
|
|||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -228,7 +228,7 @@ interface ReferentialRepository {
|
|||
filterOnLibraryIds: Collection<String>?,
|
||||
): Set<LocalDate>
|
||||
|
||||
fun findSeriesReleaseDates(
|
||||
fun findSeriesReleaseYears(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
|
|
|
|||
|
|
@ -641,14 +641,60 @@ class ReferentialDao(
|
|||
.orderBy(bma.RELEASE_DATE.desc())
|
||||
.fetchSet(bma.RELEASE_DATE)
|
||||
|
||||
override fun findSeriesReleaseDates(
|
||||
override fun findSeriesReleaseYears(
|
||||
context: SearchContext,
|
||||
filterBy: FilterBy?,
|
||||
pageable: Pageable,
|
||||
): Page<String> {
|
||||
filterBy?.let { require(it.type in setOf(FilterByEntity.LIBRARY, FilterByEntity.COLLECTION)) }
|
||||
|
||||
return findGeneric(context, null, filterBy, pageable, bma, null, bma.SERIES_ID, { it?.releaseDate?.year?.toString() }, Sort.by(Order.desc("year")), listOf(bma.RELEASE_DATE), sortField = bma.RELEASE_DATE.desc())
|
||||
val sortField = bma.RELEASE_DATE.desc()
|
||||
val restrictionCondition = ContentRestrictionsSearchHelper(context.restrictions).toCondition()
|
||||
val query =
|
||||
dslRO
|
||||
.selectDistinct(DSL.year(bma.RELEASE_DATE))
|
||||
.from(bma)
|
||||
.apply {
|
||||
restrictionCondition.second.forEach { join ->
|
||||
when (join) {
|
||||
RequiredJoin.SeriesMetadata -> innerJoin(sd).on(bma.SERIES_ID.eq(sd.SERIES_ID))
|
||||
// shouldn't be required
|
||||
RequiredJoin.BookMetadata -> Unit
|
||||
RequiredJoin.BookMetadataAggregation -> Unit
|
||||
is RequiredJoin.Collection -> Unit
|
||||
RequiredJoin.Media -> Unit
|
||||
is RequiredJoin.ReadList -> Unit
|
||||
is RequiredJoin.ReadProgress -> Unit
|
||||
}
|
||||
}
|
||||
}.apply { if (!context.libraryIds.isNullOrEmpty() || filterBy?.type == FilterByEntity.LIBRARY) leftJoin(s).on(bma.SERIES_ID.eq(s.ID)) }
|
||||
.apply { if (filterBy?.type == FilterByEntity.COLLECTION) leftJoin(cs).on(bma.SERIES_ID.eq(cs.SERIES_ID)) }
|
||||
.apply {
|
||||
if (filterBy?.type == FilterByEntity.READLIST)
|
||||
leftJoin(b)
|
||||
.on(bma.SERIES_ID.eq(b.SERIES_ID))
|
||||
.leftJoin(rb)
|
||||
.on(b.ID.eq(rb.BOOK_ID))
|
||||
}.where(restrictionCondition.first)
|
||||
.apply { context.libraryIds?.let { this.and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.apply {
|
||||
filterBy?.let {
|
||||
when (it.type) {
|
||||
FilterByEntity.LIBRARY -> this.and(s.LIBRARY_ID.`in`(it.ids))
|
||||
FilterByEntity.COLLECTION -> this.and(cs.COLLECTION_ID.`in`(it.ids))
|
||||
FilterByEntity.SERIES -> this.and(bma.SERIES_ID.`in`(it.ids))
|
||||
FilterByEntity.READLIST -> this.and(rb.READLIST_ID.`in`(it.ids))
|
||||
}
|
||||
}
|
||||
}
|
||||
val count = dslRO.fetchCount(query)
|
||||
val items =
|
||||
query
|
||||
.orderBy(sortField)
|
||||
.apply { if (pageable.isPaged) limit(pageable.pageSize).offset(pageable.offset) }
|
||||
.fetchArray(0)
|
||||
.mapNotNull { it?.toString() }
|
||||
return buildPage(items, pageable, count, Sort.by(Order.desc("year")))
|
||||
}
|
||||
|
||||
@Deprecated("Use findSharingLabels instead")
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class ReferentialV1Controller(
|
|||
@GetMapping("tags")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List tags", description = "Use GET /v2/tags instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -103,7 +103,7 @@ class ReferentialV1Controller(
|
|||
@GetMapping("tags/book")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List book tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List book tags", description = "Use GET /v2/tags instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getBookTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "series_id", required = false) seriesId: String?,
|
||||
|
|
@ -120,7 +120,7 @@ class ReferentialV1Controller(
|
|||
@GetMapping("tags/series")
|
||||
@Deprecated("Use GET /v2/tags instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List series tags", description = "Use GET /v2/sharing-labels instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List series tags", description = "Use GET /v2/tags instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getSeriesTags(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryId: String?,
|
||||
|
|
@ -150,7 +150,7 @@ class ReferentialV1Controller(
|
|||
@GetMapping("publishers")
|
||||
@Deprecated("Use GET /v2/publishers instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List publishers", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List publishers", description = "Use GET /v2/publishers instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getPublishers(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -165,7 +165,7 @@ class ReferentialV1Controller(
|
|||
@GetMapping("age-ratings")
|
||||
@Deprecated("Use GET /v2/age-ratings instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List age ratings", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List age ratings", description = "Use GET /v2/age-ratings instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getAgeRatings(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
@ -178,9 +178,9 @@ class ReferentialV1Controller(
|
|||
}.map { it?.toString() ?: "None" }.toSet()
|
||||
|
||||
@GetMapping("series/release-dates")
|
||||
@Deprecated("Use GET /v2/age-ratings instead")
|
||||
@Deprecated("Use GET /v2/series/release-years instead")
|
||||
// TODO: add deprecation release
|
||||
@Operation(summary = "List series release dates", description = "Use GET /v2/genres instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
@Operation(summary = "List series release dates", description = "Use GET /v2/series/release-years instead. Deprecated since 1.x.0", tags = [OpenApiConfiguration.TagNames.DEPRECATED])
|
||||
fun getSeriesReleaseDates(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
|
|
|
|||
|
|
@ -292,9 +292,9 @@ class ReferentialV2Controller(
|
|||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
@GetMapping("series/release-dates")
|
||||
@Operation(summary = "List series release dates", description = "Can be filtered by various criteria")
|
||||
fun getSeriesReleaseDates(
|
||||
@GetMapping("series/release-years")
|
||||
@Operation(summary = "List series release years", description = "Can be filtered by various criteria")
|
||||
fun getSeriesReleaseYears(
|
||||
@AuthenticationPrincipal principal: KomgaPrincipal,
|
||||
@RequestParam(name = "library_id", required = false) libraryIds: Set<String> = emptySet(),
|
||||
@RequestParam(name = "collection_id", required = false) collectionIds: Set<String> = emptySet(),
|
||||
|
|
@ -318,7 +318,7 @@ class ReferentialV2Controller(
|
|||
else -> null
|
||||
}
|
||||
|
||||
return referentialRepository.findSeriesReleaseDates(SearchContext(principal.user), filterBy, pageRequest)
|
||||
return referentialRepository.findSeriesReleaseYears(SearchContext(principal.user), filterBy, pageRequest)
|
||||
}
|
||||
|
||||
@PageableWithoutSortAsQueryParam
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class ReferentialDaoTest(
|
|||
makeBook("1", libraryId = library1.id, seriesId = series1.id).let { book ->
|
||||
seriesLifecycle.addBooks(series1, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item1", "writer")), releaseDate = LocalDate.of(2001, 1, 1), tags = setOf("bt1")))
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item1", "writer")), releaseDate = LocalDate.of(2002, 1, 1), tags = setOf("bt1")))
|
||||
}
|
||||
seriesMetadataRepository.findById(series1.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item1"), sharingLabels = setOf("item1"), language = "fr", publisher = "item1", ageRating = 18, tags = setOf("st1")))
|
||||
|
|
@ -109,7 +109,7 @@ class ReferentialDaoTest(
|
|||
makeBook("2", libraryId = library2.id, seriesId = series2.id).let { book ->
|
||||
seriesLifecycle.addBooks(series2, listOf(book))
|
||||
bookMetadataRepository.findById(book.id).let {
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item2", "inker")), releaseDate = LocalDate.of(2002, 1, 1), tags = setOf("bt2")))
|
||||
bookMetadataRepository.update(it.copy(authors = listOf(Author("item2", "inker")), releaseDate = LocalDate.of(2002, 2, 1), tags = setOf("bt2")))
|
||||
}
|
||||
seriesMetadataRepository.findById(series2.id).let {
|
||||
seriesMetadataRepository.update(it.copy(genres = setOf("item2"), sharingLabels = setOf("item2"), language = "en", publisher = "item2", ageRating = 19, tags = setOf("st2")))
|
||||
|
|
@ -729,11 +729,11 @@ class ReferentialDaoTest(
|
|||
}
|
||||
|
||||
@Nested
|
||||
inner class SeriesReleaseDate {
|
||||
inner class SeriesReleaseYear {
|
||||
@Test
|
||||
fun `given filter by library when getting series release dates then only matching series release dates are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
val items = referentialDao.findSeriesReleaseYears(context, FilterBy(FilterByEntity.LIBRARY, setOf(library2.id)), Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2002")
|
||||
}
|
||||
|
|
@ -741,23 +741,23 @@ class ReferentialDaoTest(
|
|||
@Test
|
||||
fun `given user without restrictions when getting series release dates then all series release dates are returned`() {
|
||||
val context = SearchContext(userAll)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
val items = referentialDao.findSeriesReleaseYears(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004", "2003", "2002", "2001")
|
||||
assertThat(items).containsExactly("2004", "2003", "2002")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted library access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userLib1)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
val items = referentialDao.findSeriesReleaseYears(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004", "2003", "2001")
|
||||
assertThat(items).containsExactly("2004", "2003", "2002")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given user with restricted label access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userLabelAllow)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
val items = referentialDao.findSeriesReleaseYears(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2003")
|
||||
}
|
||||
|
|
@ -765,7 +765,7 @@ class ReferentialDaoTest(
|
|||
@Test
|
||||
fun `given user with restricted age access when getting series release dates then only allowed series release dates are returned`() {
|
||||
val context = SearchContext(userAge10)
|
||||
val items = referentialDao.findSeriesReleaseDates(context, null, Pageable.unpaged()).content
|
||||
val items = referentialDao.findSeriesReleaseYears(context, null, Pageable.unpaged()).content
|
||||
|
||||
assertThat(items).containsExactly("2004")
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue