This commit is contained in:
Horis
2025-04-13 15:31:03 +08:00
parent e4b38aea56
commit 87d51adc4a
4 changed files with 49 additions and 52 deletions
@@ -1,6 +1,5 @@
package io.legado.app.help package io.legado.app.help
import android.net.Uri
import android.webkit.WebSettings import android.webkit.WebSettings
import androidx.annotation.Keep import androidx.annotation.Keep
import cn.hutool.core.codec.Base64 import cn.hutool.core.codec.Base64
@@ -39,12 +38,8 @@ import io.legado.app.utils.createFileReplace
import io.legado.app.utils.externalCache import io.legado.app.utils.externalCache
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.isUri
import io.legado.app.utils.longToastOnUi import io.legado.app.utils.longToastOnUi
import io.legado.app.utils.mapAsync import io.legado.app.utils.mapAsync
import io.legado.app.utils.readBytes
import io.legado.app.utils.readText
import io.legado.app.utils.stackTraceStr import io.legado.app.utils.stackTraceStr
import io.legado.app.utils.startActivity import io.legado.app.utils.startActivity
import io.legado.app.utils.toStringArray import io.legado.app.utils.toStringArray
@@ -104,14 +99,12 @@ interface JsExtensions : JsEncodeUtils {
url.toString() url.toString()
} }
val analyzeUrl = AnalyzeUrl(urlStr, source = getSource(), coroutineContext = context) val analyzeUrl = AnalyzeUrl(urlStr, source = getSource(), coroutineContext = context)
return runBlocking(context) { return kotlin.runCatching {
kotlin.runCatching { analyzeUrl.getStrResponse().body
analyzeUrl.getStrResponseAwait().body }.onFailure {
}.onFailure { AppLog.put("ajax(${urlStr}) error\n${it.localizedMessage}", it)
AppLog.put("ajax(${urlStr}) error\n${it.localizedMessage}", it) }.getOrElse {
}.getOrElse { it.stackTraceStr
it.stackTraceStr
}
} }
} }
@@ -121,7 +114,11 @@ interface JsExtensions : JsEncodeUtils {
fun ajaxAll(urlList: Array<String>): Array<StrResponse> { fun ajaxAll(urlList: Array<String>): Array<StrResponse> {
return runBlocking(context) { return runBlocking(context) {
urlList.asFlow().mapAsync(AppConfig.threadCount) { url -> urlList.asFlow().mapAsync(AppConfig.threadCount) { url ->
val analyzeUrl = AnalyzeUrl(url, source = getSource()) val analyzeUrl = AnalyzeUrl(
url,
source = getSource(),
coroutineContext = coroutineContext
)
analyzeUrl.getStrResponseAwait() analyzeUrl.getStrResponseAwait()
}.flowOn(IO).toList().toTypedArray() }.flowOn(IO).toList().toTypedArray()
} }
@@ -131,29 +128,34 @@ interface JsExtensions : JsEncodeUtils {
* 访问网络,返回Response<String> * 访问网络,返回Response<String>
*/ */
fun connect(urlStr: String): StrResponse { fun connect(urlStr: String): StrResponse {
return runBlocking(context) { val analyzeUrl = AnalyzeUrl(
val analyzeUrl = AnalyzeUrl(urlStr, source = getSource()) urlStr,
kotlin.runCatching { source = getSource(),
analyzeUrl.getStrResponseAwait() coroutineContext = context
}.onFailure { )
AppLog.put("connect(${urlStr}) error\n${it.localizedMessage}", it) return kotlin.runCatching {
}.getOrElse { analyzeUrl.getStrResponse()
StrResponse(analyzeUrl.url, it.stackTraceStr) }.onFailure {
} AppLog.put("connect(${urlStr}) error\n${it.localizedMessage}", it)
}.getOrElse {
StrResponse(analyzeUrl.url, it.stackTraceStr)
} }
} }
fun connect(urlStr: String, header: String?): StrResponse { fun connect(urlStr: String, header: String?): StrResponse {
return runBlocking(context) { val headerMap = GSON.fromJsonObject<Map<String, String>>(header).getOrNull()
val headerMap = GSON.fromJsonObject<Map<String, String>>(header).getOrNull() val analyzeUrl = AnalyzeUrl(
val analyzeUrl = AnalyzeUrl(urlStr, headerMapF = headerMap, source = getSource()) urlStr,
kotlin.runCatching { headerMapF = headerMap,
analyzeUrl.getStrResponseAwait() source = getSource(),
}.onFailure { coroutineContext = context
AppLog.put("ajax($urlStr,$header) error\n${it.localizedMessage}", it) )
}.getOrElse { return kotlin.runCatching {
StrResponse(analyzeUrl.url, it.stackTraceStr) analyzeUrl.getStrResponse()
} }.onFailure {
AppLog.put("ajax($urlStr,$header) error\n${it.localizedMessage}", it)
}.getOrElse {
StrResponse(analyzeUrl.url, it.stackTraceStr)
} }
} }
@@ -247,13 +249,11 @@ interface JsExtensions : JsEncodeUtils {
} }
/** /**
* 可从网络,本地文件(阅读私有缓存目录和书籍保存位置支持相对路径)导入JavaScript脚本 * 可从网络,本地文件(阅读私有数据目录相对路径)导入JavaScript脚本
*/ */
fun importScript(path: String): String { fun importScript(path: String): String {
val result = when { val result = when {
path.startsWith("http") -> cacheFile(path) path.startsWith("http") -> cacheFile(path)
path.isUri() -> Uri.parse(path).readText(appCtx)
path.startsWith("/storage") -> FileUtils.readText(path)
else -> readTxtFile(path) else -> readTxtFile(path)
} }
if (result.isBlank()) throw NoStackTraceException("$path 内容获取失败或者为空") if (result.isBlank()) throw NoStackTraceException("$path 内容获取失败或者为空")
@@ -561,7 +561,8 @@ interface JsExtensions : JsEncodeUtils {
cachePath + File.separator + path cachePath + File.separator + path
} }
val file = File(aPath) val file = File(aPath)
if (!file.canonicalPath.startsWith(cachePath)) { val safePath = appCtx.externalCache.parent!!
if (!file.canonicalPath.startsWith(safePath)) {
throw SecurityException("非法路径") throw SecurityException("非法路径")
} }
return file return file
@@ -812,8 +813,6 @@ interface JsExtensions : JsEncodeUtils {
if (qTTF != null) return qTTF if (qTTF != null) return qTTF
} }
val font: ByteArray? = when { val font: ByteArray? = when {
data.isContentScheme() -> Uri.parse(data).readBytes(appCtx)
data.startsWith("/storage") -> File(data).readBytes()
data.isAbsUrl() -> AnalyzeUrl( data.isAbsUrl() -> AnalyzeUrl(
data, data,
source = getSource(), source = getSource(),
@@ -791,15 +791,13 @@ class AnalyzeRule(
ruleData = book, ruleData = book,
coroutineContext = coroutineContext coroutineContext = coroutineContext
) )
return runBlocking(coroutineContext) { return kotlin.runCatching {
kotlin.runCatching { analyzeUrl.getStrResponse().body
analyzeUrl.getStrResponseAwait().body }.onFailure {
}.onFailure { log("ajax(${urlStr}) error\n${it.stackTraceToString()}")
log("ajax(${urlStr}) error\n${it.stackTraceToString()}") it.printOnDebug()
it.printOnDebug() }.getOrElse {
}.getOrElse { it.stackTraceStr
it.stackTraceStr
}
} }
} }
@@ -1,7 +1,6 @@
package io.legado.app.ui.book.audio package io.legado.app.ui.book.audio
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.icu.text.SimpleDateFormat import android.icu.text.SimpleDateFormat
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@@ -240,7 +239,7 @@ class AudioPlayActivity :
AudioPlay.book?.removeType(BookType.notShelf) AudioPlay.book?.removeType(BookType.notShelf)
AudioPlay.book?.save() AudioPlay.book?.save()
AudioPlay.inBookshelf = true AudioPlay.inBookshelf = true
setResult(Activity.RESULT_OK) setResult(RESULT_OK)
} }
noButton { viewModel.removeFromBookshelf { super.finish() } } noButton { viewModel.removeFromBookshelf { super.finish() } }
} }
@@ -289,7 +288,7 @@ class AudioPlayActivity :
} }
observeEventSticky<Float>(EventBus.AUDIO_SPEED) { observeEventSticky<Float>(EventBus.AUDIO_SPEED) {
binding.tvSpeed.text = String.format("%.1fX", it) binding.tvSpeed.text = String.format(Locale.ROOT, "%.1fX", it)
binding.tvSpeed.visible() binding.tvSpeed.visible()
} }
observeEventSticky<Int>(EventBus.AUDIO_DS) { observeEventSticky<Int>(EventBus.AUDIO_DS) {
@@ -31,6 +31,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onEmpty import kotlinx.coroutines.flow.onEmpty
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.take import kotlinx.coroutines.flow.take
import splitties.init.appCtx
class ReadMangaViewModel(application: Application) : BaseViewModel(application) { class ReadMangaViewModel(application: Application) : BaseViewModel(application) {
@@ -111,7 +112,7 @@ class ReadMangaViewModel(application: Application) : BaseViewModel(application)
return true return true
}.onFailure { }.onFailure {
//加载章节出错 //加载章节出错
ReadManga.mCallback?.loadFail("加载目录失败") ReadManga.mCallback?.loadFail(appCtx.getString(R.string.error_load_toc))
return false return false
} }
} }