mirror of
https://github.com/gotson/komga.git
synced 2025-12-06 08:32:25 +01:00
feat: library option to append ComicInfo Volume to Series title
This commit is contained in:
parent
d2244b5e75
commit
63b3c83ce2
17 changed files with 62 additions and 15 deletions
|
|
@ -246,6 +246,12 @@
|
|||
hide-details
|
||||
class="mx-4"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-model="form.importComicInfoSeriesAppendVolume"
|
||||
:label="$t('dialog.edit_library.field_import_comicinfo_series_append_volume')"
|
||||
hide-details
|
||||
class="mx-4"
|
||||
/>
|
||||
<v-checkbox
|
||||
v-model="form.importComicInfoCollection"
|
||||
:label="$t('dialog.edit_library.field_import_comicinfo_collections')"
|
||||
|
|
@ -379,6 +385,7 @@ export default Vue.extend({
|
|||
importComicInfoSeries: true,
|
||||
importComicInfoCollection: true,
|
||||
importComicInfoReadList: true,
|
||||
importComicInfoSeriesAppendVolume: true,
|
||||
importEpubBook: true,
|
||||
importEpubSeries: true,
|
||||
importMylarSeries: true,
|
||||
|
|
@ -416,7 +423,7 @@ export default Vue.extend({
|
|||
|
||||
importComicInfo: {
|
||||
get: function (): number {
|
||||
const val = [this.form.importComicInfoBook, this.form.importComicInfoCollection, this.form.importComicInfoReadList, this.form.importComicInfoSeries]
|
||||
const val = [this.form.importComicInfoBook, this.form.importComicInfoCollection, this.form.importComicInfoReadList, this.form.importComicInfoSeries, this.form.importComicInfoSeriesAppendVolume]
|
||||
const count = val.filter(Boolean).length
|
||||
if (count === val.length) return 2
|
||||
if (count === 0) return 0
|
||||
|
|
@ -427,6 +434,7 @@ export default Vue.extend({
|
|||
this.form.importComicInfoCollection = value
|
||||
this.form.importComicInfoReadList = value
|
||||
this.form.importComicInfoSeries = value
|
||||
this.form.importComicInfoSeriesAppendVolume = value
|
||||
},
|
||||
},
|
||||
|
||||
|
|
@ -510,6 +518,7 @@ export default Vue.extend({
|
|||
this.form.importComicInfoSeries = library ? library.importComicInfoSeries : true
|
||||
this.form.importComicInfoCollection = library ? library.importComicInfoCollection : true
|
||||
this.form.importComicInfoReadList = library ? library.importComicInfoReadList : true
|
||||
this.form.importComicInfoSeriesAppendVolume = library ? library.importComicInfoSeriesAppendVolume : true
|
||||
this.form.importEpubBook = library ? library.importEpubBook : true
|
||||
this.form.importEpubSeries = library ? library.importEpubSeries : true
|
||||
this.form.importMylarSeries = library ? library.importMylarSeries : true
|
||||
|
|
@ -537,6 +546,7 @@ export default Vue.extend({
|
|||
importComicInfoSeries: this.form.importComicInfoSeries,
|
||||
importComicInfoCollection: this.form.importComicInfoCollection,
|
||||
importComicInfoReadList: this.form.importComicInfoReadList,
|
||||
importComicInfoSeriesAppendVolume: this.form.importComicInfoSeriesAppendVolume,
|
||||
importEpubBook: this.form.importEpubBook,
|
||||
importEpubSeries: this.form.importEpubSeries,
|
||||
importMylarSeries: this.form.importMylarSeries,
|
||||
|
|
|
|||
|
|
@ -393,6 +393,7 @@
|
|||
"field_import_comicinfo_collections": "Collections",
|
||||
"field_import_comicinfo_readlists": "Read lists",
|
||||
"field_import_comicinfo_series": "Series metadata",
|
||||
"field_import_comicinfo_series_append_volume": "Append volume to series title",
|
||||
"field_import_epub_book": "Book metadata",
|
||||
"field_import_epub_series": "Series metadata",
|
||||
"field_import_local_artwork": "Local artwork",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export interface LibraryCreationDto {
|
|||
importComicInfoSeries: boolean,
|
||||
importComicInfoCollection: boolean,
|
||||
importComicInfoReadList: boolean,
|
||||
importComicInfoSeriesAppendVolume: boolean,
|
||||
importEpubBook: boolean,
|
||||
importEpubSeries: boolean,
|
||||
importMylarSeries: boolean,
|
||||
|
|
@ -30,6 +31,7 @@ export interface LibraryUpdateDto {
|
|||
importComicInfoSeries: boolean,
|
||||
importComicInfoCollection: boolean,
|
||||
importComicInfoReadList: boolean,
|
||||
importComicInfoSeriesAppendVolume: boolean,
|
||||
importEpubBook: boolean,
|
||||
importEpubSeries: boolean,
|
||||
importMylarSeries: boolean,
|
||||
|
|
@ -54,6 +56,7 @@ export interface LibraryDto {
|
|||
importComicInfoSeries: boolean,
|
||||
importComicInfoCollection: boolean,
|
||||
importComicInfoReadList: boolean,
|
||||
importComicInfoSeriesAppendVolume: boolean,
|
||||
importEpubBook: boolean,
|
||||
importEpubSeries: boolean,
|
||||
importMylarSeries: boolean,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE LIBRARY
|
||||
add column IMPORT_COMICINFO_SERIES_APPEND_VOLUME boolean NOT NULL DEFAULT 1;
|
||||
|
|
@ -14,6 +14,7 @@ data class Library(
|
|||
val importComicInfoSeries: Boolean = true,
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importComicInfoReadList: Boolean = true,
|
||||
val importComicInfoSeriesAppendVolume: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true,
|
||||
val importMylarSeries: Boolean = true,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class SeriesMetadataLifecycle(
|
|||
else -> {
|
||||
logger.debug { "Provider: ${provider.javaClass.simpleName}" }
|
||||
val patches = bookRepository.findAllBySeriesId(series.id)
|
||||
.mapNotNull { provider.getSeriesMetadataFromBook(BookWithMedia(it, mediaRepository.findById(it.id))) }
|
||||
.mapNotNull { provider.getSeriesMetadataFromBook(BookWithMedia(it, mediaRepository.findById(it.id)), library) }
|
||||
|
||||
if (provider.shouldLibraryHandlePatch(library, MetadataPatchTarget.SERIES)) {
|
||||
handlePatchForSeriesMetadata(patches, series)
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class LibraryDao(
|
|||
.set(l.IMPORT_COMICINFO_SERIES, library.importComicInfoSeries)
|
||||
.set(l.IMPORT_COMICINFO_COLLECTION, library.importComicInfoCollection)
|
||||
.set(l.IMPORT_COMICINFO_READLIST, library.importComicInfoReadList)
|
||||
.set(l.IMPORT_COMICINFO_SERIES_APPEND_VOLUME, library.importComicInfoSeriesAppendVolume)
|
||||
.set(l.IMPORT_EPUB_BOOK, library.importEpubBook)
|
||||
.set(l.IMPORT_EPUB_SERIES, library.importEpubSeries)
|
||||
.set(l.IMPORT_MYLAR_SERIES, library.importMylarSeries)
|
||||
|
|
@ -92,6 +93,7 @@ class LibraryDao(
|
|||
.set(l.IMPORT_COMICINFO_SERIES, library.importComicInfoSeries)
|
||||
.set(l.IMPORT_COMICINFO_COLLECTION, library.importComicInfoCollection)
|
||||
.set(l.IMPORT_COMICINFO_READLIST, library.importComicInfoReadList)
|
||||
.set(l.IMPORT_COMICINFO_SERIES_APPEND_VOLUME, library.importComicInfoSeriesAppendVolume)
|
||||
.set(l.IMPORT_EPUB_BOOK, library.importEpubBook)
|
||||
.set(l.IMPORT_EPUB_SERIES, library.importEpubSeries)
|
||||
.set(l.IMPORT_MYLAR_SERIES, library.importMylarSeries)
|
||||
|
|
@ -122,6 +124,7 @@ class LibraryDao(
|
|||
importComicInfoSeries = importComicinfoSeries,
|
||||
importComicInfoCollection = importComicinfoCollection,
|
||||
importComicInfoReadList = importComicinfoReadlist,
|
||||
importComicInfoSeriesAppendVolume = importComicinfoSeriesAppendVolume,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries,
|
||||
importMylarSeries = importMylarSeries,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package org.gotson.komga.infrastructure.metadata
|
||||
|
||||
import org.gotson.komga.domain.model.BookWithMedia
|
||||
import org.gotson.komga.domain.model.Library
|
||||
import org.gotson.komga.domain.model.SeriesMetadataPatch
|
||||
|
||||
interface SeriesMetadataFromBookProvider : MetadataProvider {
|
||||
fun getSeriesMetadataFromBook(book: BookWithMedia): SeriesMetadataPatch?
|
||||
fun getSeriesMetadataFromBook(book: BookWithMedia, library: Library): SeriesMetadataPatch?
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class ComicInfoProvider(
|
|||
return null
|
||||
}
|
||||
|
||||
override fun getSeriesMetadataFromBook(book: BookWithMedia): SeriesMetadataPatch? {
|
||||
override fun getSeriesMetadataFromBook(book: BookWithMedia, library: Library): SeriesMetadataPatch? {
|
||||
getComicInfo(book)?.let { comicInfo ->
|
||||
val readingDirection = when (comicInfo.manga) {
|
||||
Manga.NO -> SeriesMetadata.ReadingDirection.LEFT_TO_RIGHT
|
||||
|
|
@ -122,7 +122,7 @@ class ComicInfoProvider(
|
|||
}
|
||||
|
||||
val genres = comicInfo.genre?.split(',')?.mapNotNull { it.trim().ifBlank { null } }
|
||||
val series = computeSeriesFromSeriesAndVolume(comicInfo.series, comicInfo.volume)
|
||||
val series = if (library.importComicInfoSeriesAppendVolume) computeSeriesFromSeriesAndVolume(comicInfo.series, comicInfo.volume) else comicInfo.series
|
||||
|
||||
return SeriesMetadataPatch(
|
||||
title = series,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ class EpubMetadataProvider(
|
|||
return null
|
||||
}
|
||||
|
||||
override fun getSeriesMetadataFromBook(book: BookWithMedia): SeriesMetadataPatch? {
|
||||
override fun getSeriesMetadataFromBook(book: BookWithMedia, library: Library): SeriesMetadataPatch? {
|
||||
if (book.media.mediaType != MediaType.EPUB.value) return null
|
||||
epubExtractor.getPackageFile(book.book.path)?.let { packageFile ->
|
||||
val opf = Jsoup.parse(packageFile, "", Parser.xmlParser())
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ class LibraryController(
|
|||
importComicInfoSeries = library.importComicInfoSeries,
|
||||
importComicInfoCollection = library.importComicInfoCollection,
|
||||
importComicInfoReadList = library.importComicInfoReadList,
|
||||
importComicInfoSeriesAppendVolume = library.importComicInfoSeriesAppendVolume,
|
||||
importEpubBook = library.importEpubBook,
|
||||
importEpubSeries = library.importEpubSeries,
|
||||
importMylarSeries = library.importMylarSeries,
|
||||
|
|
@ -126,6 +127,7 @@ class LibraryController(
|
|||
importComicInfoSeries = library.importComicInfoSeries,
|
||||
importComicInfoCollection = library.importComicInfoCollection,
|
||||
importComicInfoReadList = library.importComicInfoReadList,
|
||||
importComicInfoSeriesAppendVolume = library.importComicInfoSeriesAppendVolume,
|
||||
importEpubBook = library.importEpubBook,
|
||||
importEpubSeries = library.importEpubSeries,
|
||||
importMylarSeries = library.importMylarSeries,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ data class LibraryCreationDto(
|
|||
val importComicInfoSeries: Boolean = true,
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importComicInfoReadList: Boolean = true,
|
||||
val importComicInfoSeriesAppendVolume: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true,
|
||||
val importMylarSeries: Boolean = true,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ data class LibraryDto(
|
|||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importComicInfoSeriesAppendVolume: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
|
|
@ -36,6 +37,7 @@ fun Library.toDto(includeRoot: Boolean) = LibraryDto(
|
|||
importComicInfoSeries = importComicInfoSeries,
|
||||
importComicInfoCollection = importComicInfoCollection,
|
||||
importComicInfoReadList = importComicInfoReadList,
|
||||
importComicInfoSeriesAppendVolume = importComicInfoSeriesAppendVolume,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries,
|
||||
importMylarSeries = importMylarSeries,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ data class LibraryUpdateDto(
|
|||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importComicInfoSeriesAppendVolume: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class LibraryDaoTest(
|
|||
libraryDao.insert(library)
|
||||
val created = libraryDao.findById(library.id)
|
||||
|
||||
assertThat(created.id).isNotEqualTo(0)
|
||||
assertThat(created.createdDate).isCloseTo(now, offset)
|
||||
assertThat(created.lastModifiedDate).isCloseTo(now, offset)
|
||||
assertThat(created.name).isEqualTo(library.name)
|
||||
|
|
@ -61,6 +60,7 @@ class LibraryDaoTest(
|
|||
importComicInfoSeries = false,
|
||||
importComicInfoBook = false,
|
||||
importComicInfoReadList = false,
|
||||
importComicInfoSeriesAppendVolume = false,
|
||||
importMylarSeries = false,
|
||||
importBarcodeIsbn = false,
|
||||
importLocalArtwork = false,
|
||||
|
|
@ -91,6 +91,7 @@ class LibraryDaoTest(
|
|||
assertThat(modified.importComicInfoSeries).isEqualTo(updated.importComicInfoSeries)
|
||||
assertThat(modified.importComicInfoBook).isEqualTo(updated.importComicInfoBook)
|
||||
assertThat(modified.importComicInfoReadList).isEqualTo(updated.importComicInfoReadList)
|
||||
assertThat(modified.importComicInfoSeriesAppendVolume).isEqualTo(updated.importComicInfoSeriesAppendVolume)
|
||||
assertThat(modified.importBarcodeIsbn).isEqualTo(updated.importBarcodeIsbn)
|
||||
assertThat(modified.importLocalArtwork).isEqualTo(updated.importLocalArtwork)
|
||||
assertThat(modified.importMylarSeries).isEqualTo(updated.importMylarSeries)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import org.gotson.komga.domain.model.Media
|
|||
import org.gotson.komga.domain.model.SeriesMetadata
|
||||
import org.gotson.komga.domain.model.WebLink
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeLibrary
|
||||
import org.gotson.komga.domain.service.BookAnalyzer
|
||||
import org.gotson.komga.infrastructure.metadata.comicrack.dto.AgeRating
|
||||
import org.gotson.komga.infrastructure.metadata.comicrack.dto.ComicInfo
|
||||
|
|
@ -329,6 +330,9 @@ class ComicInfoProviderTest {
|
|||
|
||||
@Nested
|
||||
inner class Series {
|
||||
|
||||
private val library = makeLibrary()
|
||||
private val libraryNoAppend = library.copy(importComicInfoSeriesAppendVolume = false)
|
||||
@Test
|
||||
fun `given comicInfo when getting series metadata then metadata patch is valid`() {
|
||||
val comicInfo = ComicInfo().apply {
|
||||
|
|
@ -344,7 +348,7 @@ class ComicInfoProviderTest {
|
|||
|
||||
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
|
||||
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))!!
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)!!
|
||||
|
||||
with(patch) {
|
||||
assertThat(title).isEqualTo("series")
|
||||
|
|
@ -370,11 +374,17 @@ class ComicInfoProviderTest {
|
|||
|
||||
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
|
||||
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))!!
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)!!
|
||||
|
||||
with(patch) {
|
||||
assertThat(title).isEqualTo("series (2020)")
|
||||
}
|
||||
|
||||
val patchNoAppend = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), libraryNoAppend)!!
|
||||
|
||||
with(patchNoAppend) {
|
||||
assertThat(title).isEqualTo("series")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -386,11 +396,17 @@ class ComicInfoProviderTest {
|
|||
|
||||
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
|
||||
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))!!
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)!!
|
||||
|
||||
with(patch) {
|
||||
assertThat(title).isEqualTo("series")
|
||||
}
|
||||
|
||||
val patchNoAppend = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), libraryNoAppend)!!
|
||||
|
||||
with(patchNoAppend) {
|
||||
assertThat(title).isEqualTo("series")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -401,7 +417,7 @@ class ComicInfoProviderTest {
|
|||
|
||||
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
|
||||
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))!!
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)!!
|
||||
|
||||
with(patch) {
|
||||
assertThat(language).isNull()
|
||||
|
|
@ -421,7 +437,7 @@ class ComicInfoProviderTest {
|
|||
|
||||
every { mockMapper.readValue(any<ByteArray>(), ComicInfo::class.java) } returns comicInfo
|
||||
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))!!
|
||||
val patch = comicInfoProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)!!
|
||||
|
||||
with(patch) {
|
||||
assertThat(title).isNull()
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import org.gotson.komga.domain.model.BookWithMedia
|
|||
import org.gotson.komga.domain.model.Media
|
||||
import org.gotson.komga.domain.model.SeriesMetadata
|
||||
import org.gotson.komga.domain.model.makeBook
|
||||
import org.gotson.komga.domain.model.makeLibrary
|
||||
import org.gotson.komga.infrastructure.image.ImageAnalyzer
|
||||
import org.gotson.komga.infrastructure.mediacontainer.ContentDetector
|
||||
import org.gotson.komga.infrastructure.mediacontainer.EpubExtractor
|
||||
|
|
@ -118,12 +119,14 @@ class EpubMetadataProviderTest {
|
|||
@Nested
|
||||
inner class Series {
|
||||
|
||||
private val library = makeLibrary()
|
||||
|
||||
@Test
|
||||
fun `given epub 3 opf when getting series metadata then metadata patch is valid`() {
|
||||
val opf = ClassPathResource("epub/Panik im Paradies.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isEqualTo("Die drei ??? Kids")
|
||||
|
|
@ -140,7 +143,7 @@ class EpubMetadataProviderTest {
|
|||
val opf = ClassPathResource("epub/Die Drei 3.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isEqualTo("Die drei ??? Kids")
|
||||
|
|
@ -157,7 +160,7 @@ class EpubMetadataProviderTest {
|
|||
val opf = ClassPathResource("epub/1979.opf")
|
||||
every { mockExtractor.getPackageFile(any()) } returns opf.file.readText()
|
||||
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media))
|
||||
val patch = epubMetadataProvider.getSeriesMetadataFromBook(BookWithMedia(book, media), library)
|
||||
|
||||
with(patch!!) {
|
||||
assertThat(title).isNull()
|
||||
|
|
|
|||
Loading…
Reference in a new issue