diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt index 420302d2..d2536d19 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookImporter.kt @@ -4,8 +4,10 @@ import mu.KotlinLogging import org.gotson.komga.application.tasks.TaskReceiver import org.gotson.komga.domain.model.CopyMode import org.gotson.komga.domain.model.Media +import org.gotson.komga.domain.model.PathContainedInPath import org.gotson.komga.domain.model.Series 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.ReadListRepository import org.gotson.komga.domain.persistence.ReadProgressRepository @@ -37,11 +39,16 @@ class BookImporter( private val readProgressRepository: ReadProgressRepository, private val readListRepository: ReadListRepository, private val taskReceiver: TaskReceiver, + private val libraryRepository: LibraryRepository, ) { fun importBook(sourceFile: Path, series: Series, copyMode: CopyMode, destinationName: String? = null, upgradeBookId: String? = null) { if (sourceFile.notExists()) throw FileNotFoundException("File not found: $sourceFile") + libraryRepository.findAll().forEach { library -> + if (sourceFile.startsWith(library.path())) throw PathContainedInPath("Cannot import file that is part of an existing library") + } + val destFile = series.path().resolve( if (destinationName != null) Paths.get("$destinationName.${sourceFile.extension}").fileName.toString() else sourceFile.fileName.toString() diff --git a/komga/src/test/kotlin/org/gotson/komga/domain/model/Utils.kt b/komga/src/test/kotlin/org/gotson/komga/domain/model/Utils.kt index c91d2eab..9f0bec77 100644 --- a/komga/src/test/kotlin/org/gotson/komga/domain/model/Utils.kt +++ b/komga/src/test/kotlin/org/gotson/komga/domain/model/Utils.kt @@ -25,8 +25,12 @@ fun makeSeries(name: String, libraryId: String = "", url: URL? = null): Series { ) } -fun makeLibrary(name: String = "default", url: String = "file:/$name", id: String = TsidCreator.getTsid256().toString()): Library { - return Library(name, URL(url), id = id) +fun makeLibrary(name: String = "default", path: String = "file:/$name", id: String = TsidCreator.getTsid256().toString(), url: URL? = null): Library { + return Library( + name = name, + root = url ?: URL(path), + id = id + ) } fun makeBookPage(name: String) = diff --git a/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt b/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt index c6c50264..5bf44bfd 100644 --- a/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt +++ b/komga/src/test/kotlin/org/gotson/komga/domain/service/BookImporterTest.kt @@ -15,6 +15,7 @@ import org.gotson.komga.domain.model.BookPage import org.gotson.komga.domain.model.CopyMode import org.gotson.komga.domain.model.KomgaUser import org.gotson.komga.domain.model.Media +import org.gotson.komga.domain.model.PathContainedInPath import org.gotson.komga.domain.model.ReadList import org.gotson.komga.domain.model.makeBook import org.gotson.komga.domain.model.makeLibrary @@ -148,6 +149,31 @@ class BookImporterTest( } } + @Test + fun `given source file parf of a Komga library when importing then exception is thrown`() { + Jimfs.newFileSystem(Configuration.unix()).use { fs -> + // given + val sourceDir = fs.getPath("/source").createDirectory() + val sourceFile = sourceDir.resolve("source.cbz").createFile() + val destDir = fs.getPath("/dest").createDirectory() + + val series = makeSeries("dest").copy(url = destDir.toUri().toURL()) + + val libraryJimfs = makeLibrary("jimfs", url = sourceDir.toUri().toURL()) + libraryRepository.insert(libraryJimfs) + + // when + val thrown = Assertions.catchThrowable { + bookImporter.importBook(sourceFile, series, CopyMode.COPY) + } + + // then + assertThat(thrown).isInstanceOf(PathContainedInPath::class.java) + + libraryRepository.delete(libraryJimfs.id) + } + } + @Test fun `given book when importing then book is imported and series is sorted`() { Jimfs.newFileSystem(Configuration.unix()).use { fs -> diff --git a/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/LibraryControllerTest.kt b/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/LibraryControllerTest.kt index a8ae74f6..76cab10a 100644 --- a/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/LibraryControllerTest.kt +++ b/komga/src/test/kotlin/org/gotson/komga/interfaces/rest/LibraryControllerTest.kt @@ -31,7 +31,7 @@ class LibraryControllerTest( private val route = "/api/v1/libraries" - private val library = makeLibrary(url = "file:/library1", id = "1") + private val library = makeLibrary(path = "file:/library1", id = "1") @BeforeAll fun `setup library`() {