This commit is contained in:
kunfei
2023-03-16 16:32:44 +08:00
parent b60a21181e
commit 09b530dc83
5 changed files with 50 additions and 53 deletions
@@ -7,7 +7,6 @@ import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.replace import io.legado.app.utils.replace
import io.legado.app.utils.stackTraceStr import io.legado.app.utils.stackTraceStr
import kotlinx.coroutines.runBlocking
object ReplaceRuleController { object ReplaceRuleController {
@@ -77,19 +76,17 @@ object ReplaceRuleController {
returnData.setErrorMsg("替换规则不能为空") returnData.setErrorMsg("替换规则不能为空")
} }
val text = map["text"] as String val text = map["text"] as String
val content = runBlocking { val content = try {
try { if (rule.isRegex) {
if (rule.isRegex) { text.replace(
text.replace( rule.pattern.toRegex(),
rule.pattern.toRegex(), rule.replacement, rule.timeoutMillisecond
rule.replacement, rule.timeoutMillisecond )
) } else {
} else { text.replace(rule.pattern, rule.replacement)
text.replace(rule.pattern, rule.replacement)
}
} catch (e: Exception) {
e.stackTraceStr
} }
} catch (e: Exception) {
e.stackTraceStr
} }
returnData.setData(content) returnData.setData(content)
} }
@@ -13,7 +13,6 @@ import io.legado.app.model.ReadBook
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.MD5Utils import io.legado.app.utils.MD5Utils
import io.legado.app.utils.fromJsonObject import io.legado.app.utils.fromJsonObject
import kotlinx.coroutines.runBlocking
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import java.nio.charset.Charset import java.nio.charset.Charset
@@ -270,11 +269,9 @@ data class Book(
fun migrateTo(newBook: Book, toc: List<BookChapter>): Book { fun migrateTo(newBook: Book, toc: List<BookChapter>): Book {
newBook.durChapterIndex = BookHelp newBook.durChapterIndex = BookHelp
.getDurChapter(durChapterIndex, durChapterTitle, toc, totalChapterNum) .getDurChapter(durChapterIndex, durChapterTitle, toc, totalChapterNum)
newBook.durChapterTitle = runBlocking { newBook.durChapterTitle = toc[newBook.durChapterIndex].getDisplayTitle(
toc[newBook.durChapterIndex].getDisplayTitle( ContentProcessor.get(newBook.name, newBook.origin).getTitleReplaceRules()
ContentProcessor.get(newBook.name, newBook.origin).getTitleReplaceRules() )
)
}
newBook.durChapterPos = durChapterPos newBook.durChapterPos = durChapterPos
newBook.durChapterTime = durChapterTime newBook.durChapterTime = durChapterTime
newBook.group = group newBook.group = group
@@ -83,7 +83,7 @@ data class BookChapter(
return false return false
} }
suspend fun getDisplayTitle( fun getDisplayTitle(
replaceRules: List<ReplaceRule>? = null, replaceRules: List<ReplaceRule>? = null,
useReplace: Boolean = true, useReplace: Boolean = true,
chineseConvert: Boolean = true, chineseConvert: Boolean = true,
@@ -72,7 +72,7 @@ class ContentProcessor private constructor(
return contentReplaceRules return contentReplaceRules
} }
suspend fun getContent( fun getContent(
book: Book, book: Book,
chapter: BookChapter, chapter: BookChapter,
content: String, content: String,
@@ -153,7 +153,7 @@ class ContentProcessor private constructor(
return BookContent(sameTitleRemoved, contents) return BookContent(sameTitleRemoved, contents)
} }
private suspend fun replaceContent(content: String): String { private fun replaceContent(content: String): String {
var mContent = content var mContent = content
mContent = mContent.lines().joinToString("\n") { it.trim() } mContent = mContent.lines().joinToString("\n") { it.trim() }
getContentReplaceRules().forEach { item -> getContentReplaceRules().forEach { item ->
@@ -6,6 +6,7 @@ import io.legado.app.constant.AppConst
import io.legado.app.exception.RegexTimeoutException import io.legado.app.exception.RegexTimeoutException
import io.legado.app.help.CrashHandler import io.legado.app.help.CrashHandler
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import splitties.init.appCtx import splitties.init.appCtx
import kotlin.coroutines.resume import kotlin.coroutines.resume
@@ -16,43 +17,45 @@ private val handler by lazy { buildMainHandler() }
/** /**
* 带有超时检测的正则替换 * 带有超时检测的正则替换
*/ */
suspend fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String { fun CharSequence.replace(regex: Regex, replacement: String, timeout: Long): String {
val charSequence = this@replace val charSequence = this@replace
val isJs = replacement.startsWith("@js:") val isJs = replacement.startsWith("@js:")
val replacement1 = if (isJs) replacement.substring(4) else replacement val replacement1 = if (isJs) replacement.substring(4) else replacement
return suspendCancellableCoroutine { block -> return runBlocking {
val coroutine = Coroutine.async { suspendCancellableCoroutine { block ->
try { val coroutine = Coroutine.async {
val pattern = regex.toPattern() try {
val matcher = pattern.matcher(charSequence) val pattern = regex.toPattern()
val stringBuffer = StringBuffer() val matcher = pattern.matcher(charSequence)
while (matcher.find()) { val stringBuffer = StringBuffer()
if (isJs) { while (matcher.find()) {
val bindings = SimpleBindings() if (isJs) {
bindings["result"] = matcher.group() val bindings = SimpleBindings()
val jsResult = bindings["result"] = matcher.group()
AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString() val jsResult =
matcher.appendReplacement(stringBuffer, jsResult) AppConst.SCRIPT_ENGINE.eval(replacement1, bindings).toString()
} else { matcher.appendReplacement(stringBuffer, jsResult)
matcher.appendReplacement(stringBuffer, replacement1) } else {
matcher.appendReplacement(stringBuffer, replacement1)
}
} }
matcher.appendTail(stringBuffer)
block.resume(stringBuffer.toString())
} catch (e: Exception) {
block.resumeWithException(e)
} }
matcher.appendTail(stringBuffer)
block.resume(stringBuffer.toString())
} catch (e: Exception) {
block.resumeWithException(e)
} }
} handler.postDelayed(timeout) {
handler.postDelayed(timeout) { if (coroutine.isActive) {
if (coroutine.isActive) { val timeoutMsg = "替换超时,3秒后还未结束将重启应用\n替换规则$regex\n替换内容:${this}"
val timeoutMsg = "替换超时,3秒后还未结束将重启应用\n替换规则$regex\n替换内容:${this}" val exception = RegexTimeoutException(timeoutMsg)
val exception = RegexTimeoutException(timeoutMsg) block.cancel(exception)
block.cancel(exception) appCtx.longToastOnUi(timeoutMsg)
appCtx.longToastOnUi(timeoutMsg) CrashHandler.saveCrashInfo2File(exception)
CrashHandler.saveCrashInfo2File(exception) handler.postDelayed(3000) {
handler.postDelayed(3000) { if (coroutine.isActive) {
if (coroutine.isActive) { appCtx.restart()
appCtx.restart() }
} }
} }
} }