Remove some RxJava usage

This commit is contained in:
Jobobby04 2022-10-17 20:04:34 -04:00
parent 2961202d05
commit a4de4cbb9d
2 changed files with 75 additions and 107 deletions

View File

@ -11,25 +11,28 @@ import android.webkit.JsResult
import android.webkit.WebChromeClient import android.webkit.WebChromeClient
import android.webkit.WebView import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.domain.UnsortedPreferences import eu.kanade.domain.UnsortedPreferences
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.EhActivityCaptchaBinding import eu.kanade.tachiyomi.databinding.EhActivityCaptchaBinding
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.lang.withUIContext import eu.kanade.tachiyomi.util.lang.withUIContext
import eu.kanade.tachiyomi.util.system.getSerializableExtraCompat import eu.kanade.tachiyomi.util.system.getSerializableExtraCompat
import eu.kanade.tachiyomi.util.system.setDefaultSettings import eu.kanade.tachiyomi.util.system.setDefaultSettings
import exh.log.xLogD import exh.log.xLogD
import exh.log.xLogE import exh.log.xLogE
import exh.source.DelegatedHttpSource import exh.source.DelegatedHttpSource
import exh.util.melt import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.first
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonObject
@ -39,9 +42,6 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody import okhttp3.MultipartBody
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import rx.Observable
import rx.Single
import rx.schedulers.Schedulers
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.io.Serializable import java.io.Serializable
import java.net.URL import java.net.URL
@ -58,7 +58,7 @@ class BrowserActionActivity : AppCompatActivity() {
private var validateCurrentLoopId: String? = null private var validateCurrentLoopId: String? = null
private var strictValidationStartTime: Long? = null private var strictValidationStartTime: Long? = null
private lateinit var credentialsObservable: Observable<String> private val credentialsFlow = MutableSharedFlow<String>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
private lateinit var binding: EhActivityCaptchaBinding private lateinit var binding: EhActivityCaptchaBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -158,17 +158,20 @@ class BrowserActionActivity : AppCompatActivity() {
binding.webview.webViewClient = if (actionName == null && preferencesHelper.autoSolveCaptcha().get()) { binding.webview.webViewClient = if (actionName == null && preferencesHelper.autoSolveCaptcha().get()) {
// Fetch auto-solve credentials early for speed // Fetch auto-solve credentials early for speed
credentialsObservable = httpClient.newCall( lifecycleScope.launchIO {
Request.Builder() try {
// Rob demo credentials credentialsFlow.emit(
.url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials") httpClient.newCall(
.build(), Request.Builder()
) // Rob demo credentials
.asObservableSuccess() .url("https://speech-to-text-demo.ng.bluemix.net/api/v1/credentials")
.subscribeOn(Schedulers.io()) .build(),
.map { ).await().parseAs<JsonObject>()["token"]!!.jsonPrimitive.content
it.parseAs<JsonObject>()["token"]!!.jsonPrimitive.content )
}.melt() } catch (e: Exception) {
xLogE("Failed to get credentials", e)
}
}
binding.webview.addJavascriptInterface(this@BrowserActionActivity, "exh") binding.webview.addJavascriptInterface(this@BrowserActionActivity, "exh")
AutoSolvingWebViewClient(this, verifyComplete, script, headers) AutoSolvingWebViewClient(this, verifyComplete, script, headers)
@ -250,25 +253,24 @@ class BrowserActionActivity : AppCompatActivity() {
STAGE_DOWNLOAD_AUDIO -> { STAGE_DOWNLOAD_AUDIO -> {
if (result != null) { if (result != null) {
xLogD("Got audio URL: $result") xLogD("Got audio URL: $result")
performRecognize(result) lifecycleScope.launchIO {
.observeOn(Schedulers.io()) try {
.subscribe( val transcript = performRecognize(result)
{ xLogD("Got audio transcript: $transcript")
xLogD("Got audio transcript: $it") binding.webview.post {
binding.webview.post { typeResult(
typeResult( loopId,
loopId, transcript
it!! .replace(TRANSCRIPT_CLEANER_REGEX, "")
.replace(TRANSCRIPT_CLEANER_REGEX, "") .replace(SPACE_DEDUPE_REGEX, " ")
.replace(SPACE_DEDUPE_REGEX, " ") .trim(),
.trim(), )
) }
} } catch (e: Exception) {
}, captchaSolveFail()
{ }
runBlocking { captchaSolveFail() }
}, }
)
} else { } else {
binding.webview.postDelayed( binding.webview.postDelayed(
{ {
@ -289,50 +291,43 @@ class BrowserActionActivity : AppCompatActivity() {
} }
} }
private fun performRecognize(url: String): Single<String> { private suspend fun performRecognize(url: String): String {
return credentialsObservable.flatMap { token -> val token = credentialsFlow.first()
httpClient.newCall( val audioFile = httpClient.newCall(
Request.Builder() Request.Builder()
.url(url) .url(url)
.build(),
).await().body.bytes()
val response = httpClient.newCall(
POST(
"https://stream.watsonplatform.net/speech-to-text/api/v1/recognize".toHttpUrl()
.newBuilder()
.addQueryParameter("watson-token", token)
.build()
.toString(),
body = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("jsonDescription", RECOGNIZE_JSON)
.addFormDataPart(
"audio.mp3",
"audio.mp3",
audioFile.toRequestBody(
"audio/mp3".toMediaTypeOrNull(),
0,
audioFile.size,
),
)
.build(), .build(),
).asObservableSuccess().map { ),
token to it ).await()
} return response.parseAs<JsonObject>()["results"]!!
}.flatMap { (token, response) -> .jsonArray[0]
val audioFile = response.body.bytes() .jsonObject["alternatives"]!!
.jsonArray[0]
httpClient.newCall( .jsonObject["transcript"]!!
POST( .jsonPrimitive
"https://stream.watsonplatform.net/speech-to-text/api/v1/recognize".toHttpUrl() .content
.newBuilder() .trim()
.addQueryParameter("watson-token", token)
.build()
.toString(),
body = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("jsonDescription", RECOGNIZE_JSON)
.addFormDataPart(
"audio.mp3",
"audio.mp3",
audioFile.toRequestBody(
"audio/mp3".toMediaTypeOrNull(),
0,
audioFile.size,
),
)
.build(),
),
).asObservableSuccess()
}.map { response ->
response.parseAs<JsonObject>()["results"]!!
.jsonArray[0]
.jsonObject["alternatives"]!!
.jsonArray[0]
.jsonObject["transcript"]!!
.jsonPrimitive
.content
.trim()
}.toSingle()
} }
private fun doStageCheckbox(loopId: String) { private fun doStageCheckbox(loopId: String) {

View File

@ -1,27 +0,0 @@
package exh.util
import rx.Observable
import rx.Single
import rx.subjects.ReplaySubject
/**
* Transform a cold single to a hot single
*
* Note: Behaves like a ReplaySubject
* All generated items are buffered in memory!
*/
fun <T> Single<T>.melt(): Single<T> {
return toObservable().melt().toSingle()
}
/**
* Transform a cold observable to a hot observable
*
* Note: Behaves like a ReplaySubject
* All generated items are buffered in memory!
*/
fun <T> Observable<T>.melt(): Observable<T> {
val rs = ReplaySubject.create<T>()
subscribe(rs)
return rs
}