jsLib完成
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@ val appDb by lazy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Database(
|
@Database(
|
||||||
version = 65,
|
version = 66,
|
||||||
exportSchema = true,
|
exportSchema = true,
|
||||||
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
|
||||||
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
|
||||||
@@ -50,7 +50,8 @@ val appDb by lazy {
|
|||||||
AutoMigration(from = 61, to = 62),
|
AutoMigration(from = 61, to = 62),
|
||||||
AutoMigration(from = 62, to = 63),
|
AutoMigration(from = 62, to = 63),
|
||||||
AutoMigration(from = 63, to = 64),
|
AutoMigration(from = 63, to = 64),
|
||||||
AutoMigration(from = 64, to = 65, spec = DatabaseMigrations.Migration_64_65::class)
|
AutoMigration(from = 64, to = 65, spec = DatabaseMigrations.Migration_64_65::class),
|
||||||
|
AutoMigration(from = 65, to = 66)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ import io.legado.app.help.CacheManager
|
|||||||
import io.legado.app.help.JsExtensions
|
import io.legado.app.help.JsExtensions
|
||||||
import io.legado.app.help.config.AppConfig
|
import io.legado.app.help.config.AppConfig
|
||||||
import io.legado.app.help.http.CookieStore
|
import io.legado.app.help.http.CookieStore
|
||||||
|
import io.legado.app.model.SharedJsScope
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import org.intellij.lang.annotations.Language
|
import org.intellij.lang.annotations.Language
|
||||||
|
import org.mozilla.javascript.Scriptable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 可在js里调用,source.xxx()
|
* 可在js里调用,source.xxx()
|
||||||
@@ -43,6 +45,11 @@ interface BaseSource : JsExtensions {
|
|||||||
*/
|
*/
|
||||||
var enabledCookieJar: Boolean?
|
var enabledCookieJar: Boolean?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* js库
|
||||||
|
*/
|
||||||
|
var jsLib: String?
|
||||||
|
|
||||||
fun getTag(): String
|
fun getTag(): String
|
||||||
|
|
||||||
fun getKey(): String
|
fun getKey(): String
|
||||||
@@ -230,4 +237,8 @@ interface BaseSource : JsExtensions {
|
|||||||
bindings["cache"] = CacheManager
|
bindings["cache"] = CacheManager
|
||||||
return SCRIPT_ENGINE.eval(jsStr, bindings)
|
return SCRIPT_ENGINE.eval(jsStr, bindings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getShareScope(): Scriptable? {
|
||||||
|
return SharedJsScope.getScope(jsLib)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ data class BookSource(
|
|||||||
@ColumnInfo(defaultValue = "1")
|
@ColumnInfo(defaultValue = "1")
|
||||||
var enabledExplore: Boolean = true,
|
var enabledExplore: Boolean = true,
|
||||||
// js库
|
// js库
|
||||||
var jsLib: String? = null,
|
override var jsLib: String? = null,
|
||||||
// 启用okhttp CookieJAr 自动保存每次请求的cookie
|
// 启用okhttp CookieJAr 自动保存每次请求的cookie
|
||||||
@ColumnInfo(defaultValue = "0")
|
@ColumnInfo(defaultValue = "0")
|
||||||
override var enabledCookieJar: Boolean? = true,
|
override var enabledCookieJar: Boolean? = true,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ data class HttpTTS(
|
|||||||
override var loginUrl: String? = null,
|
override var loginUrl: String? = null,
|
||||||
override var loginUi: String? = null,
|
override var loginUi: String? = null,
|
||||||
override var header: String? = null,
|
override var header: String? = null,
|
||||||
|
override var jsLib: String? = null,
|
||||||
@ColumnInfo(defaultValue = "0")
|
@ColumnInfo(defaultValue = "0")
|
||||||
override var enabledCookieJar: Boolean? = false,
|
override var enabledCookieJar: Boolean? = false,
|
||||||
var loginCheckJs: String? = null,
|
var loginCheckJs: String? = null,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ data class RssSource(
|
|||||||
// 自定义变量说明
|
// 自定义变量说明
|
||||||
var variableComment: String? = null,
|
var variableComment: String? = null,
|
||||||
// js库
|
// js库
|
||||||
var jsLib: String? = null,
|
override var jsLib: String? = null,
|
||||||
// 启用okhttp CookieJAr 自动保存每次请求的cookie
|
// 启用okhttp CookieJAr 自动保存每次请求的cookie
|
||||||
@ColumnInfo(defaultValue = "0")
|
@ColumnInfo(defaultValue = "0")
|
||||||
override var enabledCookieJar: Boolean? = true,
|
override var enabledCookieJar: Boolean? = true,
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package io.legado.app.help.source
|
|||||||
|
|
||||||
import io.legado.app.data.entities.BookSource
|
import io.legado.app.data.entities.BookSource
|
||||||
import io.legado.app.data.entities.rule.ExploreKind
|
import io.legado.app.data.entities.rule.ExploreKind
|
||||||
import io.legado.app.model.SharedJsScope
|
|
||||||
import io.legado.app.utils.ACache
|
import io.legado.app.utils.ACache
|
||||||
import io.legado.app.utils.GSON
|
import io.legado.app.utils.GSON
|
||||||
import io.legado.app.utils.MD5Utils
|
import io.legado.app.utils.MD5Utils
|
||||||
@@ -13,16 +12,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.mozilla.javascript.Scriptable
|
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.collections.List
|
|
||||||
import kotlin.collections.arrayListOf
|
|
||||||
import kotlin.collections.emptyList
|
|
||||||
import kotlin.collections.filterNotNull
|
|
||||||
import kotlin.collections.first
|
|
||||||
import kotlin.collections.forEach
|
|
||||||
import kotlin.collections.getOrNull
|
|
||||||
import kotlin.collections.hashMapOf
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,10 +83,6 @@ suspend fun BookSource.clearExploreKindsCache() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun BookSource.getShareScope(): Scriptable? {
|
|
||||||
return SharedJsScope.getScope(jsLib)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun BookSource.contains(word: String?): Boolean {
|
fun BookSource.contains(word: String?): Boolean {
|
||||||
if (word.isNullOrEmpty()) {
|
if (word.isNullOrEmpty()) {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package io.legado.app.help.source
|
package io.legado.app.help.source
|
||||||
|
|
||||||
import io.legado.app.data.entities.RssSource
|
import io.legado.app.data.entities.RssSource
|
||||||
import io.legado.app.model.SharedJsScope
|
|
||||||
import io.legado.app.utils.ACache
|
import io.legado.app.utils.ACache
|
||||||
import io.legado.app.utils.MD5Utils
|
import io.legado.app.utils.MD5Utils
|
||||||
import io.legado.app.utils.NetworkUtils
|
import io.legado.app.utils.NetworkUtils
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.mozilla.javascript.Scriptable
|
|
||||||
|
|
||||||
private val aCache by lazy { ACache.get("rssSortUrl") }
|
private val aCache by lazy { ACache.get("rssSortUrl") }
|
||||||
|
|
||||||
@@ -59,7 +57,3 @@ suspend fun RssSource.removeSortCache() {
|
|||||||
aCache.remove(getSortUrlsKey())
|
aCache.remove(getSortUrlsKey())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun RssSource.getShareScope(): Scriptable? {
|
|
||||||
return SharedJsScope.getScope(jsLib)
|
|
||||||
}
|
|
||||||
@@ -155,6 +155,7 @@ object BookCover {
|
|||||||
override var loginUrl: String? = null,
|
override var loginUrl: String? = null,
|
||||||
override var loginUi: String? = null,
|
override var loginUi: String? = null,
|
||||||
override var header: String? = null,
|
override var header: String? = null,
|
||||||
|
override var jsLib: String? = null,
|
||||||
override var enabledCookieJar: Boolean? = false,
|
override var enabledCookieJar: Boolean? = false,
|
||||||
) : BaseSource {
|
) : BaseSource {
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import io.legado.app.utils.MD5Utils
|
|||||||
import io.legado.app.utils.Rhino
|
import io.legado.app.utils.Rhino
|
||||||
import io.legado.app.utils.isAbsUrl
|
import io.legado.app.utils.isAbsUrl
|
||||||
import io.legado.app.utils.isJsonObject
|
import io.legado.app.utils.isJsonObject
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.mozilla.javascript.Scriptable
|
import org.mozilla.javascript.Scriptable
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -25,7 +26,7 @@ object SharedJsScope {
|
|||||||
|
|
||||||
private val scopeMap = hashMapOf<String, WeakReference<Scriptable>>()
|
private val scopeMap = hashMapOf<String, WeakReference<Scriptable>>()
|
||||||
|
|
||||||
suspend fun getScope(jsLib: String?): Scriptable? {
|
fun getScope(jsLib: String?): Scriptable? {
|
||||||
if (jsLib.isNullOrBlank()) {
|
if (jsLib.isNullOrBlank()) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
@@ -49,9 +50,11 @@ object SharedJsScope {
|
|||||||
val fileName = MD5Utils.md5Encode(value)
|
val fileName = MD5Utils.md5Encode(value)
|
||||||
var js = aCache.getAsString(fileName)
|
var js = aCache.getAsString(fileName)
|
||||||
if (js == null) {
|
if (js == null) {
|
||||||
js = okHttpClient.newCallStrResponse {
|
js = runBlocking {
|
||||||
|
okHttpClient.newCallStrResponse {
|
||||||
url(value)
|
url(value)
|
||||||
}.body
|
}.body
|
||||||
|
}
|
||||||
if (js !== null) {
|
if (js !== null) {
|
||||||
aCache.put(fileName, js)
|
aCache.put(fileName, js)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -693,7 +693,12 @@ class AnalyzeRule(
|
|||||||
bindings["title"] = chapter?.title
|
bindings["title"] = chapter?.title
|
||||||
bindings["src"] = content
|
bindings["src"] = content
|
||||||
bindings["nextChapterUrl"] = nextChapterUrl
|
bindings["nextChapterUrl"] = nextChapterUrl
|
||||||
return SCRIPT_ENGINE.eval(jsStr, bindings)
|
val context = SCRIPT_ENGINE.getScriptContext(bindings)
|
||||||
|
val scope = SCRIPT_ENGINE.getRuntimeScope(context)
|
||||||
|
source?.getShareScope()?.let {
|
||||||
|
scope.prototype = it
|
||||||
|
}
|
||||||
|
return SCRIPT_ENGINE.eval(jsStr, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getSource(): BaseSource? {
|
override fun getSource(): BaseSource? {
|
||||||
|
|||||||
@@ -265,7 +265,12 @@ class AnalyzeUrl(
|
|||||||
bindings["book"] = ruleData as? Book
|
bindings["book"] = ruleData as? Book
|
||||||
bindings["source"] = source
|
bindings["source"] = source
|
||||||
bindings["result"] = result
|
bindings["result"] = result
|
||||||
return SCRIPT_ENGINE.eval(jsStr, bindings)
|
val context = SCRIPT_ENGINE.getScriptContext(bindings)
|
||||||
|
val scope = SCRIPT_ENGINE.getRuntimeScope(context)
|
||||||
|
source?.getShareScope()?.let {
|
||||||
|
scope.prototype = it
|
||||||
|
}
|
||||||
|
return SCRIPT_ENGINE.eval(jsStr, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun put(key: String, value: String): String {
|
fun put(key: String, value: String): String {
|
||||||
@@ -475,7 +480,6 @@ class AnalyzeUrl(
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
setCookie()
|
setCookie()
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
|
||||||
val response = getProxyClient(proxy).newCallResponse(retry) {
|
val response = getProxyClient(proxy).newCallResponse(retry) {
|
||||||
addHeaders(headerMap)
|
addHeaders(headerMap)
|
||||||
when (method) {
|
when (method) {
|
||||||
@@ -514,7 +518,6 @@ class AnalyzeUrl(
|
|||||||
private fun getByteArrayIfDataUri(): ByteArray? {
|
private fun getByteArrayIfDataUri(): ByteArray? {
|
||||||
@Suppress("RegExpRedundantEscape")
|
@Suppress("RegExpRedundantEscape")
|
||||||
val dataUriFindResult = dataUriRegex.find(urlNoQuery)
|
val dataUriFindResult = dataUriRegex.find(urlNoQuery)
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
|
||||||
if (dataUriFindResult != null) {
|
if (dataUriFindResult != null) {
|
||||||
val dataUriBase64 = dataUriFindResult.groupValues[1]
|
val dataUriBase64 = dataUriFindResult.groupValues[1]
|
||||||
val byteArray = Base64.decode(dataUriBase64, Base64.DEFAULT)
|
val byteArray = Base64.decode(dataUriBase64, Base64.DEFAULT)
|
||||||
@@ -526,7 +529,6 @@ class AnalyzeUrl(
|
|||||||
/**
|
/**
|
||||||
* 访问网站,返回ByteArray
|
* 访问网站,返回ByteArray
|
||||||
*/
|
*/
|
||||||
@Suppress("UnnecessaryVariable", "LiftReturnOrAssignment")
|
|
||||||
@Throws(ConcurrentException::class)
|
@Throws(ConcurrentException::class)
|
||||||
suspend fun getByteArrayAwait(): ByteArray {
|
suspend fun getByteArrayAwait(): ByteArray {
|
||||||
getByteArrayIfDataUri()?.let {
|
getByteArrayIfDataUri()?.let {
|
||||||
@@ -544,7 +546,6 @@ class AnalyzeUrl(
|
|||||||
/**
|
/**
|
||||||
* 访问网站,返回InputStream
|
* 访问网站,返回InputStream
|
||||||
*/
|
*/
|
||||||
@Suppress("LiftReturnOrAssignment")
|
|
||||||
@Throws(ConcurrentException::class)
|
@Throws(ConcurrentException::class)
|
||||||
suspend fun getInputStreamAwait(): InputStream {
|
suspend fun getInputStreamAwait(): InputStream {
|
||||||
getByteArrayIfDataUri()?.let {
|
getByteArrayIfDataUri()?.let {
|
||||||
|
|||||||
@@ -330,13 +330,6 @@ object WebBook {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取段评
|
|
||||||
*/
|
|
||||||
fun getReview() {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 精准搜索
|
* 精准搜索
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user