diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/ChaptersFilesProvider.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/ChaptersFilesProvider.kt index 4b971240..20d48d35 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/ChaptersFilesProvider.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/ChaptersFilesProvider.kt @@ -13,6 +13,8 @@ import suwayomi.tachidesk.manga.impl.Page import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter import suwayomi.tachidesk.manga.impl.util.createComicInfoFile import suwayomi.tachidesk.manga.impl.util.getChapterCachePath +import suwayomi.tachidesk.manga.impl.util.getChapterDownloadPath +import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse import suwayomi.tachidesk.manga.model.table.ChapterTable import suwayomi.tachidesk.manga.model.table.MangaTable import java.io.File @@ -28,21 +30,40 @@ abstract class ChaptersFilesProvider(val mangaId: Int, val chapterId: Int) : Dow return RetrieveFile1Args(::getImageImpl) } + /** + * Extract the existing download to the base download folder (see [getChapterDownloadPath]) + */ + protected abstract fun extractExistingDownload() + + protected abstract suspend fun handleSuccessfulDownload() + @OptIn(FlowPreview::class) - open suspend fun downloadImpl( + private suspend fun downloadImpl( download: DownloadChapter, scope: CoroutineScope, step: suspend (DownloadChapter?, Boolean) -> Unit, ): Boolean { - val pageCount = download.chapter.pageCount - val chapterDir = getChapterCachePath(mangaId, chapterId) - val folder = File(chapterDir) - folder.mkdirs() + extractExistingDownload() + val finalDownloadFolder = getChapterDownloadPath(mangaId, chapterId) + + val cacheChapterDir = getChapterCachePath(mangaId, chapterId) + val downloadCacheFolder = File(cacheChapterDir) + downloadCacheFolder.mkdirs() + + val pageCount = download.chapter.pageCount for (pageNum in 0 until pageCount) { var pageProgressJob: Job? = null val fileName = Page.getPageName(pageNum) // might have to change this to index stored in database - if (File(folder, fileName).exists()) continue + + val pageExistsInFinalDownloadFolder = ImageResponse.findFileNameStartingWith(finalDownloadFolder, fileName) != null + val pageExistsInCacheDownloadFolder = ImageResponse.findFileNameStartingWith(cacheChapterDir, fileName) != null + + val doesPageAlreadyExist = pageExistsInFinalDownloadFolder || pageExistsInCacheDownloadFolder + if (doesPageAlreadyExist) { + continue + } + try { Page.getPageImage( mangaId = download.mangaId, @@ -69,7 +90,7 @@ abstract class ChaptersFilesProvider(val mangaId: Int, val chapterId: Int) : Dow } createComicInfoFile( - folder.toPath(), + downloadCacheFolder.toPath(), transaction { MangaTable.select { MangaTable.id eq mangaId }.first() }, @@ -78,6 +99,10 @@ abstract class ChaptersFilesProvider(val mangaId: Int, val chapterId: Int) : Dow }, ) + handleSuccessfulDownload() + + File(cacheChapterDir).deleteRecursively() + return true } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/ArchiveProvider.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/ArchiveProvider.kt index 80f0bc1d..4d7886ff 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/ArchiveProvider.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/ArchiveProvider.kt @@ -1,6 +1,5 @@ package suwayomi.tachidesk.manga.impl.download.fileProvider.impl -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.apache.commons.compress.archivers.zip.ZipArchiveEntry @@ -11,7 +10,6 @@ import org.kodein.di.DI import org.kodein.di.conf.global import org.kodein.di.instance import suwayomi.tachidesk.manga.impl.download.fileProvider.ChaptersFilesProvider -import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter import suwayomi.tachidesk.manga.impl.util.getChapterCachePath import suwayomi.tachidesk.manga.impl.util.getChapterCbzPath import suwayomi.tachidesk.manga.impl.util.getMangaDownloadDir @@ -32,17 +30,21 @@ class ArchiveProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(mang return Pair(inputStream.buffered(), "image/$fileType") } - override suspend fun downloadImpl( - download: DownloadChapter, - scope: CoroutineScope, - step: suspend (DownloadChapter?, Boolean) -> Unit, - ): Boolean { + override fun extractExistingDownload() { + val outputFile = File(getChapterCbzPath(mangaId, chapterId)) + val chapterCacheFolder = File(getChapterCachePath(mangaId, chapterId)) + + if (!outputFile.exists()) { + return + } + + extractCbzFile(outputFile, chapterCacheFolder) + } + + override suspend fun handleSuccessfulDownload() { val mangaDownloadFolder = File(getMangaDownloadDir(mangaId)) val outputFile = File(getChapterCbzPath(mangaId, chapterId)) val chapterCacheFolder = File(getChapterCachePath(mangaId, chapterId)) - if (outputFile.exists()) handleExistingCbzFile(outputFile, chapterCacheFolder) - - super.downloadImpl(download, scope, step) withContext(Dispatchers.IO) { mangaDownloadFolder.mkdirs() @@ -68,8 +70,6 @@ class ArchiveProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(mang if (chapterCacheFolder.exists() && chapterCacheFolder.isDirectory) { chapterCacheFolder.deleteRecursively() } - - return true } override fun delete(): Boolean { @@ -83,7 +83,7 @@ class ArchiveProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(mang return cbzDeleted } - private fun handleExistingCbzFile( + private fun extractCbzFile( cbzFile: File, chapterFolder: File, ) { diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/FolderProvider.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/FolderProvider.kt index 9c3b0b26..3b5766dc 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/FolderProvider.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/download/fileProvider/impl/FolderProvider.kt @@ -1,11 +1,9 @@ package suwayomi.tachidesk.manga.impl.download.fileProvider.impl -import kotlinx.coroutines.CoroutineScope import org.kodein.di.DI import org.kodein.di.conf.global import org.kodein.di.instance import suwayomi.tachidesk.manga.impl.download.fileProvider.ChaptersFilesProvider -import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter import suwayomi.tachidesk.manga.impl.util.getChapterCachePath import suwayomi.tachidesk.manga.impl.util.getChapterDownloadPath import suwayomi.tachidesk.manga.impl.util.storage.FileDeletionHelper @@ -29,23 +27,16 @@ class FolderProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(manga return Pair(FileInputStream(file).buffered(), "image/$fileType") } - override suspend fun downloadImpl( - download: DownloadChapter, - scope: CoroutineScope, - step: suspend (DownloadChapter?, Boolean) -> Unit, - ): Boolean { + override fun extractExistingDownload() { + // nothing to do + } + + override suspend fun handleSuccessfulDownload() { val chapterDir = getChapterDownloadPath(mangaId, chapterId) val folder = File(chapterDir) - val downloadSucceeded = super.downloadImpl(download, scope, step) - if (!downloadSucceeded) { - return false - } - val cacheChapterDir = getChapterCachePath(mangaId, chapterId) File(cacheChapterDir).copyRecursively(folder, true) - - return true } override fun delete(): Boolean {