Merge remote-tracking branch 'origin/master'

pull/32/head
Administrator 5 years ago
commit 0f70ab546b
  1. 4
      app/build.gradle
  2. 3
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSoup.kt
  3. 42
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  4. 6
      app/src/main/java/io/legado/app/model/book/All.kt
  5. 5
      app/src/main/java/io/legado/app/model/book/BookChapterList.kt
  6. 5
      app/src/main/java/io/legado/app/model/book/BookContent.kt
  7. 5
      app/src/main/java/io/legado/app/model/book/BookInfo.kt
  8. 5
      app/src/main/java/io/legado/app/model/book/BookList.kt
  9. 28
      app/src/main/java/io/legado/app/utils/Encoder.kt
  10. 22
      app/src/main/java/io/legado/app/utils/FileUtils.kt
  11. 34
      app/src/main/java/io/legado/app/utils/NetworkUtils.kt
  12. 1
      app/src/main/java/io/legado/app/utils/README.md
  13. 2
      app/src/main/java/io/legado/app/utils/StringExtensions.kt

@ -80,8 +80,8 @@ dependencies {
//androidX
implementation 'androidx.core:core-ktx:1.2.0-alpha02'
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
implementation 'androidx.preference:preference:1.1.0-beta01'
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
implementation 'androidx.preference:preference:1.1.0-rc01'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta1'
implementation 'com.google.android.material:material:1.1.0-alpha07'
implementation 'com.google.android:flexbox:1.1.0'

@ -2,7 +2,6 @@ package io.legado.app.model.analyzeRule
import android.text.TextUtils.isEmpty
import android.text.TextUtils.join
import io.legado.app.utils.startWithIgnoreCase
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import org.jsoup.select.Collector
@ -414,7 +413,7 @@ class AnalyzeByJSoup {
var replacement = ""
init {
if (ruleStr.startWithIgnoreCase("@CSS:")) {
if (ruleStr.startsWith("@CSS:", true)) {
isCss = true
elementsRule = ruleStr.substring(5).trim { it <= ' ' }
} else {

@ -6,10 +6,9 @@ import androidx.annotation.Keep
import io.legado.app.constant.AppConst.SCRIPT_ENGINE
import io.legado.app.constant.Pattern.EXP_PATTERN
import io.legado.app.data.entities.Book
import io.legado.app.utils.Encoder
import io.legado.app.utils.GSON
import io.legado.app.utils.NetworkUtils
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.*
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.RequestBody
import java.net.URLEncoder
import java.util.*
@ -33,6 +32,7 @@ class AnalyzeUrl(
) {
companion object {
private val pagePattern = Pattern.compile("<(.*?)>")
private val jsonType = MediaType.parse("application/json; charset=utf-8")
}
lateinit var url: String
@ -43,7 +43,7 @@ class AnalyzeUrl(
private set
var queryStr: String? = null
private set
private val queryMap = LinkedHashMap<String, String>()
private val fieldMap = LinkedHashMap<String, String>()
private val headerMap = HashMap<String, String>()
private var charset: String? = null
private var bodyTxt: String? = null
@ -55,9 +55,9 @@ class AnalyzeUrl(
val postData: ByteArray
get() {
val builder = StringBuilder()
val keys = queryMap.keys
val keys = fieldMap.keys
for (key in keys) {
builder.append(String.format("%s=%s&", key, queryMap[key]))
builder.append(String.format("%s=%s&", key, fieldMap[key]))
}
builder.deleteCharAt(builder.lastIndexOf("&"))
return builder.toString().toByteArray()
@ -130,9 +130,7 @@ class AnalyzeUrl(
options?.let {
options["method"]?.let { if (it.equals("POST", true)) method = Method.POST }
options["headers"]?.let { headers ->
GSON.fromJsonObject<Map<String, String>>(
headers
)?.let { headerMap.putAll(it) }
GSON.fromJsonObject<Map<String, String>>(headers)?.let { headerMap.putAll(it) }
}
options["body"]?.let { bodyTxt = it }
options["charset"]?.let { charset = it }
@ -143,11 +141,21 @@ class AnalyzeUrl(
urlArray = url.split("\\?".toRegex())
url = urlArray[0]
if (urlArray.size > 1) {
analyzePutFields(urlArray[1])
analyzeFields(urlArray[1])
}
}
Method.POST -> {
bodyTxt
bodyTxt?.let {
if (it.isJson()) {
body = RequestBody.create(jsonType, it)
} else {
analyzeFields(it)
val builder = FormBody.Builder()
for (item in fieldMap)
builder.add(item.key, item.value)
body = builder.build()
}
}
}
}
}
@ -157,7 +165,7 @@ class AnalyzeUrl(
* 解析QueryMap
*/
@Throws(Exception::class)
private fun analyzePutFields(fieldsTxt: String) {
private fun analyzeFields(fieldsTxt: String) {
queryStr = fieldsTxt
val queryS = fieldsTxt.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (query in queryS) {
@ -165,14 +173,14 @@ class AnalyzeUrl(
val value = if (queryM.size > 1) queryM[1] else ""
if (TextUtils.isEmpty(charset)) {
if (NetworkUtils.hasUrlEncoded(value)) {
queryMap[queryM[0]] = value
fieldMap[queryM[0]] = value
} else {
queryMap[queryM[0]] = URLEncoder.encode(value, "UTF-8")
fieldMap[queryM[0]] = URLEncoder.encode(value, "UTF-8")
}
} else if (charset == "escape") {
queryMap[queryM[0]] = Encoder.escape(value)
fieldMap[queryM[0]] = Encoder.escape(value)
} else {
queryMap[queryM[0]] = URLEncoder.encode(value, charset)
fieldMap[queryM[0]] = URLEncoder.encode(value, charset)
}
}
}

@ -0,0 +1,6 @@
package io.legado.app.model.book
class All {
}

@ -0,0 +1,5 @@
package io.legado.app.model.book
class BookChapterList {
}

@ -0,0 +1,5 @@
package io.legado.app.model.book
class BookContent {
}

@ -0,0 +1,5 @@
package io.legado.app.model.book
class BookInfo {
}

@ -0,0 +1,5 @@
package io.legado.app.model.book
class BookList {
}

@ -3,26 +3,20 @@ package io.legado.app.utils
object Encoder {
fun escape(src: String): String {
var i = 0
var char: Char
val tmp = StringBuilder()
tmp.ensureCapacity(src.length * 6)
while (i < src.length) {
char = src[i]
if (Character.isDigit(char) || Character.isLowerCase(char)
|| Character.isUpperCase(char)
)
for (char in src) {
val charCode = char.toInt()
if (charCode in 48..57 || charCode in 65..90 || charCode in 97..122) {
tmp.append(char)
else if (char.toInt() < 256) {
tmp.append("%")
if (char.toInt() < 16)
tmp.append("0")
tmp.append(char.toInt().toString(16))
} else {
tmp.append("%u")
tmp.append(char.toInt().toString(16))
continue
}
i++
val prefix = when {
charCode < 16 -> "%0"
charCode < 256 -> "%"
else -> "%u"
}
tmp.append(prefix).append(charCode.toString(16))
}
return tmp.toString()
}

@ -21,20 +21,7 @@ object FileUtils {
fun getSdPath() = Environment.getExternalStorageDirectory().absolutePath
fun getFileByPath(filePath: String): File? {
return if (isSpace(filePath)) null else File(filePath)
}
fun isSpace(s: String?): Boolean {
if (s == null) return true
var i = 0
val len = s.length
while (i < len) {
if (!Character.isWhitespace(s[i])) {
return false
}
++i
}
return true
return if (filePath.isBlank()) null else File(filePath)
}
fun getSdCardPath(): String {
@ -101,12 +88,9 @@ object FileUtils {
return paths
}
@TargetApi(Build.VERSION_CODES.KITKAT)
fun getPath(context: Context, uri: Uri): String? {
val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
if (DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
val docId = DocumentsContract.getDocumentId(uri)
@ -119,7 +103,7 @@ object FileUtils {
} else if (isDownloadsDocument(uri)) {
val id = DocumentsContract.getDocumentId(uri)
val split = id.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val split = id.split(":").dropLastWhile { it.isEmpty() }.toTypedArray()
val type = split[0]
if ("raw".equals(
type,

@ -8,37 +8,18 @@ object NetworkUtils {
private val notNeedEncoding: BitSet by lazy {
val bitSet = BitSet(256)
var i: Int = 'a'.toInt()
while (i <= 'z'.toInt()) {
for (i in 'a'.toInt()..'z'.toInt()) {
bitSet.set(i)
i++
}
i = 'A'.toInt()
while (i <= 'Z'.toInt()) {
for (i in 'A'.toInt()..'Z'.toInt()) {
bitSet.set(i)
i++
}
i = '0'.toInt()
while (i <= '9'.toInt()) {
for (i in '0'.toInt()..'9'.toInt()) {
bitSet.set(i)
i++
}
bitSet.set('+'.toInt())
bitSet.set('-'.toInt())
bitSet.set('_'.toInt())
bitSet.set('.'.toInt())
bitSet.set('$'.toInt())
bitSet.set(':'.toInt())
bitSet.set('('.toInt())
bitSet.set(')'.toInt())
bitSet.set('!'.toInt())
bitSet.set('*'.toInt())
bitSet.set('@'.toInt())
bitSet.set('&'.toInt())
bitSet.set('#'.toInt())
bitSet.set(','.toInt())
bitSet.set('['.toInt())
bitSet.set(']'.toInt())
for (char in "+-_.$:()!*@&#,[]") {
bitSet.set(char.toInt())
}
return@lazy bitSet
}
@ -69,7 +50,6 @@ object NetworkUtils {
// 其他字符,肯定需要urlEncode
needEncode = true
break
i++
}
return !needEncode
@ -79,7 +59,7 @@ object NetworkUtils {
* 判断c是否是16进制的字符
*/
private fun isDigit16Char(c: Char): Boolean {
return c >= '0' && c <= '9' || c >= 'A' && c <= 'F'
return c in '0'..'9' || c in 'A'..'F' || c in 'a'..'f'
}
/**

@ -17,7 +17,7 @@ fun String?.isJson(): Boolean = this?.run {
} ?: false
fun String?.htmlFormat(): String = if (this.isNullOrBlank()) "" else
this.replace("(?i)<(br[\\s/]*|/*p.*?|/*div.*?)>".toRegex(), "\n")// 替换特定标签为换行符
this.replace("(?i)<(br[\\s/]*|/*p\\b.*?|/*div\\b.*?)>".toRegex(), "\n")// 替换特定标签为换行符
.replace("<[script>]*.*?>|&nbsp;".toRegex(), "")// 删除script标签对和空格转义符
.replace("\\s*\\n+\\s*".toRegex(), "\n  ")// 移除空行,并增加段前缩进2个汉字
.replace("^[\\n\\s]+".toRegex(), "  ")//移除开头空行,并增加段前缩进2个汉字

Loading…
Cancel
Save