Fix concurrent manga downloading
This commit is contained in:
@@ -66,6 +66,7 @@ import org.koitharu.kotatsu.download.domain.DownloadState
|
|||||||
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
import org.koitharu.kotatsu.local.data.LocalMangaRepository
|
||||||
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
import org.koitharu.kotatsu.local.data.LocalStorageChanges
|
||||||
import org.koitharu.kotatsu.local.data.PagesCache
|
import org.koitharu.kotatsu.local.data.PagesCache
|
||||||
|
import org.koitharu.kotatsu.local.data.TempFileFilter
|
||||||
import org.koitharu.kotatsu.local.data.input.LocalMangaInput
|
import org.koitharu.kotatsu.local.data.input.LocalMangaInput
|
||||||
import org.koitharu.kotatsu.local.data.output.LocalMangaOutput
|
import org.koitharu.kotatsu.local.data.output.LocalMangaOutput
|
||||||
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
import org.koitharu.kotatsu.local.domain.model.LocalManga
|
||||||
@@ -173,7 +174,6 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
)
|
)
|
||||||
val destination = localMangaRepository.getOutputDir(manga)
|
val destination = localMangaRepository.getOutputDir(manga)
|
||||||
checkNotNull(destination) { applicationContext.getString(R.string.cannot_find_available_storage) }
|
checkNotNull(destination) { applicationContext.getString(R.string.cannot_find_available_storage) }
|
||||||
val tempFileName = "${manga.id}_$id.tmp"
|
|
||||||
var output: LocalMangaOutput? = null
|
var output: LocalMangaOutput? = null
|
||||||
try {
|
try {
|
||||||
if (manga.source == MangaSource.LOCAL) {
|
if (manga.source == MangaSource.LOCAL) {
|
||||||
@@ -185,8 +185,9 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
output = LocalMangaOutput.getOrCreate(destination, mangaDetails)
|
output = LocalMangaOutput.getOrCreate(destination, mangaDetails)
|
||||||
val coverUrl = mangaDetails.largeCoverUrl.ifNullOrEmpty { mangaDetails.coverUrl }
|
val coverUrl = mangaDetails.largeCoverUrl.ifNullOrEmpty { mangaDetails.coverUrl }
|
||||||
if (coverUrl.isNotEmpty()) {
|
if (coverUrl.isNotEmpty()) {
|
||||||
downloadFile(coverUrl, destination, tempFileName, repo.source).let { file ->
|
downloadFile(coverUrl, destination, repo.source).let { file ->
|
||||||
output.addCover(file, MimeTypeMap.getFileExtensionFromUrl(coverUrl))
|
output.addCover(file, MimeTypeMap.getFileExtensionFromUrl(coverUrl))
|
||||||
|
file.deleteAwait()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val chapters = getChapters(mangaDetails, includedIds)
|
val chapters = getChapters(mangaDetails, includedIds)
|
||||||
@@ -209,13 +210,16 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
runFailsafe {
|
runFailsafe {
|
||||||
val url = repo.getPageUrl(page)
|
val url = repo.getPageUrl(page)
|
||||||
val file = cache.get(url)
|
val file = cache.get(url)
|
||||||
?: downloadFile(url, destination, tempFileName, repo.source)
|
?: downloadFile(url, destination, repo.source)
|
||||||
output.addPage(
|
output.addPage(
|
||||||
chapter = chapter,
|
chapter = chapter,
|
||||||
file = file,
|
file = file,
|
||||||
pageNumber = pageIndex,
|
pageNumber = pageIndex,
|
||||||
ext = MimeTypeMap.getFileExtensionFromUrl(url),
|
ext = MimeTypeMap.getFileExtensionFromUrl(url),
|
||||||
)
|
)
|
||||||
|
if (file.extension == "tmp") {
|
||||||
|
file.deleteAwait()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
send(pageIndex)
|
send(pageIndex)
|
||||||
}
|
}
|
||||||
@@ -256,7 +260,9 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
applicationContext.unregisterReceiver(pausingReceiver)
|
applicationContext.unregisterReceiver(pausingReceiver)
|
||||||
output?.closeQuietly()
|
output?.closeQuietly()
|
||||||
output?.cleanup()
|
output?.cleanup()
|
||||||
File(destination, tempFileName).deleteAwait()
|
destination.listFiles(TempFileFilter())?.forEach {
|
||||||
|
it.deleteAwait()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +324,6 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
private suspend fun downloadFile(
|
private suspend fun downloadFile(
|
||||||
url: String,
|
url: String,
|
||||||
destination: File,
|
destination: File,
|
||||||
tempFileName: String,
|
|
||||||
source: MangaSource,
|
source: MangaSource,
|
||||||
): File {
|
): File {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
@@ -330,7 +335,7 @@ class DownloadWorker @AssistedInject constructor(
|
|||||||
.build()
|
.build()
|
||||||
slowdownDispatcher.delay(source)
|
slowdownDispatcher.delay(source)
|
||||||
val call = okHttp.newCall(request)
|
val call = okHttp.newCall(request)
|
||||||
val file = File(destination, tempFileName)
|
val file = File(destination, UUID.randomUUID().toString() + ".tmp")
|
||||||
try {
|
try {
|
||||||
val response = call.clone().await()
|
val response = call.clone().await()
|
||||||
checkNotNull(response.body).use { body ->
|
checkNotNull(response.body).use { body ->
|
||||||
|
|||||||
@@ -2,13 +2,8 @@ package org.koitharu.kotatsu.local.data
|
|||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileFilter
|
import java.io.FileFilter
|
||||||
import java.io.FilenameFilter
|
|
||||||
|
|
||||||
class TempFileFilter : FilenameFilter, FileFilter {
|
class TempFileFilter : FileFilter {
|
||||||
|
|
||||||
override fun accept(dir: File, name: String): Boolean {
|
|
||||||
return name.endsWith(".tmp", ignoreCase = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun accept(file: File): Boolean {
|
override fun accept(file: File): Boolean {
|
||||||
return file.name.endsWith(".tmp", ignoreCase = true)
|
return file.name.endsWith(".tmp", ignoreCase = true)
|
||||||
|
|||||||
Reference in New Issue
Block a user