Remove some RxJava usage
This commit is contained in:
parent
2961202d05
commit
a4de4cbb9d
@ -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) {
|
||||||
|
@ -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
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user