diff --git a/komga/src/flyway/resources/db/migration/sqlite/V20200814142406__library_scan_options.sql b/komga/src/flyway/resources/db/migration/sqlite/V20200814142406__library_scan_options.sql new file mode 100644 index 000000000..1c527d350 --- /dev/null +++ b/komga/src/flyway/resources/db/migration/sqlite/V20200814142406__library_scan_options.sql @@ -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; diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/model/Library.kt b/komga/src/main/kotlin/org/gotson/komga/domain/model/Library.kt index 43afaec3e..174434419 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/model/Library.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/model/Library.kt @@ -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(), diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/FileSystemScanner.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/FileSystemScanner.kt index d401d4dee..f11d656a7 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/FileSystemScanner.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/FileSystemScanner.kt @@ -25,12 +25,11 @@ class FileSystemScanner( val supportedExtensions = listOf("cbz", "zip", "cbr", "rar", "pdf", "epub") - fun scanRootFolder(root: Path): Map> { + fun scanRootFolder(root: Path, forceDirectoryModifiedTime: Boolean = false): Map> { 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> @@ -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 diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/LibraryScanner.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/LibraryScanner.kt index 7367fc1b3..1442aeb7a 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/LibraryScanner.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/LibraryScanner.kt @@ -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" } diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/configuration/KomgaProperties.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/configuration/KomgaProperties.kt index 142cd69d5..596dfc105 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/configuration/KomgaProperties.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/configuration/KomgaProperties.kt @@ -16,6 +16,7 @@ class KomgaProperties { var librariesScanDirectoryExclusions: List = emptyList() + @Deprecated("Deprecated since 0.56.0. Use per-library option instead") var filesystemScannerForceDirectoryModifiedTime: Boolean = false var rememberMe = RememberMe() diff --git a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/LibraryDao.kt b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/LibraryDao.kt index b95369d97..779434357 100644 --- a/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/LibraryDao.kt +++ b/komga/src/main/kotlin/org/gotson/komga/infrastructure/jooq/LibraryDao.kt @@ -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() diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/LibraryController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/LibraryController.kt index 1f1dd38e4..7124a9b84 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/LibraryController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/rest/LibraryController.kt @@ -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 ) diff --git a/komga/src/main/resources/application-dev.yml b/komga/src/main/resources/application-dev.yml index 32e8d8c84..3e071dc20 100644 --- a/komga/src/main/resources/application-dev.yml +++ b/komga/src/main/resources/application-dev.yml @@ -1,5 +1,4 @@ komga: - filesystem-scanner-force-directory-modified-time: false remember-me: key: changeMe! validity: 2592000 # 1 month