Merge remote-tracking branch 'origin/master'

pull/32/head
kunfei 5 years ago
commit 1cbd490f19
  1. 1
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  2. 11
      app/src/main/java/io/legado/app/help/permission/Request.kt
  3. 2
      app/src/main/java/io/legado/app/model/WebBook.kt
  4. 17
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt
  5. 28
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt
  6. 17
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByXPath.kt
  7. 3
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt
  8. 8
      app/src/main/java/io/legado/app/ui/search/SearchViewModel.kt
  9. 13
      app/src/main/java/io/legado/app/utils/StringExtensions.kt

@ -2,6 +2,7 @@ package io.legado.app.help.coroutine
import kotlinx.coroutines.* import kotlinx.coroutines.*
class Coroutine<T>() { class Coroutine<T>() {
companion object { companion object {

@ -87,9 +87,9 @@ internal class Request : OnRequestPermissionsResultCallback {
} else { } else {
if (deniedPermissions != null) { if (deniedPermissions != null) {
source?.context?.startActivity<PermissionActivity>( source?.context?.startActivity<PermissionActivity>(
Pair(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION), PermissionActivity.KEY_INPUT_REQUEST_TYPE to TYPE_REQUEST_PERMISSION,
Pair(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode), PermissionActivity.KEY_INPUT_PERMISSIONS_CODE to requestCode,
Pair(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions) PermissionActivity.KEY_INPUT_PERMISSIONS to deniedPermissions
) )
} else { } else {
onPermissionsGranted(requestCode) onPermissionsGranted(requestCode)
@ -133,10 +133,7 @@ internal class Request : OnRequestPermissionsResultCallback {
.setMessage(rationale) .setMessage(rationale)
.setPositiveButton(R.string.dialog_setting) { _, _ -> .setPositiveButton(R.string.dialog_setting) { _, _ ->
it.startActivity<PermissionActivity>( it.startActivity<PermissionActivity>(
Pair( PermissionActivity.KEY_INPUT_REQUEST_TYPE to TYPE_REQUEST_SETTING
PermissionActivity.KEY_INPUT_REQUEST_TYPE,
TYPE_REQUEST_SETTING
)
) )
} }
.setNegativeButton(R.string.dialog_cancel) { _, _ -> cancel() } .setNegativeButton(R.string.dialog_cancel) { _, _ -> cancel() }

@ -14,7 +14,7 @@ class WebBook(private val bookSource: BookSource) {
fun searchBook(key: String, page: Int?): Coroutine<List<SearchBook>> { fun searchBook(key: String, page: Int?): Coroutine<List<SearchBook>> {
return Coroutine.async { return Coroutine.async {
bookSource.getSearchRule().searchUrl?.let { searchUrl -> bookSource.getSearchRule().searchUrl?.let { searchUrl ->
val analyzeUrl = AnalyzeUrl(searchUrl) val analyzeUrl = AnalyzeUrl(searchUrl, key, page)
val response = when { val response = when {
analyzeUrl.method == AnalyzeUrl.Method.POST -> HttpHelper.getApiService<IHttpPostApi>( analyzeUrl.method == AnalyzeUrl.Method.POST -> HttpHelper.getApiService<IHttpPostApi>(
analyzeUrl.baseUrl analyzeUrl.baseUrl

@ -3,6 +3,7 @@ package io.legado.app.model.analyzeRule
import android.text.TextUtils import android.text.TextUtils
import com.jayway.jsonpath.JsonPath import com.jayway.jsonpath.JsonPath
import com.jayway.jsonpath.ReadContext import com.jayway.jsonpath.ReadContext
import io.legado.app.utils.splitNotBlank
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@ -24,10 +25,10 @@ class AnalyzeByJSonPath {
val rules: Array<String> val rules: Array<String>
val elementsType: String val elementsType: String
if (rule.contains("&&")) { if (rule.contains("&&")) {
rules = rule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} else { } else {
rules = rule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
if (rules.size == 1) { if (rules.size == 1) {
@ -82,15 +83,15 @@ class AnalyzeByJSonPath {
val elementsType: String val elementsType: String
when { when {
rule.contains("&&") -> { rule.contains("&&") -> {
rules = rule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} }
rule.contains("%%") -> { rule.contains("%%") -> {
rules = rule.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("%%")
elementsType = "%" elementsType = "%"
} }
else -> { else -> {
rules = rule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
} }
@ -159,15 +160,15 @@ class AnalyzeByJSonPath {
val rules: Array<String> val rules: Array<String>
when { when {
rule.contains("&&") -> { rule.contains("&&") -> {
rules = rule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} }
rule.contains("%%") -> { rule.contains("%%") -> {
rules = rule.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("%%")
elementsType = "%" elementsType = "%"
} }
else -> { else -> {
rules = rule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
} }

@ -2,6 +2,7 @@ package io.legado.app.model.analyzeRule
import android.text.TextUtils.isEmpty import android.text.TextUtils.isEmpty
import android.text.TextUtils.join import android.text.TextUtils.join
import io.legado.app.utils.splitNotBlank
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.jsoup.select.Collector import org.jsoup.select.Collector
@ -81,15 +82,15 @@ class AnalyzeByJSoup {
when { when {
sourceRule.elementsRule.contains("&&") -> { sourceRule.elementsRule.contains("&&") -> {
elementsType = "&" elementsType = "&"
ruleStrS = sourceRule.elementsRule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("&&")
} }
sourceRule.elementsRule.contains("%%") -> { sourceRule.elementsRule.contains("%%") -> {
elementsType = "%" elementsType = "%"
ruleStrS = sourceRule.elementsRule.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("%%")
} }
else -> { else -> {
elementsType = "|" elementsType = "|"
ruleStrS = sourceRule.elementsRule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("||")
} }
} }
val results = ArrayList<List<String>>() val results = ArrayList<List<String>>()
@ -144,15 +145,15 @@ class AnalyzeByJSoup {
when { when {
sourceRule.elementsRule.contains("&&") -> { sourceRule.elementsRule.contains("&&") -> {
elementsType = "&" elementsType = "&"
ruleStrS = sourceRule.elementsRule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("&&")
} }
sourceRule.elementsRule.contains("%%") -> { sourceRule.elementsRule.contains("%%") -> {
elementsType = "%" elementsType = "%"
ruleStrS = sourceRule.elementsRule.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("%%")
} }
else -> { else -> {
elementsType = "|" elementsType = "|"
ruleStrS = sourceRule.elementsRule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() ruleStrS = sourceRule.elementsRule.splitNotBlank("||")
} }
} }
val elementsList = ArrayList<Elements>() val elementsList = ArrayList<Elements>()
@ -215,7 +216,7 @@ class AnalyzeByJSoup {
private fun getElementsSingle(temp: Element, rule: String): Elements { private fun getElementsSingle(temp: Element, rule: String): Elements {
val elements = Elements() val elements = Elements()
try { try {
val rs = rule.trim { it <= ' ' }.split("@").dropLastWhile { it.isEmpty() }.toTypedArray() val rs = rule.trim { it <= ' ' }.splitNotBlank("@")
if (rs.size > 1) { if (rs.size > 1) {
elements.add(temp) elements.add(temp)
for (rl in rs) { for (rl in rs) {
@ -227,16 +228,15 @@ class AnalyzeByJSoup {
elements.addAll(es) elements.addAll(es)
} }
} else { } else {
val rulePcx = rule.split("!").dropLastWhile { it.isEmpty() }.toTypedArray() val rulePcx = rule.splitNotBlank("!")
val rulePc = val rulePc =
rulePcx[0].trim { it <= ' ' }.split(">").dropLastWhile { it.isEmpty() }.toTypedArray() rulePcx[0].trim { it <= ' ' }.splitNotBlank(">")
val rules = val rules =
rulePc[0].trim { it <= ' ' }.split(".").dropLastWhile { it.isEmpty() }.toTypedArray() rulePc[0].trim { it <= ' ' }.splitNotBlank(".")
var filterRules: Array<String>? = null var filterRules: Array<String>? = null
var needFilterElements = rulePc.size > 1 && !isEmpty(rulePc[1].trim { it <= ' ' }) var needFilterElements = rulePc.size > 1 && !isEmpty(rulePc[1].trim { it <= ' ' })
if (needFilterElements) { if (needFilterElements) {
filterRules = rulePc[1].trim { it <= ' ' }.split(".").dropLastWhile { it.isEmpty() } filterRules = rulePc[1].trim { it <= ' ' }.splitNotBlank(".")
.toTypedArray()
filterRules[0] = filterRules[0].trim { it <= ' ' } filterRules[0] = filterRules[0].trim { it <= ' ' }
val validKeys = listOf("class", "id", "tag", "text") val validKeys = listOf("class", "id", "tag", "text")
if (filterRules.size < 2 || !validKeys.contains(filterRules[0]) || isEmpty(filterRules[1].trim { it <= ' ' })) { if (filterRules.size < 2 || !validKeys.contains(filterRules[0]) || isEmpty(filterRules[1].trim { it <= ' ' })) {
@ -305,7 +305,7 @@ class AnalyzeByJSoup {
else -> elements.addAll(temp.select(rulePcx[0])) else -> elements.addAll(temp.select(rulePcx[0]))
} }
if (rulePcx.size > 1) { if (rulePcx.size > 1) {
val rulePcs = rulePcx[1].split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() val rulePcs = rulePcx[1].splitNotBlank(":")
for (pc in rulePcs) { for (pc in rulePcs) {
val pcInt = Integer.parseInt(pc) val pcInt = Integer.parseInt(pc)
if (pcInt < 0 && elements.size + pcInt >= 0) { if (pcInt < 0 && elements.size + pcInt >= 0) {
@ -334,7 +334,7 @@ class AnalyzeByJSoup {
} }
var elements = Elements() var elements = Elements()
elements.add(element) elements.add(element)
val rules = ruleStr.split("@").dropLastWhile { it.isEmpty() }.toTypedArray() val rules = ruleStr.splitNotBlank("@")
for (i in 0 until rules.size - 1) { for (i in 0 until rules.size - 1) {
val es = Elements() val es = Elements()
for (elt in elements) { for (elt in elements) {

@ -1,6 +1,7 @@
package io.legado.app.model.analyzeRule package io.legado.app.model.analyzeRule
import android.text.TextUtils import android.text.TextUtils
import io.legado.app.utils.splitNotBlank
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.seimicrawler.xpath.JXDocument import org.seimicrawler.xpath.JXDocument
import org.seimicrawler.xpath.JXNode import org.seimicrawler.xpath.JXNode
@ -35,15 +36,15 @@ class AnalyzeByXPath {
val rules: Array<String> val rules: Array<String>
when { when {
xPath.contains("&&") -> { xPath.contains("&&") -> {
rules = xPath.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} }
xPath.contains("%%") -> { xPath.contains("%%") -> {
rules = xPath.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("%%")
elementsType = "%" elementsType = "%"
} }
else -> { else -> {
rules = xPath.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
} }
@ -85,15 +86,15 @@ class AnalyzeByXPath {
val rules: Array<String> val rules: Array<String>
when { when {
xPath.contains("&&") -> { xPath.contains("&&") -> {
rules = xPath.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} }
xPath.contains("%%") -> { xPath.contains("%%") -> {
rules = xPath.split("%%").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("%%")
elementsType = "%" elementsType = "%"
} }
else -> { else -> {
rules = xPath.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = xPath.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
} }
@ -140,10 +141,10 @@ class AnalyzeByXPath {
val rules: Array<String> val rules: Array<String>
val elementsType: String val elementsType: String
if (rule.contains("&&")) { if (rule.contains("&&")) {
rules = rule.split("&&").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("&&")
elementsType = "&" elementsType = "&"
} else { } else {
rules = rule.split("||").dropLastWhile { it.isEmpty() }.toTypedArray() rules = rule.splitNotBlank("||")
elementsType = "|" elementsType = "|"
} }
if (rules.size == 1) { if (rules.size == 1) {

@ -462,8 +462,7 @@ class AnalyzeRule(private var book: BaseBook? = null) {
} }
//分离正则表达式 //分离正则表达式
val ruleStrS = val ruleStrS =
rule.trim { it <= ' ' }.split("##".toRegex()).dropLastWhile { it.isEmpty() } rule.trim { it <= ' ' }.splitNotBlank("##")
.toTypedArray()
rule = ruleStrS[0] rule = ruleStrS[0]
if (ruleStrS.size > 1) { if (ruleStrS.size > 1) {
replaceRegex = ruleStrS[1] replaceRegex = ruleStrS[1]

@ -24,6 +24,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
channel.send(it) channel.send(it)
} }
} }
val c = execute { val c = execute {
val response: String = HttpHelper.getApiService<CommonHttpApi>( val response: String = HttpHelper.getApiService<CommonHttpApi>(
"http://www.baidu.com" "http://www.baidu.com"
@ -32,7 +33,6 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
delay(2000L) delay(2000L)
response response
} }
.onStart { .onStart {
Log.e("TAG!", "start") Log.e("TAG!", "start")
@ -54,7 +54,8 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
val c2 = plus(c) val c2 = plus(c)
// .timeout { 100L } // .timeout { 100L }
// .onErrorReturn { "error return2" } // .onErrorReturn { "error return2" }
.onStart {//会拦截掉c的onStart .onStart {
//会拦截掉c的onStart
Log.e("TAG!", "start2") Log.e("TAG!", "start2")
start?.let { it() } start?.let { it() }
} }
@ -69,12 +70,11 @@ class SearchViewModel(application: Application) : BaseViewModel(application) {
if (finally != null) { if (finally != null) {
finally() finally()
} }
Log.e("TAG!", "rec2: " + channel.receive()) Log.e("TAG!", "rec2: " + channel.receive())
} }
launch { launch {
delay(1500L) delay(1500L)
// c2.cancel() // c2.cancel()

@ -23,11 +23,14 @@ fun String?.htmlFormat(): String = if (this.isNullOrBlank()) "" else
.replace("^[\\n\\s]+".toRegex(), "  ")//移除开头空行,并增加段前缩进2个汉字 .replace("^[\\n\\s]+".toRegex(), "  ")//移除开头空行,并增加段前缩进2个汉字
.replace("[\\n\\s]+$".toRegex(), "") //移除尾部空行 .replace("[\\n\\s]+$".toRegex(), "") //移除尾部空行
fun String?.splitNotBlank(delim: String) = this?.run { fun String.splitNotBlank(delimiter: String): Array<String> = run {
if (!this.contains(delim)) sequenceOf(this) else this.split(delimiter).map { it.trim() }.filterNot { it.isBlank() }.toTypedArray()
this.split(delim).asSequence().map { it.trim() }.filterNot { it.isBlank() }
} }
fun String?.startWithIgnoreCase(start: String): Boolean { fun String.splitNotBlank(regex: Regex, limit: Int = 0): Array<String> = run {
return if (this.isNullOrBlank()) false else startsWith(start, true) this.split(regex, limit).map { it.trim() }.filterNot { it.isBlank() }.toTypedArray()
}
fun String.startWithIgnoreCase(start: String): Boolean {
return if (this.isBlank()) false else startsWith(start, true)
} }
Loading…
Cancel
Save