mirror of
https://github.com/gotson/komga.git
synced 2025-12-16 13:33:49 +01:00
parent
f93143c9ec
commit
8e94b8e444
15 changed files with 180 additions and 90 deletions
|
|
@ -0,0 +1,2 @@
|
|||
alter table library
|
||||
add column SERIES_COVER varchar NOT NULL DEFAULT 'FIRST';
|
||||
|
|
@ -24,6 +24,7 @@ data class Library(
|
|||
val repairExtensions: Boolean = false,
|
||||
val convertToCbz: Boolean = false,
|
||||
val emptyTrashAfterScan: Boolean = false,
|
||||
val seriesCover: SeriesCover = SeriesCover.FIRST,
|
||||
|
||||
val id: String = TsidCreator.getTsid256().toString(),
|
||||
|
||||
|
|
@ -31,6 +32,13 @@ data class Library(
|
|||
override val lastModifiedDate: LocalDateTime = LocalDateTime.now()
|
||||
) : Auditable(), Serializable {
|
||||
|
||||
enum class SeriesCover {
|
||||
FIRST,
|
||||
FIRST_UNREAD_OR_FIRST,
|
||||
FIRST_UNREAD_OR_LAST,
|
||||
LAST,
|
||||
}
|
||||
|
||||
@delegate:Transient
|
||||
val path: Path by lazy { this.root.toURI().toPath() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ interface BookRepository {
|
|||
fun getLibraryIdOrNull(bookId: String): String?
|
||||
fun getSeriesIdOrNull(bookId: String): String?
|
||||
fun findFirstIdInSeriesOrNull(seriesId: String): String?
|
||||
fun findLastIdInSeriesOrNull(seriesId: String): String?
|
||||
fun findFirstUnreadIdInSeriesOrNull(seriesId: String, userId: String): String?
|
||||
|
||||
fun findAllIdsBySeriesId(seriesId: String): Collection<String>
|
||||
fun findAllIdsBySeriesIds(seriesIds: Collection<String>): Collection<String>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ class SeriesCollectionLifecycle(
|
|||
toDelete.forEach { eventPublisher.publishEvent(DomainEvent.CollectionDeleted(it)) }
|
||||
}
|
||||
|
||||
fun getThumbnailBytes(collection: SeriesCollection): ByteArray {
|
||||
fun getThumbnailBytes(collection: SeriesCollection, userId: String): ByteArray {
|
||||
val ids = with(mutableListOf<String>()) {
|
||||
while (size < 4) {
|
||||
this += collection.seriesIds.take(4)
|
||||
|
|
@ -69,7 +69,7 @@ class SeriesCollectionLifecycle(
|
|||
this.take(4)
|
||||
}
|
||||
|
||||
val images = ids.mapNotNull { seriesLifecycle.getThumbnailBytes(it) }
|
||||
val images = ids.mapNotNull { seriesLifecycle.getThumbnailBytes(it, userId) }
|
||||
return mosaicGenerator.createMosaic(images)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import org.gotson.komga.domain.model.BookMetadataAggregation
|
|||
import org.gotson.komga.domain.model.BookMetadataPatchCapability
|
||||
import org.gotson.komga.domain.model.DomainEvent
|
||||
import org.gotson.komga.domain.model.KomgaUser
|
||||
import org.gotson.komga.domain.model.Library
|
||||
import org.gotson.komga.domain.model.Media
|
||||
import org.gotson.komga.domain.model.ReadProgress
|
||||
import org.gotson.komga.domain.model.Series
|
||||
|
|
@ -19,6 +20,7 @@ import org.gotson.komga.domain.model.ThumbnailSeries
|
|||
import org.gotson.komga.domain.persistence.BookMetadataAggregationRepository
|
||||
import org.gotson.komga.domain.persistence.BookMetadataRepository
|
||||
import org.gotson.komga.domain.persistence.BookRepository
|
||||
import org.gotson.komga.domain.persistence.LibraryRepository
|
||||
import org.gotson.komga.domain.persistence.MediaRepository
|
||||
import org.gotson.komga.domain.persistence.ReadProgressRepository
|
||||
import org.gotson.komga.domain.persistence.SeriesCollectionRepository
|
||||
|
|
@ -37,6 +39,7 @@ private val natSortComparator: Comparator<String> = CaseInsensitiveSimpleNatural
|
|||
|
||||
@Service
|
||||
class SeriesLifecycle(
|
||||
private val libraryRepository: LibraryRepository,
|
||||
private val bookRepository: BookRepository,
|
||||
private val bookLifecycle: BookLifecycle,
|
||||
private val mediaRepository: MediaRepository,
|
||||
|
|
@ -197,14 +200,23 @@ class SeriesLifecycle(
|
|||
return selected
|
||||
}
|
||||
|
||||
fun getThumbnailBytes(seriesId: String): ByteArray? {
|
||||
fun getThumbnailBytes(seriesId: String, userId: String): ByteArray? {
|
||||
getThumbnail(seriesId)?.let {
|
||||
return File(it.url.toURI()).readBytes()
|
||||
}
|
||||
|
||||
bookRepository.findFirstIdInSeriesOrNull(seriesId)?.let { bookId ->
|
||||
return bookLifecycle.getThumbnailBytes(bookId)
|
||||
seriesRepository.findByIdOrNull(seriesId)?.let { series ->
|
||||
val bookId = when (libraryRepository.findById(series.libraryId).seriesCover) {
|
||||
Library.SeriesCover.FIRST -> bookRepository.findFirstIdInSeriesOrNull(seriesId)
|
||||
Library.SeriesCover.FIRST_UNREAD_OR_FIRST -> bookRepository.findFirstUnreadIdInSeriesOrNull(seriesId, userId)
|
||||
?: bookRepository.findFirstIdInSeriesOrNull(seriesId)
|
||||
Library.SeriesCover.FIRST_UNREAD_OR_LAST -> bookRepository.findFirstUnreadIdInSeriesOrNull(seriesId, userId)
|
||||
?: bookRepository.findLastIdInSeriesOrNull(seriesId)
|
||||
Library.SeriesCover.LAST -> bookRepository.findLastIdInSeriesOrNull(seriesId)
|
||||
}
|
||||
if (bookId != null) return bookLifecycle.getThumbnailBytes(bookId)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ class BookDao(
|
|||
private val b = Tables.BOOK
|
||||
private val m = Tables.MEDIA
|
||||
private val d = Tables.BOOK_METADATA
|
||||
private val r = Tables.READ_PROGRESS
|
||||
|
||||
private val sorts = mapOf(
|
||||
"createdDate" to b.CREATED_DATE,
|
||||
|
|
@ -139,6 +140,26 @@ class BookDao(
|
|||
.limit(1)
|
||||
.fetchOne(b.ID)
|
||||
|
||||
override fun findLastIdInSeriesOrNull(seriesId: String): String? =
|
||||
dsl.select(b.ID)
|
||||
.from(b)
|
||||
.leftJoin(d).on(b.ID.eq(d.BOOK_ID))
|
||||
.where(b.SERIES_ID.eq(seriesId))
|
||||
.orderBy(d.NUMBER_SORT.desc())
|
||||
.limit(1)
|
||||
.fetchOne(b.ID)
|
||||
|
||||
override fun findFirstUnreadIdInSeriesOrNull(seriesId: String, userId: String): String? ? =
|
||||
dsl.select(b.ID)
|
||||
.from(b)
|
||||
.leftJoin(d).on(b.ID.eq(d.BOOK_ID))
|
||||
.leftJoin(r).on(b.ID.eq(r.BOOK_ID)).and(r.USER_ID.eq(userId).or(r.USER_ID.isNull))
|
||||
.where(b.SERIES_ID.eq(seriesId))
|
||||
.and(r.COMPLETED.isNull)
|
||||
.orderBy(d.NUMBER_SORT)
|
||||
.limit(1)
|
||||
.fetchOne(b.ID)
|
||||
|
||||
override fun findAllIdsBySeriesId(seriesId: String): Collection<String> =
|
||||
dsl.select(b.ID)
|
||||
.from(b)
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ class LibraryDao(
|
|||
.set(l.REPAIR_EXTENSIONS, library.repairExtensions)
|
||||
.set(l.CONVERT_TO_CBZ, library.convertToCbz)
|
||||
.set(l.EMPTY_TRASH_AFTER_SCAN, library.emptyTrashAfterScan)
|
||||
.set(l.SERIES_COVER, library.seriesCover.toString())
|
||||
.execute()
|
||||
}
|
||||
|
||||
|
|
@ -97,6 +98,7 @@ class LibraryDao(
|
|||
.set(l.REPAIR_EXTENSIONS, library.repairExtensions)
|
||||
.set(l.CONVERT_TO_CBZ, library.convertToCbz)
|
||||
.set(l.EMPTY_TRASH_AFTER_SCAN, library.emptyTrashAfterScan)
|
||||
.set(l.SERIES_COVER, library.seriesCover.toString())
|
||||
.set(l.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(l.ID.eq(library.id))
|
||||
.execute()
|
||||
|
|
@ -122,6 +124,7 @@ class LibraryDao(
|
|||
repairExtensions = repairExtensions,
|
||||
convertToCbz = convertToCbz,
|
||||
emptyTrashAfterScan = emptyTrashAfterScan,
|
||||
seriesCover = Library.SeriesCover.valueOf(seriesCover),
|
||||
id = id,
|
||||
createdDate = createdDate.toCurrentTimeZone(),
|
||||
lastModifiedDate = lastModifiedDate.toCurrentTimeZone()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package org.gotson.komga.interfaces.rest
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.gotson.komga.application.tasks.HIGH_PRIORITY
|
||||
import org.gotson.komga.application.tasks.TaskReceiver
|
||||
import org.gotson.komga.domain.model.DirectoryNotFoundException
|
||||
|
|
@ -14,7 +13,11 @@ import org.gotson.komga.domain.persistence.SeriesRepository
|
|||
import org.gotson.komga.domain.service.LibraryLifecycle
|
||||
import org.gotson.komga.infrastructure.security.KomgaPrincipal
|
||||
import org.gotson.komga.infrastructure.web.filePathToUrl
|
||||
import org.gotson.komga.infrastructure.web.toFilePath
|
||||
import org.gotson.komga.interfaces.rest.dto.LibraryCreationDto
|
||||
import org.gotson.komga.interfaces.rest.dto.LibraryDto
|
||||
import org.gotson.komga.interfaces.rest.dto.LibraryUpdateDto
|
||||
import org.gotson.komga.interfaces.rest.dto.toDomain
|
||||
import org.gotson.komga.interfaces.rest.dto.toDto
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.MediaType
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
|
|
@ -31,9 +34,6 @@ import org.springframework.web.bind.annotation.RestController
|
|||
import org.springframework.web.server.ResponseStatusException
|
||||
import java.io.FileNotFoundException
|
||||
import javax.validation.Valid
|
||||
import javax.validation.constraints.NotBlank
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@RestController
|
||||
@RequestMapping("api/v1/libraries", produces = [MediaType.APPLICATION_JSON_VALUE])
|
||||
|
|
@ -90,6 +90,7 @@ class LibraryController(
|
|||
repairExtensions = library.repairExtensions,
|
||||
convertToCbz = library.convertToCbz,
|
||||
emptyTrashAfterScan = library.emptyTrashAfterScan,
|
||||
seriesCover = library.seriesCover.toDomain(),
|
||||
)
|
||||
).toDto(includeRoot = principal.user.roleAdmin)
|
||||
} catch (e: Exception) {
|
||||
|
|
@ -129,6 +130,7 @@ class LibraryController(
|
|||
repairExtensions = library.repairExtensions,
|
||||
convertToCbz = library.convertToCbz,
|
||||
emptyTrashAfterScan = library.emptyTrashAfterScan,
|
||||
seriesCover = library.seriesCover.toDomain(),
|
||||
)
|
||||
libraryLifecycle.updateLibrary(toUpdate)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
|
@ -183,81 +185,3 @@ class LibraryController(
|
|||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
data class LibraryCreationDto(
|
||||
@get:NotBlank val name: String,
|
||||
@get:NotBlank val root: String,
|
||||
val importComicInfoBook: Boolean = true,
|
||||
val importComicInfoSeries: Boolean = true,
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importComicInfoReadList: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true,
|
||||
val importMylarSeries: Boolean = true,
|
||||
val importLocalArtwork: Boolean = true,
|
||||
val importBarcodeIsbn: Boolean = true,
|
||||
val scanForceModifiedTime: Boolean = false,
|
||||
val scanDeep: Boolean = false,
|
||||
val repairExtensions: Boolean = false,
|
||||
val convertToCbz: Boolean = false,
|
||||
val emptyTrashAfterScan: Boolean = false,
|
||||
)
|
||||
|
||||
data class LibraryDto(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val root: String,
|
||||
val importComicInfoBook: Boolean,
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
val importLocalArtwork: Boolean,
|
||||
val importBarcodeIsbn: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean,
|
||||
val repairExtensions: Boolean,
|
||||
val convertToCbz: Boolean,
|
||||
val emptyTrashAfterScan: Boolean,
|
||||
)
|
||||
|
||||
data class LibraryUpdateDto(
|
||||
@get:NotBlank val name: String,
|
||||
@get:NotBlank val root: String,
|
||||
val importComicInfoBook: Boolean,
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
val importLocalArtwork: Boolean,
|
||||
val importBarcodeIsbn: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean,
|
||||
val repairExtensions: Boolean,
|
||||
val convertToCbz: Boolean,
|
||||
val emptyTrashAfterScan: Boolean,
|
||||
)
|
||||
|
||||
fun Library.toDto(includeRoot: Boolean) = LibraryDto(
|
||||
id = id,
|
||||
name = name,
|
||||
root = if (includeRoot) this.root.toFilePath() else "",
|
||||
importComicInfoBook = importComicInfoBook,
|
||||
importComicInfoSeries = importComicInfoSeries,
|
||||
importComicInfoCollection = importComicInfoCollection,
|
||||
importComicInfoReadList = importComicInfoReadList,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries,
|
||||
importMylarSeries = importMylarSeries,
|
||||
importLocalArtwork = importLocalArtwork,
|
||||
importBarcodeIsbn = importBarcodeIsbn,
|
||||
scanForceModifiedTime = scanForceModifiedTime,
|
||||
scanDeep = scanDeep,
|
||||
repairExtensions = repairExtensions,
|
||||
convertToCbz = convertToCbz,
|
||||
emptyTrashAfterScan = emptyTrashAfterScan,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ class SeriesCollectionController(
|
|||
collectionRepository.findByIdOrNull(id, principal.user.getAuthorizedLibraryIds(null))?.let {
|
||||
return ResponseEntity.ok()
|
||||
.cacheControl(CacheControl.maxAge(1, TimeUnit.HOURS).cachePrivate())
|
||||
.body(collectionLifecycle.getThumbnailBytes(it))
|
||||
.body(collectionLifecycle.getThumbnailBytes(it, principal.user.id))
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ class SeriesController(
|
|||
if (!principal.user.canAccessLibrary(it)) throw ResponseStatusException(HttpStatus.FORBIDDEN)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
|
||||
return seriesLifecycle.getThumbnailBytes(seriesId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
return seriesLifecycle.getThumbnailBytes(seriesId, principal.user.id) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
}
|
||||
|
||||
@PageableAsQueryParam
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
package org.gotson.komga.interfaces.rest.dto
|
||||
|
||||
import javax.validation.constraints.NotBlank
|
||||
|
||||
data class LibraryCreationDto(
|
||||
@get:NotBlank val name: String,
|
||||
@get:NotBlank val root: String,
|
||||
val importComicInfoBook: Boolean = true,
|
||||
val importComicInfoSeries: Boolean = true,
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importComicInfoReadList: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true,
|
||||
val importMylarSeries: Boolean = true,
|
||||
val importLocalArtwork: Boolean = true,
|
||||
val importBarcodeIsbn: Boolean = true,
|
||||
val scanForceModifiedTime: Boolean = false,
|
||||
val scanDeep: Boolean = false,
|
||||
val repairExtensions: Boolean = false,
|
||||
val convertToCbz: Boolean = false,
|
||||
val emptyTrashAfterScan: Boolean = false,
|
||||
val seriesCover: SeriesCoverDto = SeriesCoverDto.FIRST,
|
||||
)
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package org.gotson.komga.interfaces.rest.dto
|
||||
|
||||
import org.gotson.komga.domain.model.Library
|
||||
import org.gotson.komga.infrastructure.web.toFilePath
|
||||
|
||||
data class LibraryDto(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val root: String,
|
||||
val importComicInfoBook: Boolean,
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
val importLocalArtwork: Boolean,
|
||||
val importBarcodeIsbn: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean,
|
||||
val repairExtensions: Boolean,
|
||||
val convertToCbz: Boolean,
|
||||
val emptyTrashAfterScan: Boolean,
|
||||
val seriesCover: SeriesCoverDto,
|
||||
)
|
||||
|
||||
fun Library.toDto(includeRoot: Boolean) = LibraryDto(
|
||||
id = id,
|
||||
name = name,
|
||||
root = if (includeRoot) this.root.toFilePath() else "",
|
||||
importComicInfoBook = importComicInfoBook,
|
||||
importComicInfoSeries = importComicInfoSeries,
|
||||
importComicInfoCollection = importComicInfoCollection,
|
||||
importComicInfoReadList = importComicInfoReadList,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries,
|
||||
importMylarSeries = importMylarSeries,
|
||||
importLocalArtwork = importLocalArtwork,
|
||||
importBarcodeIsbn = importBarcodeIsbn,
|
||||
scanForceModifiedTime = scanForceModifiedTime,
|
||||
scanDeep = scanDeep,
|
||||
repairExtensions = repairExtensions,
|
||||
convertToCbz = convertToCbz,
|
||||
emptyTrashAfterScan = emptyTrashAfterScan,
|
||||
seriesCover = seriesCover.toDto(),
|
||||
)
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package org.gotson.komga.interfaces.rest.dto
|
||||
|
||||
import javax.validation.constraints.NotBlank
|
||||
|
||||
data class LibraryUpdateDto(
|
||||
@get:NotBlank val name: String,
|
||||
@get:NotBlank val root: String,
|
||||
val importComicInfoBook: Boolean,
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importComicInfoReadList: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean,
|
||||
val importMylarSeries: Boolean,
|
||||
val importLocalArtwork: Boolean,
|
||||
val importBarcodeIsbn: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean,
|
||||
val repairExtensions: Boolean,
|
||||
val convertToCbz: Boolean,
|
||||
val emptyTrashAfterScan: Boolean,
|
||||
val seriesCover: SeriesCoverDto,
|
||||
)
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.gotson.komga.interfaces.rest.dto
|
||||
|
||||
import org.gotson.komga.domain.model.Library
|
||||
|
||||
enum class SeriesCoverDto {
|
||||
FIRST,
|
||||
FIRST_UNREAD_OR_FIRST,
|
||||
FIRST_UNREAD_OR_LAST,
|
||||
LAST,
|
||||
}
|
||||
|
||||
fun Library.SeriesCover.toDto() = when (this) {
|
||||
Library.SeriesCover.FIRST -> SeriesCoverDto.FIRST
|
||||
Library.SeriesCover.FIRST_UNREAD_OR_FIRST -> SeriesCoverDto.FIRST_UNREAD_OR_FIRST
|
||||
Library.SeriesCover.FIRST_UNREAD_OR_LAST -> SeriesCoverDto.FIRST_UNREAD_OR_LAST
|
||||
Library.SeriesCover.LAST -> SeriesCoverDto.LAST
|
||||
}
|
||||
|
||||
fun SeriesCoverDto.toDomain() = when (this) {
|
||||
SeriesCoverDto.FIRST -> Library.SeriesCover.FIRST
|
||||
SeriesCoverDto.FIRST_UNREAD_OR_FIRST -> Library.SeriesCover.FIRST_UNREAD_OR_FIRST
|
||||
SeriesCoverDto.FIRST_UNREAD_OR_LAST -> Library.SeriesCover.FIRST_UNREAD_OR_LAST
|
||||
SeriesCoverDto.LAST -> Library.SeriesCover.LAST
|
||||
}
|
||||
|
|
@ -67,6 +67,7 @@ class LibraryDaoTest(
|
|||
repairExtensions = true,
|
||||
convertToCbz = true,
|
||||
emptyTrashAfterScan = true,
|
||||
seriesCover = Library.SeriesCover.LAST,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -93,6 +94,7 @@ class LibraryDaoTest(
|
|||
assertThat(modified.repairExtensions).isEqualTo(updated.repairExtensions)
|
||||
assertThat(modified.convertToCbz).isEqualTo(updated.convertToCbz)
|
||||
assertThat(modified.emptyTrashAfterScan).isEqualTo(updated.emptyTrashAfterScan)
|
||||
assertThat(modified.seriesCover).isEqualTo(updated.seriesCover)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
Loading…
Reference in a new issue