mirror of
https://github.com/gotson/komga.git
synced 2026-05-08 21:00:16 +02:00
feat: comicrack read list matching will look for series with and without volume in brackets
Closes: #1075
This commit is contained in:
parent
53b1137d97
commit
ac1e956890
9 changed files with 64 additions and 47 deletions
|
|
@ -1,7 +1,9 @@
|
|||
<template>
|
||||
<tr v-if="match">
|
||||
<slot/>
|
||||
<td>{{ match.request.series }}</td>
|
||||
<td>
|
||||
<div v-for="s in match.request.series" :key="s">{{ s }}</div>
|
||||
</td>
|
||||
<td>{{ match.request.number }}</td>
|
||||
|
||||
<!-- Series picker -->
|
||||
|
|
@ -130,7 +132,7 @@ export default Vue.extend({
|
|||
if (match.matches.length === 1) {
|
||||
seriesId = match.matches[0].seriesId
|
||||
} else if (match.matches.length > 1) {
|
||||
seriesId = match.matches.find((m) => m.bookIds.length > 1)?.seriesId
|
||||
seriesId = match.matches.find((m) => m.bookIds.length > 0)?.seriesId
|
||||
}
|
||||
if (seriesId) {
|
||||
this.selectedSeries = await this.$komgaSeries.getOneSeries(seriesId)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ export interface ReadListRequestBookDto {
|
|||
number: string,
|
||||
}
|
||||
|
||||
export interface ReadListRequestBookV2Dto {
|
||||
series: string[],
|
||||
number: string,
|
||||
}
|
||||
|
||||
export interface ReadListThumbnailDto {
|
||||
id: string,
|
||||
readListId: string,
|
||||
|
|
@ -59,7 +64,7 @@ export interface ReadListMatchDto {
|
|||
}
|
||||
|
||||
export interface ReadListRequestBookMatchesDto {
|
||||
request: ReadListRequestBookDto,
|
||||
request: ReadListRequestBookV2Dto,
|
||||
matches: ReadListRequestBookMatchDto[],
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ data class ReadListRequest(
|
|||
)
|
||||
|
||||
data class ReadListRequestBook(
|
||||
val series: String,
|
||||
val series: Set<String>,
|
||||
val number: String,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class ReadListMatcher(
|
|||
val unmatchedBooks = mutableListOf<ReadListRequestResultBook>()
|
||||
|
||||
request.books.forEach { book ->
|
||||
val seriesMatches = seriesRepository.findAllByTitle(book.series)
|
||||
val seriesMatches = seriesRepository.findAllByTitle(book.series.first())
|
||||
when {
|
||||
seriesMatches.size > 1 -> unmatchedBooks += ReadListRequestResultBook(book, "ERR_1011")
|
||||
seriesMatches.isEmpty() -> unmatchedBooks += ReadListRequestResultBook(book, "ERR_1012")
|
||||
|
|
@ -77,7 +77,7 @@ class ReadListMatcher(
|
|||
else ReadListMatch(request.name)
|
||||
|
||||
val matches = request.books.map { book ->
|
||||
val matches = seriesRepository.findAllByTitle(book.series).associateWith { series ->
|
||||
val matches = book.series.flatMap { seriesRepository.findAllByTitle(it) }.associateWith { series ->
|
||||
bookRepository.findAllBySeriesId(series.id)
|
||||
.filter { (bookMetadataRepository.findById(it.id).number.trimStart('0') == book.number.trimStart('0')) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class ReadListProvider(
|
|||
val books = readingList.books.mapNotNull {
|
||||
val series = computeSeriesFromSeriesAndVolume(it.series, it.volume)
|
||||
if (!series.isNullOrBlank() && it.number != null)
|
||||
ReadListRequestBook(series, it.number!!.trim())
|
||||
ReadListRequestBook(setOf(series), it.number!!.trim())
|
||||
else {
|
||||
logger.warn { "Book is missing series or number, skipping: $it" }
|
||||
null
|
||||
|
|
@ -61,9 +61,9 @@ class ReadListProvider(
|
|||
if (readingList.books.isEmpty()) throw ComicRackListException("ReadingList does not contain any Book element", "ERR_1029")
|
||||
|
||||
val books = readingList.books.map {
|
||||
val series = computeSeriesFromSeriesAndVolume(it.series, it.volume)
|
||||
if (series.isNullOrBlank() || it.number == null) throw ComicRackListException("Book is missing series or number: $it", "ERR_1031")
|
||||
else ReadListRequestBook(series, it.number!!.trim())
|
||||
if (it.series.isNullOrBlank() || it.number == null) throw ComicRackListException("Book is missing series or number: $it", "ERR_1031")
|
||||
val series = setOfNotNull(computeSeriesFromSeriesAndVolume(it.series, it.volume), it.series?.ifBlank { null })
|
||||
ReadListRequestBook(series, it.number!!.trim())
|
||||
}
|
||||
|
||||
return ReadListRequest(name = readingList.name!!, books = books)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.gotson.komga.interfaces.api.rest.dto
|
||||
|
||||
import org.gotson.komga.domain.model.ReadListMatch
|
||||
import org.gotson.komga.domain.model.ReadListRequestBook
|
||||
import org.gotson.komga.domain.model.ReadListRequestMatch
|
||||
|
||||
data class ReadListRequestMatchDto(
|
||||
|
|
@ -14,7 +15,7 @@ fun ReadListRequestMatch.toDto() =
|
|||
readListMatch.toDto(),
|
||||
matches.map {
|
||||
ReadListRequestBookMatchesDto(
|
||||
it.request.toDto(),
|
||||
it.request.toDtoV2(),
|
||||
it.matches.entries.map { (series, books) ->
|
||||
ReadListRequestBookMatchDto(
|
||||
series.id,
|
||||
|
|
@ -31,10 +32,21 @@ data class ReadListMatchDto(
|
|||
)
|
||||
|
||||
data class ReadListRequestBookMatchesDto(
|
||||
val request: ReadListRequestBookDto,
|
||||
val request: ReadListRequestBookV2Dto,
|
||||
val matches: List<ReadListRequestBookMatchDto>,
|
||||
)
|
||||
|
||||
data class ReadListRequestBookV2Dto(
|
||||
val series: Set<String>,
|
||||
val number: String,
|
||||
)
|
||||
|
||||
fun ReadListRequestBook.toDtoV2() =
|
||||
ReadListRequestBookV2Dto(
|
||||
series = series,
|
||||
number = number,
|
||||
)
|
||||
|
||||
data class ReadListRequestBookMatchDto(
|
||||
val seriesId: String,
|
||||
val bookIds: List<String>,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,6 @@ fun ReadListRequestResultBook.toDto() =
|
|||
|
||||
fun ReadListRequestBook.toDto() =
|
||||
ReadListRequestBookDto(
|
||||
series = series,
|
||||
series = series.first(),
|
||||
number = number,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -103,10 +103,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "Batman: White Knight", number = "1"),
|
||||
ReadListRequestBook(series = "joker", number = "02"),
|
||||
ReadListRequestBook(series = "Batman: White Knight", number = "2"),
|
||||
ReadListRequestBook(series = "joker", number = "25"),
|
||||
ReadListRequestBook(series = setOf("Batman: White Knight"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "02"),
|
||||
ReadListRequestBook(series = setOf("Batman: White Knight"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "25"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -143,10 +143,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "my readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "batman: white knight", number = "1"),
|
||||
ReadListRequestBook(series = "joker", number = "2"),
|
||||
ReadListRequestBook(series = "BATMAN: WHITE KNIGHT", number = "2"),
|
||||
ReadListRequestBook(series = "joker", number = "25"),
|
||||
ReadListRequestBook(series = setOf("batman: white knight"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("BATMAN: WHITE KNIGHT"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "25"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -194,10 +194,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "tokyo ghost", number = "1"),
|
||||
ReadListRequestBook(series = "batman", number = "3"),
|
||||
ReadListRequestBook(series = "joker", number = "3"),
|
||||
ReadListRequestBook(series = "batman", number = "2"),
|
||||
ReadListRequestBook(series = setOf("tokyo ghost"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "3"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "3"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "2"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -241,9 +241,9 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "batman", number = "1"),
|
||||
ReadListRequestBook(series = "batman", number = "2"),
|
||||
ReadListRequestBook(series = "batman", number = "2"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "2"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -315,10 +315,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "Batman: White Knight", number = "1"),
|
||||
ReadListRequestBook(series = "joker", number = "02"),
|
||||
ReadListRequestBook(series = "Batman: White Knight", number = "2"),
|
||||
ReadListRequestBook(series = "joker", number = "25"),
|
||||
ReadListRequestBook(series = setOf("Batman: White Knight"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "02"),
|
||||
ReadListRequestBook(series = setOf("Batman: White Knight"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "25"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -381,10 +381,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "my readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "batman: white knight", number = "1"),
|
||||
ReadListRequestBook(series = "joker", number = "2"),
|
||||
ReadListRequestBook(series = "BATMAN: WHITE KNIGHT", number = "2"),
|
||||
ReadListRequestBook(series = "joker", number = "25"),
|
||||
ReadListRequestBook(series = setOf("batman: white knight"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("BATMAN: WHITE KNIGHT"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "25"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -443,10 +443,10 @@ class ReadListMatcherTest(
|
|||
val request = ReadListRequest(
|
||||
name = "readlist",
|
||||
books = listOf(
|
||||
ReadListRequestBook(series = "tokyo ghost", number = "1"),
|
||||
ReadListRequestBook(series = "batman", number = "3"),
|
||||
ReadListRequestBook(series = "joker", number = "2"),
|
||||
ReadListRequestBook(series = "batman", number = "2"),
|
||||
ReadListRequestBook(series = setOf("tokyo ghost"), number = "1"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "3"),
|
||||
ReadListRequestBook(series = setOf("joker"), number = "2"),
|
||||
ReadListRequestBook(series = setOf("batman"), number = "2"),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ class ReadListProviderTest {
|
|||
private val mockMapper = mockk<XmlMapper>()
|
||||
private val readListProvider = ReadListProvider(mockMapper)
|
||||
|
||||
|
||||
@Nested
|
||||
inner class ImportFromCbl {
|
||||
@Test
|
||||
|
|
@ -49,12 +48,12 @@ class ReadListProviderTest {
|
|||
assertThat(books).hasSize(2)
|
||||
|
||||
with(books[0]) {
|
||||
assertThat(series).isEqualTo("series 1 (2005)")
|
||||
assertThat(series).containsExactlyInAnyOrder("series 1 (2005)")
|
||||
assertThat(number).isEqualTo("4")
|
||||
}
|
||||
|
||||
with(books[1]) {
|
||||
assertThat(series).isEqualTo("series 2")
|
||||
assertThat(series).containsExactlyInAnyOrder("series 2")
|
||||
assertThat(number).isEqualTo("1")
|
||||
}
|
||||
}
|
||||
|
|
@ -189,18 +188,17 @@ class ReadListProviderTest {
|
|||
val request = readListProvider.importFromCblV2(ByteArray(0))
|
||||
|
||||
// then
|
||||
assertThat(request).isNotNull
|
||||
with(request!!) {
|
||||
with(request) {
|
||||
assertThat(name).isEqualTo(cbl.name)
|
||||
assertThat(books).hasSize(2)
|
||||
|
||||
with(books[0]) {
|
||||
assertThat(series).isEqualTo("series 1 (2005)")
|
||||
assertThat(series).containsExactlyInAnyOrder("series 1 (2005)", "series 1")
|
||||
assertThat(number).isEqualTo("4")
|
||||
}
|
||||
|
||||
with(books[1]) {
|
||||
assertThat(series).isEqualTo("series 2")
|
||||
assertThat(series).containsExactlyInAnyOrder("series 2")
|
||||
assertThat(number).isEqualTo("1")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue