Migrate to coroutine

This commit is contained in:
tom5079
2022-01-02 20:32:00 +09:00
parent a17b7355f5
commit 1b441f6aea
7 changed files with 72 additions and 87 deletions

View File

@@ -38,7 +38,7 @@ android {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 30 targetSdkVersion 30
versionCode 69 versionCode 69
versionName "5.1.32" versionName "5.1.33"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
} }

View File

@@ -11,7 +11,7 @@
"type": "SINGLE", "type": "SINGLE",
"filters": [], "filters": [],
"versionCode": 69, "versionCode": 69,
"versionName": "5.1.32", "versionName": "5.1.33",
"outputFile": "app-release.apk" "outputFile": "app-release.apk"
} }
] ]

View File

@@ -45,68 +45,57 @@ const val galleryblockdir = "galleryblock"
const val nozomiextension = ".nozomi" const val nozomiextension = ".nozomi"
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
interface gg { object gg {
fun m(g: Int): Int suspend fun m(g: Int): Int = coroutineScope {
val b: String var result: Int? = null
fun s(h: String): String
companion object { launch(Dispatchers.Main) {
@Volatile private var instance: gg? = null while (webView.progress != 100) yield()
fun getInstance(): gg = webView.evaluateJavascript("gg.m($g)") {
instance ?: synchronized(this) { result = it.toInt()
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 }
} }
}
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" var retval = "b"
if (!base.isNullOrBlank()) 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) val g = m.groupValues.let { it[2]+it[1] }.toIntOrNull(b)
if (g != null) { if (g != null) {
retval = (97+ gg.getInstance().m(g)).toChar().toString() + retval retval = (97+ gg.m(g)).toChar().toString() + retval
} }
return 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/") return url.replace(Regex("""//..?\.hitomi\.la/"""), "//${subdomainFromURL(url, base)}.hitomi.la/")
} }
fun fullPathFromHash(hash: String) : String = suspend fun fullPathFromHash(hash: String) : String =
"${gg.getInstance().b}${gg.getInstance().s(hash)}/$hash" "${gg.b()}${gg.s(hash)}/$hash"
fun realFullPathFromHash(hash: String): String = fun realFullPathFromHash(hash: String): String =
hash.replace(Regex("""^.*(..)(.)$"""), "$2/$1/$hash") 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 ext = ext ?: dir ?: image.name.takeLastWhile { it != '.' }
val dir = dir ?: "images" val dir = dir ?: "images"
return "https://a.hitomi.la/$dir/${fullPathFromHash(image.hash)}.$ext" 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") if (base == "tn")
urlFromUrl("https://a.hitomi.la/$dir/${realFullPathFromHash(image.hash)}.$ext", base) urlFromUrl("https://a.hitomi.la/$dir/${realFullPathFromHash(image.hash)}.$ext", base)
else else
urlFromUrl(urlFromHash(galleryID, image, dir, ext), base) urlFromUrl(urlFromHash(galleryID, image, dir, ext), base)
fun rewriteTnPaths(html: String) = suspend fun rewriteTnPaths(html: String) =
html.replace(Regex("""//tn\.hitomi\.la/[^/]+/[0-9a-f]/[0-9a-f]{2}/[0-9a-f]{64}""")) { url -> Regex("""//tn\.hitomi\.la/[^/]+/[0-9a-f]/[0-9a-f]{2}/[0-9a-f]{64}""").find(html)?.let { m ->
urlFromUrl(url.value, "tn") 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 { return when {
noWebp -> noWebp ->
urlFromUrlFromHash(galleryID, image) urlFromUrlFromHash(galleryID, image)

View File

@@ -37,7 +37,7 @@ data class Gallery(
val tags: List<String>, val tags: List<String>,
val thumbnails: List<String> val thumbnails: List<String>
) )
fun getGallery(galleryID: Int) : Gallery { suspend fun getGallery(galleryID: Int) : Gallery {
val url = Jsoup.parse(URL("https://hitomi.la/galleries/$galleryID.html").readText()) val url = Jsoup.parse(URL("https://hitomi.la/galleries/$galleryID.html").readText())
.select("link").attr("href") .select("link").attr("href")

View File

@@ -75,7 +75,7 @@ data class GalleryBlock(
val relatedTags: List<String> val relatedTags: List<String>
) )
fun getGalleryBlock(galleryID: Int) : GalleryBlock { suspend fun getGalleryBlock(galleryID: Int) : GalleryBlock {
val url = "$protocol//$domain/$galleryblockdir/$galleryID$extension" val url = "$protocol//$domain/$galleryblockdir/$galleryID$extension"
val doc = Jsoup.parse(rewriteTnPaths(URL(url).readText())) 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) return GalleryBlock(galleryID, galleryUrl, thumbnails, title, artists, series, type, language, relatedTags)
} }
fun getGalleryBlockOrNull(galleryID: Int) = runCatching { getGalleryBlock(galleryID) }.getOrNull() suspend fun getGalleryBlockOrNull(galleryID: Int) = runCatching { getGalleryBlock(galleryID) }.getOrNull()

View File

@@ -41,12 +41,9 @@ import okhttp3.ResponseBody
import okio.* import okio.*
import xyz.quaver.pupil.* import xyz.quaver.pupil.*
import xyz.quaver.pupil.ui.ReaderActivity 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.Cache
import xyz.quaver.pupil.util.downloader.DownloadManager 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.io.IOException
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
import kotlin.math.ceil 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) { if (progress[galleryID]?.get(index)?.isInfinite() == false) {
val request = it.tag(Tag(galleryID, index, startId)).build() val request = it.tag(Tag(galleryID, index, startId)).build()
client.newCall(request).enqueue(callback) client.newCall(request).enqueue(callback)

View File

@@ -97,18 +97,17 @@ fun GalleryBlock.formatDownloadFolderTest(format: String): String =
} }
}.replace(Regex("""[*\\|"?><:/]"""), "").ellipsize(127) }.replace(Regex("""[*\\|"?><:/]"""), "").ellipsize(127)
val GalleryInfo.requestBuilders: List<Request.Builder> suspend fun GalleryInfo.getRequestBuilders(): List<Request.Builder> {
get() { val galleryID = this.id ?: 0
val galleryID = this.id ?: 0 val lowQuality = Preferences["low_quality", true]
val lowQuality = Preferences["low_quality", true]
return this.files.map { return this.files.map {
Request.Builder() Request.Builder()
.url(imageUrlFromImage(galleryID, it, !lowQuality)) .url(imageUrlFromImage(galleryID, it, !lowQuality))
.header("Referer", "https://hitomi.la/") .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") .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 = fun String.ellipsize(n: Int): String =
if (this.length > n) if (this.length > n)