mirror of
https://github.com/Suwayomi/Tachidesk.git
synced 2025-12-10 06:42:07 +01:00
Fix/recognition of already downloaded chapters (#922)
* Remove overrides of "ChapterFilesProvider::downloadImpl"
* Check final download folder for existing page on download
Downloads were changed to get downloaded to the system temp folder instead to directly into the final download folder.
This broke the check for existing pages, because now only the temp folder was checked instead of both the temp and the final download folder.
Regression introduced with 1c9a139006
* Properly check for already existing downloaded pages
The previous check was always false because the file ending of the page file is unknown and thus, missing from the created file path
* Cleanup cache download folder
This commit is contained in:
@@ -13,6 +13,8 @@ import suwayomi.tachidesk.manga.impl.Page
|
|||||||
import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter
|
||||||
import suwayomi.tachidesk.manga.impl.util.createComicInfoFile
|
import suwayomi.tachidesk.manga.impl.util.createComicInfoFile
|
||||||
import suwayomi.tachidesk.manga.impl.util.getChapterCachePath
|
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.ChapterTable
|
||||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -28,21 +30,40 @@ abstract class ChaptersFilesProvider(val mangaId: Int, val chapterId: Int) : Dow
|
|||||||
return RetrieveFile1Args(::getImageImpl)
|
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)
|
@OptIn(FlowPreview::class)
|
||||||
open suspend fun downloadImpl(
|
private suspend fun downloadImpl(
|
||||||
download: DownloadChapter,
|
download: DownloadChapter,
|
||||||
scope: CoroutineScope,
|
scope: CoroutineScope,
|
||||||
step: suspend (DownloadChapter?, Boolean) -> Unit,
|
step: suspend (DownloadChapter?, Boolean) -> Unit,
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val pageCount = download.chapter.pageCount
|
extractExistingDownload()
|
||||||
val chapterDir = getChapterCachePath(mangaId, chapterId)
|
|
||||||
val folder = File(chapterDir)
|
|
||||||
folder.mkdirs()
|
|
||||||
|
|
||||||
|
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) {
|
for (pageNum in 0 until pageCount) {
|
||||||
var pageProgressJob: Job? = null
|
var pageProgressJob: Job? = null
|
||||||
val fileName = Page.getPageName(pageNum) // might have to change this to index stored in database
|
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 {
|
try {
|
||||||
Page.getPageImage(
|
Page.getPageImage(
|
||||||
mangaId = download.mangaId,
|
mangaId = download.mangaId,
|
||||||
@@ -69,7 +90,7 @@ abstract class ChaptersFilesProvider(val mangaId: Int, val chapterId: Int) : Dow
|
|||||||
}
|
}
|
||||||
|
|
||||||
createComicInfoFile(
|
createComicInfoFile(
|
||||||
folder.toPath(),
|
downloadCacheFolder.toPath(),
|
||||||
transaction {
|
transaction {
|
||||||
MangaTable.select { MangaTable.id eq mangaId }.first()
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package suwayomi.tachidesk.manga.impl.download.fileProvider.impl
|
package suwayomi.tachidesk.manga.impl.download.fileProvider.impl
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
|
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.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.tachidesk.manga.impl.download.fileProvider.ChaptersFilesProvider
|
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.getChapterCachePath
|
||||||
import suwayomi.tachidesk.manga.impl.util.getChapterCbzPath
|
import suwayomi.tachidesk.manga.impl.util.getChapterCbzPath
|
||||||
import suwayomi.tachidesk.manga.impl.util.getMangaDownloadDir
|
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")
|
return Pair(inputStream.buffered(), "image/$fileType")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun downloadImpl(
|
override fun extractExistingDownload() {
|
||||||
download: DownloadChapter,
|
val outputFile = File(getChapterCbzPath(mangaId, chapterId))
|
||||||
scope: CoroutineScope,
|
val chapterCacheFolder = File(getChapterCachePath(mangaId, chapterId))
|
||||||
step: suspend (DownloadChapter?, Boolean) -> Unit,
|
|
||||||
): Boolean {
|
if (!outputFile.exists()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
extractCbzFile(outputFile, chapterCacheFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun handleSuccessfulDownload() {
|
||||||
val mangaDownloadFolder = File(getMangaDownloadDir(mangaId))
|
val mangaDownloadFolder = File(getMangaDownloadDir(mangaId))
|
||||||
val outputFile = File(getChapterCbzPath(mangaId, chapterId))
|
val outputFile = File(getChapterCbzPath(mangaId, chapterId))
|
||||||
val chapterCacheFolder = File(getChapterCachePath(mangaId, chapterId))
|
val chapterCacheFolder = File(getChapterCachePath(mangaId, chapterId))
|
||||||
if (outputFile.exists()) handleExistingCbzFile(outputFile, chapterCacheFolder)
|
|
||||||
|
|
||||||
super.downloadImpl(download, scope, step)
|
|
||||||
|
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
mangaDownloadFolder.mkdirs()
|
mangaDownloadFolder.mkdirs()
|
||||||
@@ -68,8 +70,6 @@ class ArchiveProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(mang
|
|||||||
if (chapterCacheFolder.exists() && chapterCacheFolder.isDirectory) {
|
if (chapterCacheFolder.exists() && chapterCacheFolder.isDirectory) {
|
||||||
chapterCacheFolder.deleteRecursively()
|
chapterCacheFolder.deleteRecursively()
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(): Boolean {
|
override fun delete(): Boolean {
|
||||||
@@ -83,7 +83,7 @@ class ArchiveProvider(mangaId: Int, chapterId: Int) : ChaptersFilesProvider(mang
|
|||||||
return cbzDeleted
|
return cbzDeleted
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleExistingCbzFile(
|
private fun extractCbzFile(
|
||||||
cbzFile: File,
|
cbzFile: File,
|
||||||
chapterFolder: File,
|
chapterFolder: File,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package suwayomi.tachidesk.manga.impl.download.fileProvider.impl
|
package suwayomi.tachidesk.manga.impl.download.fileProvider.impl
|
||||||
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.tachidesk.manga.impl.download.fileProvider.ChaptersFilesProvider
|
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.getChapterCachePath
|
||||||
import suwayomi.tachidesk.manga.impl.util.getChapterDownloadPath
|
import suwayomi.tachidesk.manga.impl.util.getChapterDownloadPath
|
||||||
import suwayomi.tachidesk.manga.impl.util.storage.FileDeletionHelper
|
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")
|
return Pair(FileInputStream(file).buffered(), "image/$fileType")
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun downloadImpl(
|
override fun extractExistingDownload() {
|
||||||
download: DownloadChapter,
|
// nothing to do
|
||||||
scope: CoroutineScope,
|
}
|
||||||
step: suspend (DownloadChapter?, Boolean) -> Unit,
|
|
||||||
): Boolean {
|
override suspend fun handleSuccessfulDownload() {
|
||||||
val chapterDir = getChapterDownloadPath(mangaId, chapterId)
|
val chapterDir = getChapterDownloadPath(mangaId, chapterId)
|
||||||
val folder = File(chapterDir)
|
val folder = File(chapterDir)
|
||||||
|
|
||||||
val downloadSucceeded = super.downloadImpl(download, scope, step)
|
|
||||||
if (!downloadSucceeded) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val cacheChapterDir = getChapterCachePath(mangaId, chapterId)
|
val cacheChapterDir = getChapterCachePath(mangaId, chapterId)
|
||||||
File(cacheChapterDir).copyRecursively(folder, true)
|
File(cacheChapterDir).copyRecursively(folder, true)
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(): Boolean {
|
override fun delete(): Boolean {
|
||||||
|
|||||||
Reference in New Issue
Block a user