Migrate to coroutine
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user