From e94a01bc691662e4dc26a2bce7678ab9ceed25f3 Mon Sep 17 00:00:00 2001 From: Xwite <1797350009@qq.com> Date: Wed, 4 May 2022 18:50:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=94=AF=E6=8C=81=E6=9B=B4=E5=A4=9A?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/help/jsHelp.md | 3 + app/src/main/assets/updateLog.md | 2 +- .../java/io/legado/app/help/JsExtensions.kt | 45 ++++-------- .../legado/app/help/SourceVerificationHelp.kt | 69 +++++++++++++++++++ .../ui/association/VerificationCodeDialog.kt | 15 ++-- .../legado/app/ui/browser/WebViewActivity.kt | 5 +- .../io/legado/app/ui/browser/WebViewModel.kt | 12 ++++ 7 files changed, 109 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt diff --git a/app/src/main/assets/help/jsHelp.md b/app/src/main/assets/help/jsHelp.md index 2bbf5018e..420f45ebe 100644 --- a/app/src/main/assets/help/jsHelp.md +++ b/app/src/main/assets/help/jsHelp.md @@ -67,6 +67,9 @@ java.webView(html: String?, url: String?, js: String?): String * @param url 要打开的链接 * @param title 浏览器的标题 java.startBrowser(url: String, title: String) + +* 使用内置浏览器打开链接,并等待网页结果 .body()获取网页内容 +java.startBrowserAwait(url: String, title: String): StrResponse ``` * 调试 ``` diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 6e365bba3..9bd798800 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -13,7 +13,7 @@ **2022/05/04** -* js添加 getVerificationCode +* js添加 getVerificationCode startBrowserAwait **2022/05/02** diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index b931790ba..e63dc6528 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -15,13 +15,10 @@ import io.legado.app.help.http.* import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.QueryTTF -import io.legado.app.ui.association.VerificationCodeActivity -import io.legado.app.ui.browser.WebViewActivity import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.async import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withContext import org.jsoup.Connection import org.jsoup.Jsoup import splitties.init.appCtx @@ -135,46 +132,28 @@ interface JsExtensions { } /** - * 使用内置浏览器打开链接,可用于获取验证码 手动验证网站防爬 + * 使用内置浏览器打开链接,手动验证网站防爬 * @param url 要打开的链接 * @param title 浏览器页面的标题 */ fun startBrowser(url: String, title: String) { - appCtx.startActivity { - putExtra("title", title) - putExtra("url", url) - IntentData.put(url, getSource()?.getHeaderMap(true)) - } + SourceVerificationHelp.startBrowser(getSource(), url, title) } /** - * 打开验证码对话框,等待输入验证码 + * 使用内置浏览器打开链接,并等待网页结果 */ - fun getVerificationCode(imageUrl: String): String { - return runBlocking { - val key = "${getSource()?.getKey() ?: ""}_verificationCode" - CacheManager.delete(key) - appCtx.startActivity { - putExtra("imageUrl", imageUrl) - putExtra("sourceOrigin", getSource()?.getKey()) - } - var waitUserInput: Boolean = false - while(CacheManager.get(key) == null) { - if (!waitUserInput) { - log("等待输入验证码...") - waitUserInput = true - } - } - CacheManager.get(key)!!.let { - if (it.isBlank()) { - throw NoStackTraceException("未输入验证码或者验证码为空") - } else { - it - } - } - } + fun startBrowserAwait(url: String, title: String): StrResponse { + return StrResponse(url, SourceVerificationHelp.getVerificationResult(getSource(), url, title, true)) } + /** + * 打开图片验证码对话框,等待返回验证结果 + */ + fun getVerificationCode(imageUrl: String): String { + return SourceVerificationHelp.getVerificationResult(getSource(), imageUrl, "", false) + } + /** * 可从网络,本地文件(阅读私有缓存目录和书籍保存位置支持相对路径)导入JavaScript脚本 */ diff --git a/app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt b/app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt new file mode 100644 index 000000000..3f3a302dc --- /dev/null +++ b/app/src/main/java/io/legado/app/help/SourceVerificationHelp.kt @@ -0,0 +1,69 @@ +package io.legado.app.help + +import io.legado.app.utils.startActivity +import io.legado.app.constant.AppLog +import io.legado.app.exception.NoStackTraceException +import io.legado.app.data.entities.BaseSource +import io.legado.app.ui.browser.WebViewActivity +import io.legado.app.ui.association.VerificationCodeActivity +import splitties.init.appCtx +import kotlinx.coroutines.runBlocking + + +object SourceVerificationHelp { + + /** + * 获取书源验证结果 + * 图片验证码 防爬 滑动验证码 点击字符 等等 + */ + fun getVerificationResult(source: BaseSource?, url: String, title: String, useBrowser: Boolean): String { + source ?: throw NoStackTraceException("getVerificationResult parameter source cannot be null") + return runBlocking { + val key = "${source?.getKey() ?: ""}_verificationResult" + CacheManager.delete(key) + + if (!useBrowser) { + appCtx.startActivity { + putExtra("imageUrl", url) + putExtra("sourceOrigin", source?.getKey()) + } + } else { + startBrowser(source, url, title, true) + } + + var waitUserInput: Boolean = false + while(CacheManager.get(key) == null) { + if (!waitUserInput) { + AppLog.putDebug("等待返回验证结果...") + waitUserInput = true + } + } + CacheManager.get(key)!!.let { + if (it.isBlank()) { + throw NoStackTraceException("验证结果为空") + } else { + it + } + } + } + } + + /** + * 启动内置浏览器 + @param saveResult 保存网页源代码到数据库 + */ + fun startBrowser(source: BaseSource?, url: String, title: String, saveResult: Boolean? = false) { + source ?: throw NoStackTraceException("startBrowser parameter source cannot be null") + appCtx.startActivity { + putExtra("title", title) + putExtra("url", url) + putExtra("sourceOrigin", source?.getKey()) + putExtra("sourceVerificationEnable", saveResult) + IntentData.put(url, source?.getHeaderMap(true)) + } + } + + private fun checkActivityStatus(): Boolean { + return true + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt b/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt index 568800b29..0e8265f7a 100644 --- a/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt +++ b/app/src/main/java/io/legado/app/ui/association/VerificationCodeDialog.kt @@ -17,7 +17,12 @@ import io.legado.app.utils.setLayout import io.legado.app.utils.showDialogFragment import io.legado.app.utils.viewbindingdelegate.viewBinding -//图片验证码输入对话框 +/** + * 图片验证码对话框 + * 结果保存在数据库中 + * val key = "${sourceOrigin ?: ""}_verificationResult" + * CacheManager.get(key) + */ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification_code_view) { constructor(imageUrl: String, sourceOrigin: String? = null) : this() { @@ -38,7 +43,7 @@ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification binding.run { toolBar.setBackgroundColor(primaryColor) val sourceOrigin = arguments?.getString("sourceOrigin") - val key = "${sourceOrigin ?: ""}_verificationCode" + val key = "${sourceOrigin ?: ""}_verificationResult" arguments?.getString("imageUrl")?.let { imageUrl -> ImageLoader.load(requireContext(), imageUrl).apply { sourceOrigin?.let { @@ -54,10 +59,6 @@ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification ivImage.setOnClickListener { showDialogFragment(PhotoDialog(imageUrl, sourceOrigin)) } - ivImage.setOnLongClickListener { - showDialogFragment(PhotoDialog(imageUrl, sourceOrigin)) - true - } } tvOk.setOnClickListener { val verificationCode = binding.verificationCode.text.toString() @@ -74,7 +75,7 @@ class VerificationCodeDialog() : BaseDialogFragment(R.layout.dialog_verification override fun onDestroy() { val sourceOrigin = arguments?.getString("sourceOrigin") - val key = "${sourceOrigin ?: ""}_verificationCode" + val key = "${sourceOrigin ?: ""}_verificationResult" CacheManager.get(key) ?: CacheManager.put(key, "") super.onDestroy() activity?.finish() diff --git a/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt b/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt index e4532d566..71485b027 100644 --- a/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt +++ b/app/src/main/java/io/legado/app/ui/browser/WebViewActivity.kt @@ -26,6 +26,7 @@ import io.legado.app.ui.document.HandleFileContract import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding import java.net.URLDecoder +import kotlinx.coroutines.runBlocking class WebViewActivity : VMBaseActivity() { @@ -135,7 +136,6 @@ class WebViewActivity : VMBaseActivity() { viewModel.saveImage(webPic, path) } } - private fun selectSaveFolder() { val default = arrayListOf>() val path = ACache.get(this).getAsString(imagePathKey) @@ -176,6 +176,9 @@ class WebViewActivity : VMBaseActivity() { override fun onDestroy() { super.onDestroy() + runBlocking { + viewModel.saveVerificationResult() + } binding.webView.destroy() } diff --git a/app/src/main/java/io/legado/app/ui/browser/WebViewModel.kt b/app/src/main/java/io/legado/app/ui/browser/WebViewModel.kt index 16c813ef4..79f6e21ad 100644 --- a/app/src/main/java/io/legado/app/ui/browser/WebViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/browser/WebViewModel.kt @@ -9,6 +9,7 @@ import androidx.documentfile.provider.DocumentFile import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppConst import io.legado.app.exception.NoStackTraceException +import io.legado.app.help.CacheManager import io.legado.app.help.IntentData import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient @@ -21,6 +22,8 @@ class WebViewModel(application: Application) : BaseViewModel(application) { var baseUrl: String = "" var html: String? = null val headerMap: HashMap = hashMapOf() + var sourceVerificationEnable: Boolean = false + var sourceOrigin: String = "" fun initData( intent: Intent, @@ -29,6 +32,8 @@ class WebViewModel(application: Application) : BaseViewModel(application) { execute { val url = intent.getStringExtra("url") ?: throw NoStackTraceException("url不能为空") + sourceOrigin = intent.getStringExtra("sourceOrigin") ?: "" + sourceVerificationEnable = intent.getBooleanExtra("sourceVerificationEnable", false) val headerMapF = IntentData.get>(url) val analyzeUrl = AnalyzeUrl(url, headerMapF = headerMapF) baseUrl = analyzeUrl.url @@ -78,5 +83,12 @@ class WebViewModel(application: Application) : BaseViewModel(application) { } } + fun saveVerificationResult() { + if (sourceVerificationEnable) { + val key = "${sourceOrigin}_verificationResult" + html = AnalyzeUrl(baseUrl, headerMapF = headerMap).getStrResponse(useWebView = false).body + CacheManager.put(key, html!!) + } + } } \ No newline at end of file