From ee85ef50f4eee5c141b2a11c4a999c3b58d11db3 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 7 Jul 2024 11:50:08 +0300 Subject: [PATCH] Use image proxy for downloading #897 --- .../ui/pager/pages/MangaPageFetcher.kt | 2 +- .../download/ui/worker/DownloadWorker.kt | 42 +++++++++---------- .../reader/domain/DetectReaderModeUseCase.kt | 2 +- .../kotatsu/reader/domain/PageLoader.kt | 6 +-- 4 files changed, 25 insertions(+), 27 deletions(-) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/MangaPageFetcher.kt b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/MangaPageFetcher.kt index 3bfe70c52..e954b630e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/MangaPageFetcher.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/details/ui/pager/pages/MangaPageFetcher.kt @@ -92,7 +92,7 @@ class MangaPageFetcher( } else -> { - val request = PageLoader.createPageRequest(page, pageUrl) + val request = PageLoader.createPageRequest(pageUrl, page.source) imageProxyInterceptor.interceptPageRequest(request, okHttpClient).use { response -> if (!response.isSuccessful) { throw HttpException(response) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt index fb0fea709..2c1ae89ac 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/worker/DownloadWorker.kt @@ -35,16 +35,16 @@ import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.withContext import okhttp3.OkHttpClient -import okhttp3.Request import okhttp3.internal.closeQuietly import okio.IOException import okio.buffer import okio.sink +import okio.use import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.exceptions.TooManyRequestExceptions import org.koitharu.kotatsu.core.model.ids -import org.koitharu.kotatsu.core.network.CommonHeaders import org.koitharu.kotatsu.core.network.MangaHttpClient +import org.koitharu.kotatsu.core.network.imageproxy.ImageProxyInterceptor import org.koitharu.kotatsu.core.parser.MangaDataRepository import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings @@ -55,6 +55,7 @@ import org.koitharu.kotatsu.core.util.ext.awaitWorkInfosByTag import org.koitharu.kotatsu.core.util.ext.deleteAwait import org.koitharu.kotatsu.core.util.ext.deleteWork import org.koitharu.kotatsu.core.util.ext.deleteWorks +import org.koitharu.kotatsu.core.util.ext.ensureSuccess import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.getWorkInputData import org.koitharu.kotatsu.core.util.ext.getWorkSpec @@ -73,9 +74,9 @@ import org.koitharu.kotatsu.local.domain.model.LocalManga import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.util.await import org.koitharu.kotatsu.parsers.util.mapToSet import org.koitharu.kotatsu.parsers.util.runCatchingCancellable +import org.koitharu.kotatsu.reader.domain.PageLoader import java.io.File import java.util.UUID import java.util.concurrent.TimeUnit @@ -93,6 +94,7 @@ class DownloadWorker @AssistedInject constructor( private val mangaRepositoryFactory: MangaRepository.Factory, private val settings: AppSettings, @LocalStorageChanges private val localStorageChanges: MutableSharedFlow, + private val imageProxyInterceptor: ImageProxyInterceptor, notificationFactoryFactory: DownloadNotificationFactory.Factory, ) : CoroutineWorker(appContext, params) { @@ -327,28 +329,24 @@ class DownloadWorker @AssistedInject constructor( destination: File, source: MangaSource, ): File { - val request = Request.Builder() - .url(url) - .tag(MangaSource::class.java, source) - .header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8") - .cacheControl(CommonHeaders.CACHE_CONTROL_NO_STORE) - .get() - .build() + val request = PageLoader.createPageRequest(url, source) slowdownDispatcher.delay(source) - val call = okHttp.newCall(request) - val file = File(destination, UUID.randomUUID().toString() + ".tmp") - try { - val response = call.clone().await() - checkNotNull(response.body).use { body -> - file.sink(append = false).buffer().use { - it.writeAllCancellable(body.source()) + return imageProxyInterceptor.interceptPageRequest(request, okHttp) + .ensureSuccess() + .use { response -> + val file = File(destination, UUID.randomUUID().toString() + ".tmp") + try { + checkNotNull(response.body).use { body -> + file.sink(append = false).buffer().use { + it.writeAllCancellable(body.source()) + } + } + } catch (e: CancellationException) { + file.delete() + throw e } + file } - } catch (e: CancellationException) { - file.delete() - throw e - } - return file } private suspend fun publishState(state: DownloadState) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/DetectReaderModeUseCase.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/DetectReaderModeUseCase.kt index 1be842980..7f8989ece 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/DetectReaderModeUseCase.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/DetectReaderModeUseCase.kt @@ -71,7 +71,7 @@ class DetectReaderModeUseCase @Inject constructor( } } } else { - val request = PageLoader.createPageRequest(page, url) + val request = PageLoader.createPageRequest(url, page.source) imageProxyInterceptor.interceptPageRequest(request, okHttpClient).use { runInterruptible(Dispatchers.IO) { getBitmapSize(it.body?.byteStream()) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt index 08d1e537b..68d4adb55 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/PageLoader.kt @@ -230,7 +230,7 @@ class PageLoader @Inject constructor( uri.isFileUri() -> uri else -> { - val request = createPageRequest(page, pageUrl) + val request = createPageRequest(pageUrl, page.source) imageProxyInterceptor.interceptPageRequest(request, okHttp).ensureSuccess().use { response -> val body = checkNotNull(response.body) { "Null response body" } body.withProgress(progress).use { @@ -265,12 +265,12 @@ class PageLoader @Inject constructor( private const val PREFETCH_LIMIT_DEFAULT = 6 private const val PREFETCH_MIN_RAM_MB = 80L - fun createPageRequest(page: MangaPage, pageUrl: String) = Request.Builder() + fun createPageRequest(pageUrl: String, mangaSource: MangaSource) = Request.Builder() .url(pageUrl) .get() .header(CommonHeaders.ACCEPT, "image/webp,image/png;q=0.9,image/jpeg,*/*;q=0.8") .cacheControl(CommonHeaders.CACHE_CONTROL_NO_STORE) - .tag(MangaSource::class.java, page.source) + .tag(MangaSource::class.java, mangaSource) .build() } }