This commit is contained in:
Horis
2024-07-31 19:20:55 +08:00
parent be9320124d
commit 0fea035a05
9 changed files with 95 additions and 60 deletions
@@ -2,6 +2,7 @@ package io.legado.app.data.entities
import cn.hutool.crypto.symmetric.AES import cn.hutool.crypto.symmetric.AES
import com.script.ScriptBindings import com.script.ScriptBindings
import com.script.buildScriptBindings
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
@@ -232,13 +233,14 @@ interface BaseSource : JsExtensions {
*/ */
@Throws(Exception::class) @Throws(Exception::class)
fun evalJS(jsStr: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? { fun evalJS(jsStr: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings.apply(bindingsConfig) bindings.apply(bindingsConfig)
bindings["java"] = this bindings["java"] = this
bindings["source"] = this bindings["source"] = this
bindings["baseUrl"] = getKey() bindings["baseUrl"] = getKey()
bindings["cookie"] = CookieStore bindings["cookie"] = CookieStore
bindings["cache"] = CacheManager bindings["cache"] = CacheManager
}
val scope = RhinoScriptEngine.getRuntimeScope(bindings) val scope = RhinoScriptEngine.getRuntimeScope(bindings)
getShareScope()?.let { getShareScope()?.let {
scope.prototype = it scope.prototype = it
@@ -3,7 +3,7 @@
package io.legado.app.help.book package io.legado.app.help.book
import android.net.Uri import android.net.Uri
import com.script.ScriptBindings import com.script.buildScriptBindings
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.BookSourceType import io.legado.app.constant.BookSourceType
@@ -273,10 +273,11 @@ fun Book.getExportFileName(suffix: String): String {
if (jsStr.isNullOrBlank()) { if (jsStr.isNullOrBlank()) {
return "$name 作者:${getRealAuthor()}.$suffix" return "$name 作者:${getRealAuthor()}.$suffix"
} }
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误 bindings["epubIndex"] = ""// 兼容老版本,修复可能存在的错误
bindings["name"] = name bindings["name"] = name
bindings["author"] = getRealAuthor() bindings["author"] = getRealAuthor()
}
return kotlin.runCatching { return kotlin.runCatching {
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
}.onFailure { }.onFailure {
@@ -297,10 +298,11 @@ fun Book.getExportFileName(
if (jsStr.isNullOrBlank()) { if (jsStr.isNullOrBlank()) {
return default return default
} }
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings["name"] = name bindings["name"] = name
bindings["author"] = getRealAuthor() bindings["author"] = getRealAuthor()
bindings["epubIndex"] = epubIndex bindings["epubIndex"] = epubIndex
}
return kotlin.runCatching { return kotlin.runCatching {
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
}.onFailure { }.onFailure {
@@ -327,10 +329,11 @@ fun Book.readSimulating(): Boolean {
} }
fun tryParesExportFileName(jsStr: String): Boolean { fun tryParesExportFileName(jsStr: String): Boolean {
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings["name"] = "name" bindings["name"] = "name"
bindings["author"] = "author" bindings["author"] = "author"
bindings["epubIndex"] = "epubIndex" bindings["epubIndex"] = "epubIndex"
}
return runCatching { return runCatching {
RhinoScriptEngine.eval(jsStr, bindings) RhinoScriptEngine.eval(jsStr, bindings)
true true
@@ -3,6 +3,7 @@ package io.legado.app.model.analyzeRule
import android.text.TextUtils import android.text.TextUtils
import androidx.annotation.Keep import androidx.annotation.Keep
import com.script.ScriptBindings import com.script.ScriptBindings
import com.script.buildScriptBindings
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppPattern.JS_PATTERN import io.legado.app.constant.AppPattern.JS_PATTERN
import io.legado.app.data.entities.BaseBook import io.legado.app.data.entities.BaseBook
@@ -745,18 +746,19 @@ class AnalyzeRule(
* 执行JS * 执行JS
*/ */
fun evalJS(jsStr: String, result: Any? = null): Any? { fun evalJS(jsStr: String, result: Any? = null): Any? {
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings["java"] = this bindings["java"] = this
bindings["cookie"] = CookieStore bindings["cookie"] = CookieStore
bindings["cache"] = CacheManager bindings["cache"] = CacheManager
bindings["source"] = source bindings["source"] = source
bindings["book"] = book bindings["book"] = book
bindings["result"] = result bindings["result"] = result
bindings["baseUrl"] = baseUrl bindings["baseUrl"] = baseUrl
bindings["chapter"] = chapter bindings["chapter"] = chapter
bindings["title"] = chapter?.title bindings["title"] = chapter?.title
bindings["src"] = content bindings["src"] = content
bindings["nextChapterUrl"] = nextChapterUrl bindings["nextChapterUrl"] = nextChapterUrl
}
val scope = RhinoScriptEngine.getRuntimeScope(bindings) val scope = RhinoScriptEngine.getRuntimeScope(bindings)
source?.getShareScope()?.let { source?.getShareScope()?.let {
scope.prototype = it scope.prototype = it
@@ -6,7 +6,7 @@ import androidx.annotation.Keep
import androidx.media3.common.MediaItem import androidx.media3.common.MediaItem
import cn.hutool.core.util.HexUtil import cn.hutool.core.util.HexUtil
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GlideUrl
import com.script.ScriptBindings import com.script.buildScriptBindings
import com.script.rhino.RhinoScriptEngine import com.script.rhino.RhinoScriptEngine
import io.legado.app.constant.AppConst.UA_NAME import io.legado.app.constant.AppConst.UA_NAME
import io.legado.app.constant.AppPattern import io.legado.app.constant.AppPattern
@@ -266,18 +266,19 @@ class AnalyzeUrl(
* 执行JS * 执行JS
*/ */
fun evalJS(jsStr: String, result: Any? = null): Any? { fun evalJS(jsStr: String, result: Any? = null): Any? {
val bindings = ScriptBindings() val bindings = buildScriptBindings { bindings ->
bindings["java"] = this bindings["java"] = this
bindings["baseUrl"] = baseUrl bindings["baseUrl"] = baseUrl
bindings["cookie"] = CookieStore bindings["cookie"] = CookieStore
bindings["cache"] = CacheManager bindings["cache"] = CacheManager
bindings["page"] = page bindings["page"] = page
bindings["key"] = key bindings["key"] = key
bindings["speakText"] = speakText bindings["speakText"] = speakText
bindings["speakSpeed"] = speakSpeed bindings["speakSpeed"] = speakSpeed
bindings["book"] = ruleData as? Book bindings["book"] = ruleData as? Book
bindings["source"] = source bindings["source"] = source
bindings["result"] = result bindings["result"] = result
}
val scope = RhinoScriptEngine.getRuntimeScope(bindings) val scope = RhinoScriptEngine.getRuntimeScope(bindings)
source?.getShareScope()?.let { source?.getShareScope()?.let {
scope.prototype = it scope.prototype = it
@@ -20,6 +20,7 @@ import io.legado.app.utils.isTrue
import io.legado.app.utils.mapAsync import io.legado.app.utils.mapAsync
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flow
import org.mozilla.javascript.Context
import splitties.init.appCtx import splitties.init.appCtx
import kotlin.coroutines.coroutineContext import kotlin.coroutines.coroutineContext
@@ -126,21 +127,25 @@ object BookChapterList {
} }
Debug.log(book.origin, "◇目录总数:${list.size}") Debug.log(book.origin, "◇目录总数:${list.size}")
coroutineContext.ensureActive() coroutineContext.ensureActive()
val formatJs = tocRule.formatJs
val bindings = ScriptBindings()
bindings["gInt"] = 0
list.forEachIndexed { index, bookChapter -> list.forEachIndexed { index, bookChapter ->
bookChapter.index = index bookChapter.index = index
if (!formatJs.isNullOrBlank()) { }
bindings["index"] = index + 1 val formatJs = tocRule.formatJs
bindings["chapter"] = bookChapter if (!formatJs.isNullOrBlank()) {
bindings["title"] = bookChapter.title Context.enter().use {
RhinoScriptEngine.runCatching { val bindings = ScriptBindings()
eval(formatJs, bindings)?.toString()?.let { bindings["gInt"] = 0
bookChapter.title = it list.forEachIndexed { index, bookChapter ->
bindings["index"] = index + 1
bindings["chapter"] = bookChapter
bindings["title"] = bookChapter.title
RhinoScriptEngine.runCatching {
eval(formatJs, bindings)?.toString()?.let {
bookChapter.title = it
}
}.onFailure {
Debug.log(book.origin, "格式化标题出错, ${it.localizedMessage}")
} }
}.onFailure {
Debug.log(book.origin, "格式化标题出错, ${it.localizedMessage}")
} }
} }
} }
-1
View File
@@ -105,7 +105,6 @@ protobuf-javalite = { module = "com.google.protobuf:protobuf-javalite", version.
quick-chinese-transfer-core = { module = "com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core", version.ref = "quickChineseTransfer" } quick-chinese-transfer-core = { module = "com.github.liuyueyi.quick-chinese-transfer:quick-transfer-core", version.ref = "quickChineseTransfer" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
@@ -39,4 +39,8 @@ class ScriptBindings : NativeObject() {
} }
} }
fun put(key: String, value: Any?) {
set(key, value)
}
} }
@@ -0,0 +1,14 @@
package com.script
import org.mozilla.javascript.Context
inline fun buildScriptBindings(block: (bindings: ScriptBindings) -> Unit): ScriptBindings {
val bindings = ScriptBindings()
Context.enter()
try {
block(bindings)
} finally {
Context.exit()
}
return bindings
}
@@ -55,7 +55,12 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
fun eval(js: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? { fun eval(js: String, bindingsConfig: ScriptBindings.() -> Unit = {}): Any? {
val bindings = ScriptBindings() val bindings = ScriptBindings()
bindings.apply(bindingsConfig) Context.enter()
try {
bindings.apply(bindingsConfig)
} finally {
Context.exit()
}
return eval(js, bindings) return eval(js, bindings)
} }
@@ -249,7 +254,7 @@ object RhinoScriptEngine : AbstractScriptEngine(), Invocable, Compilable {
return newScope return newScope
} }
override fun getRuntimeScope(bindings: ScriptBindings): ScriptBindings { override fun getRuntimeScope(bindings: ScriptBindings): Scriptable {
val cx = Context.enter() val cx = Context.enter()
try { try {
bindings.prototype = cx.initStandardObjects() bindings.prototype = cx.initStandardObjects()