pull/32/head
parent
d7fb601d33
commit
079088d6e5
@ -1,8 +0,0 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class BaseRule( |
||||
var selector: String = "", |
||||
var template: String? = null, |
||||
var attr: String? = null, |
||||
var type: RuleType |
||||
) |
@ -1,11 +1,14 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class BookInfoRule( |
||||
var name: Rule, |
||||
var author: Rule, |
||||
var desc: Rule, |
||||
var meta: Rule, |
||||
var updateTime: Rule, |
||||
var tocUrl: Rule, |
||||
var store: List<PutRule> |
||||
var urlPattern: String? = null, |
||||
var init: String? = null, |
||||
var name: String? = null, |
||||
var author: String? = null, |
||||
var desc: String? = null, |
||||
var meta: String? = null, |
||||
var lastChapter: String? = null, |
||||
var updateTime: String? = null, |
||||
var coverUrl: String? = null, |
||||
var tocUrl: String? = null |
||||
) |
@ -1,10 +0,0 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class ChapterRule( |
||||
var chapterList: Rule, |
||||
var isReversed: Boolean = false, |
||||
var title: Rule, |
||||
var contentUrl: Rule, |
||||
var resourceUrl: Rule, |
||||
var nextUrl: Rule |
||||
) |
@ -1,7 +1,6 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class ContentRule( |
||||
var fulltext: Rule, |
||||
var resourceUrl: Rule, |
||||
var nextUrl: Rule |
||||
var content: String? = null, |
||||
var nextUrl: String? = null |
||||
) |
@ -1,11 +1,14 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class ExploreRule( |
||||
var bookList: Rule, |
||||
var name: Rule, |
||||
var author: Rule, |
||||
var desc: Rule, |
||||
var meta: Rule, |
||||
var bookUrl: Rule, |
||||
var store: PutRule |
||||
var exploreUrl: String? = null, |
||||
var bookList: String? = null, |
||||
var name: String? = null, |
||||
var author: String? = null, |
||||
var desc: String? = null, |
||||
var meta: String? = null, |
||||
var lastChapter: String? = null, |
||||
var updateTime: String? = null, |
||||
var bookUrl: String? = null, |
||||
var coverUrl: String? = null |
||||
) |
@ -1,6 +0,0 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class PutRule( |
||||
var selector: Rule, |
||||
var key: String |
||||
) |
@ -1,120 +0,0 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
import io.legado.app.utils.safeTrim |
||||
import io.legado.app.utils.splitNotBlank |
||||
|
||||
data class Rule( |
||||
var selectors: List<BaseRule>, |
||||
var regex: String?, |
||||
var replacement: String?, |
||||
var javascript: String?, |
||||
var extra: String? |
||||
) { |
||||
companion object { |
||||
val JS_PATTERN = Regex("""\{\{([^}]+?)}}""") |
||||
val CONST_PATTERN = Regex("""\{(\$\.[^}]+?)}""") |
||||
|
||||
fun parse(input: String) = when { |
||||
input.startsWith("$.") -> parseJSON(input) |
||||
input.startsWith("//") -> parseXPATH(input) |
||||
input.startsWith("RE:") -> parseREGEX(input) |
||||
isJsRule(input) -> parseJS(input) |
||||
isConstRule(input) -> parseCONST(input) |
||||
else -> parseCSS(input) |
||||
} |
||||
|
||||
private fun isJsRule(input: String): Boolean { |
||||
val open = input.indexOf("{{") |
||||
if (open < 0) return false |
||||
val close = input.indexOf("}}", open) |
||||
return close > 0 |
||||
} |
||||
|
||||
private fun isConstRule(input: String): Boolean { |
||||
val open = input.indexOf("{") |
||||
if (open < 0) return false |
||||
val close = input.indexOf("}", open) |
||||
return close > 0 |
||||
} |
||||
|
||||
|
||||
private fun parseCSS(rawRule: String): List<BaseRule> { |
||||
val rules = mutableListOf<BaseRule>() |
||||
for (line in rawRule.splitNotBlank("\n")) { |
||||
val baseRule = BaseRule(type = RuleType.CSS) |
||||
if (line.contains("@@")) { |
||||
val temp = line.split("@@") |
||||
baseRule.selector = temp[0].trim() |
||||
baseRule.attr = temp[1].safeTrim() ?: "text" // 写了 @@ 但是后面空白的也默认为 text |
||||
} else { |
||||
baseRule.selector = line |
||||
baseRule.attr = "text" |
||||
} |
||||
rules.add(baseRule) |
||||
} |
||||
return rules |
||||
} |
||||
|
||||
private fun parseJSON(rawRule: String): List<BaseRule> { |
||||
val rules = mutableListOf<BaseRule>() |
||||
for (line in rawRule.splitNotBlank("\n")) { |
||||
val baseRule = BaseRule(type = RuleType.JSON) |
||||
baseRule.selector = line |
||||
rules.add(baseRule) |
||||
} |
||||
return rules |
||||
} |
||||
|
||||
private fun parseXPATH(rawRule: String): List<BaseRule> { |
||||
val rules = mutableListOf<BaseRule>() |
||||
for (line in rawRule.splitNotBlank("\n")) { |
||||
val baseRule = BaseRule(type = RuleType.XPATH) |
||||
baseRule.selector = line |
||||
rules.add(baseRule) |
||||
} |
||||
return rules |
||||
} |
||||
|
||||
private fun parseCONST(rawRule: String): List<BaseRule> { |
||||
val rules = mutableListOf<BaseRule>() |
||||
val subRule = mutableListOf<String>() |
||||
for (line in rawRule.splitNotBlank("\n")) { |
||||
subRule.clear() |
||||
val baseRule = BaseRule(type = RuleType.JSON) |
||||
// 保留 URL 中的 % 字符 |
||||
baseRule.template = CONST_PATTERN.replace(line.replace("%", "%%")) { match -> |
||||
subRule.add(match.groupValues[1]) |
||||
"%s" |
||||
} |
||||
baseRule.selector = subRule.joinToString("\n") |
||||
rules.add(baseRule) |
||||
} |
||||
return rules |
||||
} |
||||
|
||||
private fun parseJS(rawRule: String): List<BaseRule> { |
||||
TODO() |
||||
} |
||||
|
||||
private fun parseREGEX(rawRule: String): List<BaseRule> { |
||||
TODO() |
||||
} |
||||
|
||||
} |
||||
} |
||||
|
||||
/* |
||||
* |
||||
* CSS 规则说明 |
||||
* 使用 JSOUP 的"选择规则",后面加上需要获取的属性名或者方法,如 href, data-url, text 等,如果不加默认为 text |
||||
* CSS "选择规则" 和 "属性方法" 之间用 @@ 隔开 |
||||
* |
||||
* CONST 规则说明: |
||||
* {$.xxx} 表示要获取 JSON 变量 $.xxx,最先解析 |
||||
* {@.yyy} 表示要获取之前存储的变量 yyy |
||||
* {#.zzz} 表示直接输出 zzz,可以留空,{#.} 什么也不输出 |
||||
* |
||||
* */ |
||||
enum class RuleType { |
||||
CSS, XPATH, JSON, REGEX, CONST, JS, HYBRID |
||||
} |
@ -1,11 +1,14 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class SearchRule( |
||||
var bookList: Rule, |
||||
var name: Rule, |
||||
var author: Rule, |
||||
var desc: Rule, |
||||
var meta: Rule, |
||||
var bookUrl: Rule, |
||||
var store: List<PutRule> |
||||
var searchUrl: String? = null, |
||||
var bookList: String? = null, |
||||
var name: String? = null, |
||||
var author: String? = null, |
||||
var desc: String? = null, |
||||
var meta: String? = null, |
||||
var lastChapter: String? = null, |
||||
var updateTime: String? = null, |
||||
var bookUrl: String? = null, |
||||
var coverUrl: String? = null |
||||
) |
@ -0,0 +1,8 @@ |
||||
package io.legado.app.data.entities.rule |
||||
|
||||
data class TocRule( |
||||
var chapterList: String? = null, |
||||
var chapterName: String? = null, |
||||
var chapterUrl: String? = null, |
||||
var nextUrl: String? = null |
||||
) |
Loading…
Reference in new issue