From 1b441f6aea4977b6f6dc61b77138cbc2d2a0e138 Mon Sep 17 00:00:00 2001 From: tom5079 Date: Sun, 2 Jan 2022 20:32:00 +0900 Subject: [PATCH] Migrate to coroutine --- app/build.gradle | 2 +- app/release/output-metadata.json | 2 +- .../java/xyz/quaver/pupil/hitomi/common.kt | 123 ++++++++---------- .../java/xyz/quaver/pupil/hitomi/galleries.kt | 2 +- .../xyz/quaver/pupil/hitomi/galleryblock.kt | 4 +- .../quaver/pupil/services/DownloadService.kt | 7 +- .../main/java/xyz/quaver/pupil/util/misc.kt | 19 ++- 7 files changed, 72 insertions(+), 87 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8ca49503..a803aa43 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -38,7 +38,7 @@ android { minSdkVersion 16 targetSdkVersion 30 versionCode 69 - versionName "5.1.32" + versionName "5.1.33" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true } diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index d2e45aa1..3157dfda 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,7 +11,7 @@ "type": "SINGLE", "filters": [], "versionCode": 69, - "versionName": "5.1.32", + "versionName": "5.1.33", "outputFile": "app-release.apk" } ] diff --git a/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt b/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt index 17d3cc01..69e3adf5 100644 --- a/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt +++ b/app/src/main/java/xyz/quaver/pupil/hitomi/common.kt @@ -45,68 +45,57 @@ const val galleryblockdir = "galleryblock" const val nozomiextension = ".nozomi" @SuppressLint("SetJavaScriptEnabled") -interface gg { - fun m(g: Int): Int - val b: String - fun s(h: String): String +object gg { + suspend fun m(g: Int): Int = coroutineScope { + var result: Int? = null - companion object { - @Volatile private var instance: gg? = null + launch(Dispatchers.Main) { + while (webView.progress != 100) yield() - fun getInstance(): gg = - instance ?: synchronized(this) { - instance ?: object: gg { - override fun m(g: Int): Int { - var result: Int? = null - - MainScope().launch { - while (webView.progress != 100) delay(100) - webView.evaluateJavascript("gg.m($g)") { - result = it.toInt() - } - } - - while (result == null) Thread.sleep(100) - - return result!! - } - - override val b: String - get() { - var result: String? = null - - MainScope().launch { - while (webView.progress != 100) delay(100) - webView.evaluateJavascript("gg.b") { - result = it.replace("\"", "") - } - } - - while (result == null) Thread.sleep(100) - - return result!! - } - - override fun s(h: String): String { - var result: String? = null - - MainScope().launch { - while (webView.progress != 100) delay(100) - webView.evaluateJavascript("gg.s('$h')") { - result = it.replace("\"", "") - } - } - - while (result == null) Thread.sleep(100) - - return result!! - } - }.also { instance = it } + webView.evaluateJavascript("gg.m($g)") { + result = it.toInt() } + } + + while (result == null) yield() + + result!! + } + + suspend fun b(): String = coroutineScope { + var result: String? = null + + launch(Dispatchers.Main) { + while (webView.progress != 100) yield() + + webView.evaluateJavascript("gg.b") { + result = it.replace("\"", "") + } + } + + while (result == null) yield() + + result!! + } + + suspend fun s(h: String): String = coroutineScope { + var result: String? = null + + launch(Dispatchers.Main) { + while (webView.progress != 100) yield() + + webView.evaluateJavascript("gg.s('$h')") { + result = it.replace("\"", "") + } + } + + while (result == null) yield() + + result!! } } -fun subdomainFromURL(url: String, base: String? = null) : String { +suspend fun subdomainFromURL(url: String, base: String? = null) : String { var retval = "b" if (!base.isNullOrBlank()) @@ -120,41 +109,41 @@ fun subdomainFromURL(url: String, base: String? = null) : String { val g = m.groupValues.let { it[2]+it[1] }.toIntOrNull(b) if (g != null) { - retval = (97+ gg.getInstance().m(g)).toChar().toString() + retval + retval = (97+ gg.m(g)).toChar().toString() + retval } return retval } -fun urlFromUrl(url: String, base: String? = null) : String { +suspend fun urlFromUrl(url: String, base: String? = null) : String { return url.replace(Regex("""//..?\.hitomi\.la/"""), "//${subdomainFromURL(url, base)}.hitomi.la/") } -fun fullPathFromHash(hash: String) : String = - "${gg.getInstance().b}${gg.getInstance().s(hash)}/$hash" +suspend fun fullPathFromHash(hash: String) : String = + "${gg.b()}${gg.s(hash)}/$hash" fun realFullPathFromHash(hash: String): String = hash.replace(Regex("""^.*(..)(.)$"""), "$2/$1/$hash") -fun urlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null) : String { +suspend fun urlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null) : String { val ext = ext ?: dir ?: image.name.takeLastWhile { it != '.' } val dir = dir ?: "images" return "https://a.hitomi.la/$dir/${fullPathFromHash(image.hash)}.$ext" } -fun urlFromUrlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null, base: String? = null) = +suspend fun urlFromUrlFromHash(galleryID: Int, image: GalleryFiles, dir: String? = null, ext: String? = null, base: String? = null) = if (base == "tn") urlFromUrl("https://a.hitomi.la/$dir/${realFullPathFromHash(image.hash)}.$ext", base) else urlFromUrl(urlFromHash(galleryID, image, dir, ext), base) -fun rewriteTnPaths(html: String) = - html.replace(Regex("""//tn\.hitomi\.la/[^/]+/[0-9a-f]/[0-9a-f]{2}/[0-9a-f]{64}""")) { url -> - urlFromUrl(url.value, "tn") - } +suspend fun rewriteTnPaths(html: String) = + Regex("""//tn\.hitomi\.la/[^/]+/[0-9a-f]/[0-9a-f]{2}/[0-9a-f]{64}""").find(html)?.let { m -> + html.replaceRange(m.range, urlFromUrl(m.value, "tn")) + } ?: html -fun imageUrlFromImage(galleryID: Int, image: GalleryFiles, noWebp: Boolean) : String { +suspend fun imageUrlFromImage(galleryID: Int, image: GalleryFiles, noWebp: Boolean) : String { return when { noWebp -> urlFromUrlFromHash(galleryID, image) diff --git a/app/src/main/java/xyz/quaver/pupil/hitomi/galleries.kt b/app/src/main/java/xyz/quaver/pupil/hitomi/galleries.kt index 2fad3212..20feaa72 100644 --- a/app/src/main/java/xyz/quaver/pupil/hitomi/galleries.kt +++ b/app/src/main/java/xyz/quaver/pupil/hitomi/galleries.kt @@ -37,7 +37,7 @@ data class Gallery( val tags: List, val thumbnails: List ) -fun getGallery(galleryID: Int) : Gallery { +suspend fun getGallery(galleryID: Int) : Gallery { val url = Jsoup.parse(URL("https://hitomi.la/galleries/$galleryID.html").readText()) .select("link").attr("href") diff --git a/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt b/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt index 4d7f87f5..f9596947 100644 --- a/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt +++ b/app/src/main/java/xyz/quaver/pupil/hitomi/galleryblock.kt @@ -75,7 +75,7 @@ data class GalleryBlock( val relatedTags: List ) -fun getGalleryBlock(galleryID: Int) : GalleryBlock { +suspend fun getGalleryBlock(galleryID: Int) : GalleryBlock { val url = "$protocol//$domain/$galleryblockdir/$galleryID$extension" val doc = Jsoup.parse(rewriteTnPaths(URL(url).readText())) @@ -102,4 +102,4 @@ fun getGalleryBlock(galleryID: Int) : GalleryBlock { return GalleryBlock(galleryID, galleryUrl, thumbnails, title, artists, series, type, language, relatedTags) } -fun getGalleryBlockOrNull(galleryID: Int) = runCatching { getGalleryBlock(galleryID) }.getOrNull() \ No newline at end of file +suspend fun getGalleryBlockOrNull(galleryID: Int) = runCatching { getGalleryBlock(galleryID) }.getOrNull() \ No newline at end of file diff --git a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt index af5b1bb0..30891bce 100644 --- a/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt +++ b/app/src/main/java/xyz/quaver/pupil/services/DownloadService.kt @@ -41,12 +41,9 @@ import okhttp3.ResponseBody import okio.* import xyz.quaver.pupil.* import xyz.quaver.pupil.ui.ReaderActivity -import xyz.quaver.pupil.util.cleanCache +import xyz.quaver.pupil.util.* import xyz.quaver.pupil.util.downloader.Cache import xyz.quaver.pupil.util.downloader.DownloadManager -import xyz.quaver.pupil.util.ellipsize -import xyz.quaver.pupil.util.normalizeID -import xyz.quaver.pupil.util.requestBuilders import java.io.IOException import java.util.concurrent.ConcurrentHashMap import kotlin.math.ceil @@ -357,7 +354,7 @@ class DownloadService : Service() { } } - galleryInfo.requestBuilders.forEachIndexed { index, it -> + galleryInfo.getRequestBuilders().forEachIndexed { index, it -> if (progress[galleryID]?.get(index)?.isInfinite() == false) { val request = it.tag(Tag(galleryID, index, startId)).build() client.newCall(request).enqueue(callback) diff --git a/app/src/main/java/xyz/quaver/pupil/util/misc.kt b/app/src/main/java/xyz/quaver/pupil/util/misc.kt index ce9fc58a..503c12df 100644 --- a/app/src/main/java/xyz/quaver/pupil/util/misc.kt +++ b/app/src/main/java/xyz/quaver/pupil/util/misc.kt @@ -97,18 +97,17 @@ fun GalleryBlock.formatDownloadFolderTest(format: String): String = } }.replace(Regex("""[*\\|"?><:/]"""), "").ellipsize(127) -val GalleryInfo.requestBuilders: List - get() { - val galleryID = this.id ?: 0 - val lowQuality = Preferences["low_quality", true] +suspend fun GalleryInfo.getRequestBuilders(): List { + val galleryID = this.id ?: 0 + val lowQuality = Preferences["low_quality", true] - return this.files.map { - Request.Builder() - .url(imageUrlFromImage(galleryID, it, !lowQuality)) - .header("Referer", "https://hitomi.la/") - .header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36") - } + return this.files.map { + Request.Builder() + .url(imageUrlFromImage(galleryID, it, !lowQuality)) + .header("Referer", "https://hitomi.la/") + .header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36") } +} fun String.ellipsize(n: Int): String = if (this.length > n)