mirror of
https://github.com/gotson/komga.git
synced 2025-01-09 04:08:00 +08:00
feat: scanner option per library
Library can now have scanner options: - scanForceModifiedTime replaces filesystemScannerForceDirectoryModifiedTime - scanDeep will bypass the modified date comparison for series, and check all books The configuration key komga.filesystem-scanner-force-directory-modified-time is deprecated
This commit is contained in:
parent
fe22cb5ce6
commit
4da6ff9fd4
@ -0,0 +1,4 @@
|
||||
alter table library
|
||||
add column SCAN_FORCE_MODIFIED_TIME boolean NOT NULL DEFAULT 0;
|
||||
alter table library
|
||||
add column SCAN_DEEP boolean NOT NULL DEFAULT 0;
|
@ -14,6 +14,8 @@ data class Library(
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true,
|
||||
val scanForceModifiedTime: Boolean = false,
|
||||
val scanDeep: Boolean = false,
|
||||
|
||||
val id: String = TsidCreator.getTsidString256(),
|
||||
|
||||
|
@ -25,12 +25,11 @@ class FileSystemScanner(
|
||||
|
||||
val supportedExtensions = listOf("cbz", "zip", "cbr", "rar", "pdf", "epub")
|
||||
|
||||
fun scanRootFolder(root: Path): Map<Series, List<Book>> {
|
||||
fun scanRootFolder(root: Path, forceDirectoryModifiedTime: Boolean = false): Map<Series, List<Book>> {
|
||||
logger.info { "Scanning folder: $root" }
|
||||
logger.info { "Supported extensions: $supportedExtensions" }
|
||||
logger.info { "Excluded patterns: ${komgaProperties.librariesScanDirectoryExclusions}" }
|
||||
if (komgaProperties.filesystemScannerForceDirectoryModifiedTime)
|
||||
logger.info { "Force directory modified time: active" }
|
||||
logger.info { "Force directory modified time: $forceDirectoryModifiedTime" }
|
||||
|
||||
lateinit var scannedSeries: Map<Series, List<Book>>
|
||||
|
||||
@ -70,7 +69,7 @@ class FileSystemScanner(
|
||||
name = dir.fileName.toString(),
|
||||
url = dir.toUri().toURL(),
|
||||
fileLastModified =
|
||||
if (komgaProperties.filesystemScannerForceDirectoryModifiedTime)
|
||||
if (forceDirectoryModifiedTime)
|
||||
maxOf(dir.getUpdatedTime(), books.map { it.fileLastModified }.max()!!)
|
||||
else dir.getUpdatedTime()
|
||||
) to books
|
||||
|
@ -27,7 +27,7 @@ class LibraryScanner(
|
||||
logger.info { "Updating library: $library" }
|
||||
measureTime {
|
||||
val scannedSeries =
|
||||
fileSystemScanner.scanRootFolder(Paths.get(library.root.toURI()))
|
||||
fileSystemScanner.scanRootFolder(Paths.get(library.root.toURI()), library.scanForceModifiedTime)
|
||||
.map { (series, books) ->
|
||||
series.copy(libraryId = library.id) to books.map { it.copy(libraryId = library.id) }
|
||||
}.toMap()
|
||||
@ -59,15 +59,15 @@ class LibraryScanner(
|
||||
} else {
|
||||
// if series already exists, update it
|
||||
logger.debug { "Scanned series already exists. Scanned: $newSeries, Existing: $existingSeries" }
|
||||
if (newSeries.fileLastModified.truncatedTo(ChronoUnit.MILLIS) != existingSeries.fileLastModified.truncatedTo(ChronoUnit.MILLIS)) {
|
||||
val seriesChanged = newSeries.fileLastModified.truncatedTo(ChronoUnit.MILLIS) != existingSeries.fileLastModified.truncatedTo(ChronoUnit.MILLIS)
|
||||
if (seriesChanged) {
|
||||
logger.info { "Series changed on disk, updating: $existingSeries" }
|
||||
|
||||
seriesRepository.update(existingSeries.copy(fileLastModified = newSeries.fileLastModified))
|
||||
|
||||
}
|
||||
if (library.scanDeep || seriesChanged) {
|
||||
// update list of books with existing entities if they exist
|
||||
val existingBooks = bookRepository.findBySeriesId(existingSeries.id)
|
||||
logger.debug { "Existing books: $existingBooks" }
|
||||
|
||||
// update existing books
|
||||
newBooks.forEach { newBook ->
|
||||
logger.debug { "Trying to match scanned book by url: $newBook" }
|
||||
|
@ -16,6 +16,7 @@ class KomgaProperties {
|
||||
|
||||
var librariesScanDirectoryExclusions: List<String> = emptyList()
|
||||
|
||||
@Deprecated("Deprecated since 0.56.0. Use per-library option instead")
|
||||
var filesystemScannerForceDirectoryModifiedTime: Boolean = false
|
||||
|
||||
var rememberMe = RememberMe()
|
||||
|
@ -72,6 +72,8 @@ class LibraryDao(
|
||||
.set(l.IMPORT_COMICINFO_COLLECTION, library.importComicInfoCollection)
|
||||
.set(l.IMPORT_EPUB_BOOK, library.importEpubBook)
|
||||
.set(l.IMPORT_EPUB_SERIES, library.importEpubSeries)
|
||||
.set(l.SCAN_FORCE_MODIFIED_TIME, library.scanForceModifiedTime)
|
||||
.set(l.SCAN_DEEP, library.scanDeep)
|
||||
.execute()
|
||||
}
|
||||
|
||||
@ -84,6 +86,8 @@ class LibraryDao(
|
||||
.set(l.IMPORT_COMICINFO_COLLECTION, library.importComicInfoCollection)
|
||||
.set(l.IMPORT_EPUB_BOOK, library.importEpubBook)
|
||||
.set(l.IMPORT_EPUB_SERIES, library.importEpubSeries)
|
||||
.set(l.SCAN_FORCE_MODIFIED_TIME, library.scanForceModifiedTime)
|
||||
.set(l.SCAN_DEEP, library.scanDeep)
|
||||
.set(l.LAST_MODIFIED_DATE, LocalDateTime.now(ZoneId.of("Z")))
|
||||
.where(l.ID.eq(library.id))
|
||||
.execute()
|
||||
@ -101,6 +105,8 @@ class LibraryDao(
|
||||
importComicInfoCollection = importComicinfoCollection,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries,
|
||||
scanForceModifiedTime = scanForceModifiedTime,
|
||||
scanDeep = scanDeep,
|
||||
id = id,
|
||||
createdDate = createdDate.toCurrentTimeZone(),
|
||||
lastModifiedDate = lastModifiedDate.toCurrentTimeZone()
|
||||
|
@ -77,7 +77,9 @@ class LibraryController(
|
||||
importComicInfoSeries = library.importComicInfoSeries,
|
||||
importComicInfoCollection = library.importComicInfoCollection,
|
||||
importEpubBook = library.importEpubBook,
|
||||
importEpubSeries = library.importEpubSeries
|
||||
importEpubSeries = library.importEpubSeries,
|
||||
scanForceModifiedTime = library.scanForceModifiedTime,
|
||||
scanDeep = library.scanDeep
|
||||
)
|
||||
).toDto(includeRoot = principal.user.roleAdmin)
|
||||
} catch (e: Exception) {
|
||||
@ -107,7 +109,9 @@ class LibraryController(
|
||||
importComicInfoSeries = library.importComicInfoSeries,
|
||||
importComicInfoCollection = library.importComicInfoCollection,
|
||||
importEpubBook = library.importEpubBook,
|
||||
importEpubSeries = library.importEpubSeries
|
||||
importEpubSeries = library.importEpubSeries,
|
||||
scanForceModifiedTime = library.scanForceModifiedTime,
|
||||
scanDeep = library.scanDeep
|
||||
)
|
||||
libraryLifecycle.updateLibrary(toUpdate)
|
||||
} ?: throw ResponseStatusException(HttpStatus.NOT_FOUND)
|
||||
@ -157,7 +161,9 @@ data class LibraryCreationDto(
|
||||
val importComicInfoSeries: Boolean = true,
|
||||
val importComicInfoCollection: Boolean = true,
|
||||
val importEpubBook: Boolean = true,
|
||||
val importEpubSeries: Boolean = true
|
||||
val importEpubSeries: Boolean = true,
|
||||
val scanForceModifiedTime: Boolean = false,
|
||||
val scanDeep: Boolean = false
|
||||
)
|
||||
|
||||
data class LibraryDto(
|
||||
@ -168,7 +174,9 @@ data class LibraryDto(
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean
|
||||
val importEpubSeries: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean
|
||||
)
|
||||
|
||||
data class LibraryUpdateDto(
|
||||
@ -178,7 +186,9 @@ data class LibraryUpdateDto(
|
||||
val importComicInfoSeries: Boolean,
|
||||
val importComicInfoCollection: Boolean,
|
||||
val importEpubBook: Boolean,
|
||||
val importEpubSeries: Boolean
|
||||
val importEpubSeries: Boolean,
|
||||
val scanForceModifiedTime: Boolean,
|
||||
val scanDeep: Boolean
|
||||
)
|
||||
|
||||
fun Library.toDto(includeRoot: Boolean) = LibraryDto(
|
||||
@ -189,5 +199,7 @@ fun Library.toDto(includeRoot: Boolean) = LibraryDto(
|
||||
importComicInfoSeries = importComicInfoSeries,
|
||||
importComicInfoCollection = importComicInfoCollection,
|
||||
importEpubBook = importEpubBook,
|
||||
importEpubSeries = importEpubSeries
|
||||
importEpubSeries = importEpubSeries,
|
||||
scanForceModifiedTime = scanForceModifiedTime,
|
||||
scanDeep = scanDeep
|
||||
)
|
||||
|
@ -1,5 +1,4 @@
|
||||
komga:
|
||||
filesystem-scanner-force-directory-modified-time: false
|
||||
remember-me:
|
||||
key: changeMe!
|
||||
validity: 2592000 # 1 month
|
||||
|
Loading…
Reference in New Issue
Block a user