Drop Ktor

This commit is contained in:
tarsin committed 2023-05-07 23:00:54 +08:00
1 parent 65d5377683
commit 25931f9068
10 files changed
+32 -73

No files matched your search

@@ -43,8 +43,6 @@ import com.hippo.yorozuya.FileUtils
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
import eu.kanade.tachiyomi.ui.reader.setting.ReaderPreferences
import eu.kanade.tachiyomi.util.lang.launchIO
import io.ktor.client.HttpClient
import io.ktor.client.engine.okhttp.OkHttp
import kotlinx.coroutines.DelicateCoroutinesApi
import okhttp3.Cache
import okhttp3.OkHttpClient
@@ -184,14 +182,6 @@ class EhApplication : Application(), DefaultLifecycleObserver, ImageLoaderFactor
).build()
}
val ktorClient by lazy {
HttpClient(OkHttp) {
engine {
preconfigured = nonCacheOkHttpClient
}
}
}
val galleryDetailCache by lazy {
LruCache<Long, GalleryDetail>(25).also {
favouriteStatusRouter.addListener { gid, slot ->
@@ -19,8 +19,6 @@ import com.hippo.ehviewer.EhApplication
import com.hippo.network.CookieDatabase
import com.hippo.network.CookieSet
import eu.kanade.tachiyomi.util.lang.launchIO
import io.ktor.client.plugins.cookies.CookiesStorage
import io.ktor.http.Url
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.HttpUrl
@@ -28,9 +26,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrl
import java.util.Collections
import java.util.regex.Pattern
typealias KtorCookie = io.ktor.http.Cookie
object EhCookieStore : CookieJar, CookiesStorage {
object EhCookieStore : CookieJar {
private val db: CookieDatabase = CookieDatabase(EhApplication.application, "okhttp3-cookie.db")
private val map: MutableMap<String, CookieSet> = db.allCookies
@@ -205,21 +201,6 @@ object EhCookieStore : CookieJar, CookiesStorage {
}
}
override suspend fun addCookie(requestUrl: Url, cookie: io.ktor.http.Cookie) {}
// This should never be closed
override fun close() {}
private val okhttpCookieToKtorCookieMap = hashMapOf<Cookie, KtorCookie>()
override suspend fun get(requestUrl: Url): List<io.ktor.http.Cookie> {
return loadForRequest(requestUrl.toString().toHttpUrl()).map {
okhttpCookieToKtorCookieMap[it] ?: KtorCookie(
it.name,
it.value,
).apply { okhttpCookieToKtorCookieMap[it] = this }
}
}
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
for (cookie in cookies) {
// See https://github.com/Ehviewer-Overhauled/Ehviewer/issues/873
@@ -15,7 +15,6 @@
*/
package com.hippo.ehviewer.client
import io.ktor.http.HttpMessageBuilder
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
@@ -45,8 +44,6 @@ fun jsonArrayOf(vararg element: Any?) = JSONArray().apply { element.forEach { pu
inline fun Request.Builder.jsonBody(builder: JSONObject.() -> Unit) = post(JSONObject().apply(builder).toString().toRequestBody(MEDIA_TYPE_JSON))
fun HttpMessageBuilder.referer(value: String?): Unit = value?.let { headers.append("Referer", it) } ?: Unit
const val CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"
const val CHROME_ACCEPT = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
const val CHROME_ACCEPT_LANGUAGE = "en-US,en;q=0.5"
@@ -18,13 +18,13 @@ package com.hippo.ehviewer.spider
import android.graphics.ImageDecoder
import android.os.ParcelFileDescriptor
import android.os.ParcelFileDescriptor.MODE_READ_WRITE
import com.hippo.ehviewer.EhApplication
import com.hippo.ehviewer.EhApplication.Companion.nonCacheOkHttpClient
import com.hippo.ehviewer.EhDB
import com.hippo.ehviewer.Settings
import com.hippo.ehviewer.client.EhUtils.getSuitableTitle
import com.hippo.ehviewer.client.data.GalleryInfo
import com.hippo.ehviewer.client.ehRequest
import com.hippo.ehviewer.client.getImageKey
import com.hippo.ehviewer.client.referer
import com.hippo.ehviewer.coil.edit
import com.hippo.ehviewer.coil.read
import com.hippo.ehviewer.gallery.SUPPORT_IMAGE_EXTENSIONS
@@ -34,22 +34,18 @@ import com.hippo.unifile.UniFile
import com.hippo.unifile.openOutputStream
import com.hippo.util.sendTo
import com.hippo.yorozuya.FileUtils
import io.ktor.client.plugins.onDownload
import io.ktor.client.request.prepareGet
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsChannel
import io.ktor.http.ContentType
import io.ktor.http.contentLength
import io.ktor.http.contentType
import io.ktor.utils.io.jvm.nio.copyTo
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.ensureActive
import moe.tarsin.coroutines.runSuspendCatching
import okhttp3.Response
import okhttp3.executeAsync
import okio.buffer
import okio.sink
import java.io.IOException
import java.util.Locale
import kotlin.io.path.readText
import com.hippo.ehviewer.EhApplication.Companion.imageCache as sCache
private val client = EhApplication.ktorClient
class SpiderDen(private val mGalleryInfo: GalleryInfo) {
private val mGid = mGalleryInfo.gid
var downloadDir: UniFile? = getGalleryDownloadDir(mGid)?.takeIf { it.isDirectory }
@@ -138,30 +134,34 @@ class SpiderDen(private val mGalleryInfo: GalleryInfo) {
referer: String?,
notifyProgress: (Long, Long, Int) -> Unit,
): Boolean {
return client.prepareGet(url) {
var state: Long = 0
referer(referer)
onDownload { bytesSentTotal, contentLength ->
notifyProgress(contentLength, bytesSentTotal, (bytesSentTotal - state).toInt())
state = bytesSentTotal
}
}.execute {
if (it.status.value >= 400) return@execute false
saveFromHttpResponse(index, it)
// TODO: Use HttpEngine[https://developer.android.com/reference/android/net/http/HttpEngine] directly here if available
// Since we don't want unnecessary copy between jvm heap & native heap
nonCacheOkHttpClient.newCall(ehRequest(url, referer)).executeAsync().use {
if (it.code >= 400) return false
return saveFromHttpResponse(index, it, notifyProgress)
}
}
private suspend fun saveFromHttpResponse(index: Int, body: HttpResponse): Boolean {
val contentType = body.contentType()
val extension = contentType?.contentSubtype ?: "jpg"
val length = body.contentLength() ?: return false
private suspend fun saveFromHttpResponse(index: Int, response: Response, notifyProgress: (Long, Long, Int) -> Unit): Boolean {
val contentType = response.body.contentType()
val extension = contentType?.subtype ?: "jpg"
val length = response.body.contentLength()
suspend fun doSave(outFile: UniFile): Long {
val ret: Long
outFile.openOutputStream().use {
ret = body.bodyAsChannel().copyTo(it.channel)
var ret: Long = 1
outFile.openOutputStream().sink().buffer().use { sink ->
response.body.source().use { source ->
while (true) {
currentCoroutineContext().ensureActive()
val bytesRead = source.read(sink.buffer, 8192)
sink.emitCompleteSegments()
ret += bytesRead
notifyProgress(length, ret, bytesRead.toInt())
if (bytesRead.toInt() < 0) break
}
}
}
if (contentType == ContentType.Image.GIF) {
if (extension.lowercase() == "gif") {
outFile.openFileDescriptor("rw").use {
rewriteGifSource2(it.fd)
}