diff --git a/app/src/main/java/io/legado/app/help/RuleComplete.kt b/app/src/main/java/io/legado/app/help/RuleComplete.kt new file mode 100644 index 000000000..cbdc6b4ed --- /dev/null +++ b/app/src/main/java/io/legado/app/help/RuleComplete.kt @@ -0,0 +1,75 @@ +package io.legado.app.help + + +object RuleComplete { + + // 补全时忽略匹配规则 + private val completeIgnore = + Regex( + """\\n|##|@js:||@Json:|\$\.|(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\)|##.*)?\s*$""", + RegexOption.MULTILINE + ) + + // 补全时忽略匹配的规则(判断列表项和详情页预处理规则生效) + private val completeIgnorePreRule = Regex("""^:|##|@js:||@Json:|\$\.""") + + // 匹配从图片获取信息的规则 + private val imgComplete = Regex( + """(?<=(tag\.|[+/@~>| &]))img[@/]text(\(\))?$|^img[@/]text(\(\))?$""", + RegexOption.IGNORE_CASE + ) + + + /** + * 对简单规则进行补全,简化部分书源规则的编写 + * 该方法仅对对JSOUP/XPath/CSS规则生效 + * @author 希弥 + * @return 补全后的规则 或 原规则 + * @param rule 需要补全的规则 + * @param preRule 预处理规则 + * 用于分析详情页预处理规则 + * @param type 补全结果的类型,可选的值有: + * 1 文字(默认) + * 2 链接 + * 3 图片 + */ + fun autoComplete( + rule: String?, + preRule: String? = null, + type: Int = 1, + enable: Boolean + ): String? { + if (!enable) { + return rule + } + if (rule.isNullOrEmpty() || rule.contains(completeIgnore) + || preRule?.contains(completeIgnorePreRule) == true + ) { + return rule + } + val textRule: String + val linkRule: String + val imgRule: String + val imgText: String + if (rule.contains(Regex("/[^@]+$"))) { + textRule = "/text()" + linkRule = "/@href" + imgRule = "/@src" + imgText = "img/@alt" + } else { + textRule = "@text" + linkRule = "@href" + imgRule = "@src" + imgText = "img@alt" + } + var ret: String = rule + when (type) { + 1 -> ret = rule.replace(Regex("$"), textRule).replace(imgComplete, imgText) + 2 -> ret = rule.replace(Regex("$"), linkRule) + 3 -> ret = rule.replace(Regex("$"), imgRule) + } + return ret + } + + +} diff --git a/app/src/main/java/io/legado/app/help/ruleComplete.kt b/app/src/main/java/io/legado/app/help/ruleComplete.kt deleted file mode 100644 index af699e667..000000000 --- a/app/src/main/java/io/legado/app/help/ruleComplete.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.legado.app.help - -// 补全时忽略匹配规则 -val completeIgnore = - Regex("""\\n|##|@js:||@Json:|\$\.|(attr|text|ownText|textNodes|href|content|html|alt|all|value|src)(\(\)|##.*)?\s*$""",RegexOption.MULTILINE) - -// 补全时忽略匹配的规则(判断列表项和详情页预处理规则生效) -val completeIgnorePreRule = Regex("""^:|##|@js:||@Json:|\$\.""") - -// 匹配从图片获取信息的规则 -val imgComplete = Regex( - """(?<=(tag\.|[+/@~>| &]))img[@/]text(\(\))?$|^img[@/]text(\(\))?$""", - RegexOption.IGNORE_CASE -) - -/** - * 对简单规则进行补全,简化部分书源规则的编写 - * 该方法仅对对JSOUP/XPath/CSS规则生效 - * @author 希弥 - * @return 补全后的规则 或 原规则 - * @param rule 需要补全的规则 - * @param preRule 预处理规则 - * 用于分析详情页预处理规则 - * @param type 补全结果的类型,可选的值有: - * 1 文字(默认) - * 2 链接 - * 3 图片 - */ -fun ruleComplete(rule: String?, preRule: String? = "", type: Int = 1): String? { - if (rule.isNullOrEmpty() || rule.contains(completeIgnore) - || preRule?.contains(completeIgnorePreRule) == true - ) { - return rule - } - val textRule: String - val linkRule: String - val imgRule: String - val imgText: String - if (rule.contains(Regex("/[^@]+$"))) { - textRule = "/text()" - linkRule = "/@href" - imgRule = "/@src" - imgText = "img/@alt" - } else { - textRule = "@text" - linkRule = "@href" - imgRule = "@src" - imgText = "img@alt" - } - var ret: String = rule - when (type) { - 1 -> ret = rule.replace(Regex("$"), textRule).replace(imgComplete, imgText) - 2 -> ret = rule.replace(Regex("$"), linkRule) - 3 -> ret = rule.replace(Regex("$"), imgRule) - } - return ret -} diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index 28803d546..cc8bfe8df 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -21,7 +21,6 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.* import io.legado.app.databinding.ActivityBookSourceEditBinding import io.legado.app.help.LocalConfig -import io.legado.app.help.ruleComplete import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.backgroundColor @@ -90,6 +89,7 @@ class BookSourceEditActivity : override fun onMenuOpened(featureId: Int, menu: Menu): Boolean { menu.findItem(R.id.menu_login)?.isVisible = !viewModel.bookSource?.loginUrl.isNullOrBlank() + menu.findItem(R.id.menu_auto_complete)?.isChecked = viewModel.autoComplete return super.onMenuOpened(featureId, menu) } @@ -112,6 +112,7 @@ class BookSourceEditActivity : } } } + R.id.menu_auto_complete -> viewModel.autoComplete = !viewModel.autoComplete R.id.menu_copy_source -> sendToClip(GSON.toJson(getSource())) R.id.menu_paste_source -> viewModel.pasteSource { upRecyclerView(it) } R.id.menu_qr_code_camera -> qrCodeResult.launch() @@ -328,64 +329,86 @@ class BookSourceEditActivity : "searchUrl" -> source.searchUrl = it.value "checkKeyWord" -> searchRule.checkKeyWord = it.value "bookList" -> searchRule.bookList = it.value ?: "" - "name" -> searchRule.name = ruleComplete(it.value,searchRule.bookList) - "author" -> searchRule.author = ruleComplete(it.value,searchRule.bookList) - "kind" -> searchRule.kind = ruleComplete(it.value,searchRule.bookList) - "intro" -> searchRule.intro = ruleComplete(it.value,searchRule.bookList) - "updateTime" -> searchRule.updateTime = ruleComplete(it.value,searchRule.bookList) - "wordCount" -> searchRule.wordCount = ruleComplete(it.value,searchRule.bookList) - "lastChapter" -> searchRule.lastChapter = ruleComplete(it.value,searchRule.bookList) - "coverUrl" -> searchRule.coverUrl = ruleComplete(it.value,searchRule.bookList,3) - "bookUrl" -> searchRule.bookUrl = ruleComplete(it.value,searchRule.bookList,2) + "name" -> searchRule.name = viewModel.ruleComplete(it.value, searchRule.bookList) + "author" -> searchRule.author = + viewModel.ruleComplete(it.value, searchRule.bookList) + "kind" -> searchRule.kind = viewModel.ruleComplete(it.value, searchRule.bookList) + "intro" -> searchRule.intro = viewModel.ruleComplete(it.value, searchRule.bookList) + "updateTime" -> searchRule.updateTime = + viewModel.ruleComplete(it.value, searchRule.bookList) + "wordCount" -> searchRule.wordCount = + viewModel.ruleComplete(it.value, searchRule.bookList) + "lastChapter" -> searchRule.lastChapter = + viewModel.ruleComplete(it.value, searchRule.bookList) + "coverUrl" -> searchRule.coverUrl = + viewModel.ruleComplete(it.value, searchRule.bookList, 3) + "bookUrl" -> searchRule.bookUrl = + viewModel.ruleComplete(it.value, searchRule.bookList, 2) } } findEntities.forEach { when (it.key) { "exploreUrl" -> source.exploreUrl = it.value "bookList" -> exploreRule.bookList = it.value ?: "" - "name" -> exploreRule.name = ruleComplete(it.value,exploreRule.bookList) - "author" -> exploreRule.author = ruleComplete(it.value,exploreRule.bookList) - "kind" -> exploreRule.kind = ruleComplete(it.value,exploreRule.bookList) - "intro" -> exploreRule.intro = ruleComplete(it.value,exploreRule.bookList) - "updateTime" -> exploreRule.updateTime = ruleComplete(it.value,exploreRule.bookList) - "wordCount" -> exploreRule.wordCount = ruleComplete(it.value,exploreRule.bookList) - "lastChapter" -> exploreRule.lastChapter = ruleComplete(it.value,exploreRule.bookList) - "coverUrl" -> exploreRule.coverUrl = ruleComplete(it.value,exploreRule.bookList,3) - "bookUrl" -> exploreRule.bookUrl = ruleComplete(it.value,exploreRule.bookList,2) + "name" -> exploreRule.name = viewModel.ruleComplete(it.value, exploreRule.bookList) + "author" -> exploreRule.author = + viewModel.ruleComplete(it.value, exploreRule.bookList) + "kind" -> exploreRule.kind = viewModel.ruleComplete(it.value, exploreRule.bookList) + "intro" -> exploreRule.intro = + viewModel.ruleComplete(it.value, exploreRule.bookList) + "updateTime" -> exploreRule.updateTime = + viewModel.ruleComplete(it.value, exploreRule.bookList) + "wordCount" -> exploreRule.wordCount = + viewModel.ruleComplete(it.value, exploreRule.bookList) + "lastChapter" -> exploreRule.lastChapter = + viewModel.ruleComplete(it.value, exploreRule.bookList) + "coverUrl" -> exploreRule.coverUrl = + viewModel.ruleComplete(it.value, exploreRule.bookList, 3) + "bookUrl" -> exploreRule.bookUrl = + viewModel.ruleComplete(it.value, exploreRule.bookList, 2) } } infoEntities.forEach { when (it.key) { "init" -> bookInfoRule.init = it.value ?: "" - "name" -> bookInfoRule.name = ruleComplete(it.value, bookInfoRule.init) - "author" -> bookInfoRule.author = ruleComplete(it.value, bookInfoRule.init) - "kind" -> bookInfoRule.kind = ruleComplete(it.value, bookInfoRule.init) - "intro" -> bookInfoRule.intro = ruleComplete(it.value, bookInfoRule.init) - "updateTime" -> bookInfoRule.updateTime = ruleComplete(it.value, bookInfoRule.init) - "wordCount" -> bookInfoRule.wordCount = ruleComplete(it.value, bookInfoRule.init) + "name" -> bookInfoRule.name = viewModel.ruleComplete(it.value, bookInfoRule.init) + "author" -> bookInfoRule.author = + viewModel.ruleComplete(it.value, bookInfoRule.init) + "kind" -> bookInfoRule.kind = viewModel.ruleComplete(it.value, bookInfoRule.init) + "intro" -> bookInfoRule.intro = viewModel.ruleComplete(it.value, bookInfoRule.init) + "updateTime" -> bookInfoRule.updateTime = + viewModel.ruleComplete(it.value, bookInfoRule.init) + "wordCount" -> bookInfoRule.wordCount = + viewModel.ruleComplete(it.value, bookInfoRule.init) "lastChapter" -> bookInfoRule.lastChapter = - ruleComplete(it.value, bookInfoRule.init) - "coverUrl" -> bookInfoRule.coverUrl = ruleComplete(it.value, bookInfoRule.init, 3) - "tocUrl" -> bookInfoRule.tocUrl = ruleComplete(it.value, bookInfoRule.init, 2) + viewModel.ruleComplete(it.value, bookInfoRule.init) + "coverUrl" -> bookInfoRule.coverUrl = + viewModel.ruleComplete(it.value, bookInfoRule.init, 3) + "tocUrl" -> bookInfoRule.tocUrl = + viewModel.ruleComplete(it.value, bookInfoRule.init, 2) "canReName" -> bookInfoRule.canReName = it.value } } tocEntities.forEach { when (it.key) { "chapterList" -> tocRule.chapterList = it.value ?: "" - "chapterName" -> tocRule.chapterName = ruleComplete(it.value,tocRule.chapterList) - "chapterUrl" -> tocRule.chapterUrl = ruleComplete(it.value,tocRule.chapterList, 2) + "chapterName" -> tocRule.chapterName = + viewModel.ruleComplete(it.value, tocRule.chapterList) + "chapterUrl" -> tocRule.chapterUrl = + viewModel.ruleComplete(it.value, tocRule.chapterList, 2) "isVolume" -> tocRule.isVolume = it.value "updateTime" -> tocRule.updateTime = it.value "isVip" -> tocRule.isVip = it.value "isPay" -> tocRule.isPay = it.value - "nextTocUrl" -> tocRule.nextTocUrl = ruleComplete(it.value,tocRule.chapterList,2) + "nextTocUrl" -> tocRule.nextTocUrl = + viewModel.ruleComplete(it.value, tocRule.chapterList, 2) } } contentEntities.forEach { when (it.key) { - "content" -> contentRule.content = ruleComplete(it.value) - "nextContentUrl" -> contentRule.nextContentUrl = ruleComplete(it.value, type = 2) + "content" -> contentRule.content = viewModel.ruleComplete(it.value) + "nextContentUrl" -> contentRule.nextContentUrl = + viewModel.ruleComplete(it.value, type = 2) "webJs" -> contentRule.webJs = it.value "sourceRegex" -> contentRule.sourceRegex = it.value "replaceRegex" -> contentRule.replaceRegex = it.value diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt index 948714664..03683d51f 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt @@ -5,6 +5,7 @@ import android.content.Intent import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource +import io.legado.app.help.RuleComplete import io.legado.app.help.http.newCallStrResponse import io.legado.app.help.http.okHttpClient import io.legado.app.model.NoStackTraceException @@ -13,7 +14,7 @@ import kotlinx.coroutines.Dispatchers class BookSourceEditViewModel(application: Application) : BaseViewModel(application) { - + var autoComplete = false var bookSource: BookSource? = null private var oldSourceUrl: String? = null @@ -95,4 +96,9 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat } } } + + fun ruleComplete(rule: String?, preRule: String? = null, type: Int = 1): String? { + return RuleComplete.autoComplete(rule, preRule, type, autoComplete) + } + } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_code_view.xml b/app/src/main/res/layout/dialog_code_view.xml index 411ac4a8c..3f0ffd8b9 100644 --- a/app/src/main/res/layout/dialog_code_view.xml +++ b/app/src/main/res/layout/dialog_code_view.xml @@ -19,8 +19,7 @@ android:id="@+id/code_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="12dp" - android:textIsSelectable="true" /> + android:padding="12dp" /> diff --git a/app/src/main/res/menu/source_edit.xml b/app/src/main/res/menu/source_edit.xml index f4dd24240..dc20d0f20 100644 --- a/app/src/main/res/menu/source_edit.xml +++ b/app/src/main/res/menu/source_edit.xml @@ -1,24 +1,32 @@ - + + app:showAsAction="always" /> + app:showAsAction="always" /> + + 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index bffb90efe..d4a30e496 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -947,5 +947,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 325e1220b..01f07fef6 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -947,5 +947,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 8decfbf09..dc9757fee 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -944,5 +944,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5b0a70a61..00a2a1162 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -946,5 +946,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 93868fd11..9621f1543 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -946,5 +946,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4eff8223d..6577cbf65 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -947,5 +947,6 @@ 时间排序 开启记录 拷贝所有 + 自动补全