pull/737/head
Robot 4 years ago
commit a2859a53d8
  1. 4
      app/src/main/java/io/legado/app/App.kt
  2. 2
      app/src/main/java/io/legado/app/help/BookHelp.kt
  3. 7
      app/src/main/java/io/legado/app/help/JsExtensions.kt
  4. 13
      app/src/main/java/io/legado/app/help/http/ByteParser.kt
  5. 95
      app/src/main/java/io/legado/app/help/http/HttpHelper.kt
  6. 33
      app/src/main/java/io/legado/app/help/http/TextParser.kt
  7. 36
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt
  8. 4
      app/src/main/java/io/legado/app/model/rss/Rss.kt
  9. 4
      app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt
  10. 4
      app/src/main/java/io/legado/app/model/webBook/BookContent.kt
  11. 10
      app/src/main/java/io/legado/app/model/webBook/WebBook.kt
  12. 2
      app/src/main/java/io/legado/app/service/HttpReadAloudService.kt
  13. 5
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  14. 5
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt
  15. 5
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt
  16. 7
      app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt
  17. 5
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt
  18. 5
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt
  19. 5
      app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt

@ -9,6 +9,7 @@ import android.provider.Settings
import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDexApplication
import com.jeremyliao.liveeventbus.LiveEventBus
import io.legado.app.constant.AppConst
import io.legado.app.constant.AppConst.channelIdDownload
import io.legado.app.constant.AppConst.channelIdReadAloud
import io.legado.app.constant.AppConst.channelIdWeb
@ -47,6 +48,9 @@ class App : MultiDexApplication() {
LanguageUtils.setConfiguration(this)
db = AppDatabase.createDatabase(INSTANCE)
RxHttp.init(HttpHelper.client, BuildConfig.DEBUG)
RxHttp.setOnParamAssembly {
it.addHeader(AppConst.UA_NAME, AppConfig.userAgent)
}
packageManager.getPackageInfo(packageName, 0)?.let {
versionCode = it.versionCode
versionName = it.versionName

@ -112,7 +112,7 @@ object BookHelp {
downloadImages.add(src)
val analyzeUrl = AnalyzeUrl(src)
try {
analyzeUrl.getResponseBytes(book.origin)?.let {
analyzeUrl.getByteArray(book.origin).let {
FileUtils.createFileIfNotExist(
downloadDir,
cacheFolderName,

@ -6,7 +6,6 @@ import androidx.annotation.Keep
import io.legado.app.App
import io.legado.app.constant.AppConst.dateFormat
import io.legado.app.help.http.CookieStore
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.http.SSLHelper
import io.legado.app.model.Debug
import io.legado.app.model.analyzeRule.AnalyzeUrl
@ -15,6 +14,8 @@ import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking
import org.jsoup.Connection
import org.jsoup.Jsoup
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toByteArray
import java.io.File
import java.net.URLEncoder
import java.nio.charset.Charset
@ -250,8 +251,8 @@ interface JsExtensions {
str.isAbsUrl() -> runBlocking {
var x = CacheManager.getByteArray(key)
if (x == null) {
x = HttpHelper.simpleGetBytesAsync(str)
x?.let {
x = RxHttp.get(str).toByteArray().await()
x.let {
CacheManager.put(key, it)
}
}

@ -0,0 +1,13 @@
package io.legado.app.help.http
import okhttp3.Response
import rxhttp.wrapper.annotation.Parser
@Parser(name = "ByteArray")
class ByteParser : rxhttp.wrapper.parse.Parser<ByteArray> {
override fun onParse(response: Response): ByteArray {
return response.body()!!.bytes()
}
}

@ -1,14 +1,8 @@
package io.legado.app.help.http
import io.legado.app.constant.AppConst
import io.legado.app.help.AppConfig
import io.legado.app.help.http.api.HttpGetApi
import io.legado.app.utils.NetworkUtils
import kotlinx.coroutines.suspendCancellableCoroutine
import okhttp3.*
import retrofit2.Retrofit
import rxhttp.toStr
import rxhttp.wrapper.param.RxHttp
import java.net.InetSocketAddress
import java.net.Proxy
import java.util.concurrent.TimeUnit
@ -41,72 +35,48 @@ object HttpHelper {
builder.build()
}
suspend fun simpleGetAsync(url: String): String {
val str = RxHttp.get(url)
.addHeader(AppConst.UA_NAME, AppConfig.userAgent)
.toStr()
return str.await()
}
suspend fun simpleGetBytesAsync(url: String): ByteArray? {
NetworkUtils.getBaseUrl(url)?.let { baseUrl ->
return getByteRetrofit(baseUrl)
.create(HttpGetApi::class.java)
.getMapByteAsync(url, mapOf(), mapOf(Pair(AppConst.UA_NAME, AppConfig.userAgent)))
.body()
}
return null
}
inline fun <reified T> getApiService(
baseUrl: String,
encode: String? = null,
proxy: String? = null
): T {
return if (proxy.isNullOrEmpty()) {
getRetrofit(baseUrl, encode).create(T::class.java)
} else {
getRetrofitWithProxy(baseUrl, encode, proxy).create(T::class.java)
}
}
inline fun <reified T> getBytesApiService(baseUrl: String): T {
return getByteRetrofit(baseUrl).create(T::class.java)
return getRetrofit(baseUrl, encode, proxy).create(T::class.java)
}
fun getRetrofit(baseUrl: String, encode: String? = null): Retrofit {
fun getRetrofit(
baseUrl: String,
encode: String? = null,
proxy: String? = null
): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl)
//增加返回值为字符串的支持(以实体类返回)
.addConverterFactory(EncodeConverter(encode))
.client(client)
.client(getProxyClient(proxy))
.build()
}
fun getRetrofitWithProxy(
baseUrl: String,
encode: String? = null,
proxy: String? = null
): Retrofit {
fun getProxyClient(proxy: String? = null): OkHttpClient {
if (proxy.isNullOrBlank()) {
return client
}
val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?")
val ms = proxy?.let { r.findAll(it) }
val group = ms?.first()
var type = "direct" //直接连接
var host = "127.0.0.1" //代理服务器hostname
var port = 1080 //代理服务器port
val ms = r.findAll(proxy)
val group = ms.first()
val type: String //直接连接
val host: String //代理服务器hostname
val port: Int //代理服务器port
var username = "" //代理服务器验证用户名
var password = "" //代理服务器验证密码
if (group != null) {
type = if (group.groupValues[1] == "http") {
"http"
} else {
"socks"
}
host = group.groupValues[2]
port = group.groupValues[3].toInt()
if (group.groupValues[4] != "") {
username = group.groupValues[4].split("@")[1]
password = group.groupValues[4].split("@")[2]
}
type = if (group.groupValues[1] == "http") {
"http"
} else {
"socks"
}
host = group.groupValues[2]
port = group.groupValues[3].toInt()
if (group.groupValues[4] != "") {
username = group.groupValues[4].split("@")[1]
password = group.groupValues[4].split("@")[2]
}
val builder = client.newBuilder()
if (type != "direct" && host != "") {
@ -125,18 +95,7 @@ object HttpHelper {
}
}
return Retrofit.Builder().baseUrl(baseUrl)
//增加返回值为字符串的支持(以实体类返回)
.addConverterFactory(EncodeConverter(encode))
.client(builder.build())
.build()
}
fun getByteRetrofit(baseUrl: String): Retrofit {
return Retrofit.Builder().baseUrl(baseUrl)
.addConverterFactory(ByteConverter())
.client(client)
.build()
return builder.build()
}
private fun getHeaderInterceptor(): Interceptor {

@ -0,0 +1,33 @@
package io.legado.app.help.http
import io.legado.app.utils.EncodingDetect
import io.legado.app.utils.UTF8BOMFighter
import okhttp3.Response
import rxhttp.wrapper.annotation.Parser
import rxhttp.wrapper.exception.HttpStatusCodeException
import java.nio.charset.Charset
@Parser(name = "Text")
class TextParser(val encode: String? = null) : rxhttp.wrapper.parse.Parser<String> {
override fun onParse(response: Response): String {
val responseBody = response.body() ?: throw HttpStatusCodeException(response, "内容为空")
val responseBytes = UTF8BOMFighter.removeUTF8BOM(responseBody.bytes())
var charsetName: String? = encode
charsetName?.let {
return String(responseBytes, Charset.forName(charsetName))
}
//根据http头判断
responseBody.contentType()?.charset()?.let {
return String(responseBytes, it)
}
//根据内容判断
charsetName = EncodingDetect.getHtmlEncode(responseBytes)
return String(responseBytes, Charset.forName(charsetName))
}
}

@ -22,6 +22,8 @@ import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.RequestBody
import retrofit2.Call
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toByteArray
import java.net.URLEncoder
import java.util.*
import java.util.regex.Pattern
@ -315,13 +317,13 @@ class AnalyzeUrl(
}
}
suspend fun getResponseAwait(
suspend fun getRes(
tag: String,
jsStr: String? = null,
sourceRegex: String? = null,
): Res {
if (type != null) {
return Res(url, StringUtils.byteToHexString(getResponseBytes(tag)))
return Res(url, StringUtils.byteToHexString(getByteArray(tag)))
}
val cookie = CookieStore.getCookie(tag)
if (cookie.isNotEmpty()) {
@ -369,7 +371,7 @@ class AnalyzeUrl(
return Res(NetworkUtils.getUrl(res), res.body())
}
suspend fun getResponseBytes(tag: String? = null): ByteArray? {
suspend fun getByteArray(tag: String? = null): ByteArray {
if (tag != null) {
val cookie = CookieStore.getCookie(tag)
if (cookie.isNotEmpty()) {
@ -382,26 +384,24 @@ class AnalyzeUrl(
}
}
}
val response = when {
method == RequestMethod.POST -> {
return when (method) {
RequestMethod.POST -> {
if (fieldMap.isNotEmpty()) {
HttpHelper
.getBytesApiService<HttpPostApi>(baseUrl)
.postMapByteAsync(url, fieldMap, headerMap)
RxHttp.postForm(url)
.addAll(fieldMap)
.addAllHeader(headerMap)
.toByteArray().await()
} else {
HttpHelper
.getBytesApiService<HttpPostApi>(baseUrl)
.postBodyByteAsync(url, requestBody!!, headerMap)
RxHttp.postJson(url)
.addAll(body)
.addAllHeader(headerMap)
.toByteArray().await()
}
}
fieldMap.isEmpty() -> HttpHelper
.getBytesApiService<HttpGetApi>(baseUrl)
.getByteAsync(url, headerMap)
else -> HttpHelper
.getBytesApiService<HttpGetApi>(baseUrl)
.getMapByteAsync(url, fieldMap, headerMap)
else -> RxHttp.get(url)
.addAll(fieldMap)
.toByteArray().await()
}
return response.body()
}
fun getGlideUrl(): GlideUrl {

@ -26,7 +26,7 @@ object Rss {
page = page,
headerMapF = rssSource.getHeaderMap()
)
val body = analyzeUrl.getResponseAwait(rssSource.sourceUrl).body
val body = analyzeUrl.getRes(rssSource.sourceUrl).body
RssParserByRule.parseXML(sortName, sortUrl, body, rssSource)
}
}
@ -42,7 +42,7 @@ object Rss {
val body = AnalyzeUrl(
rssArticle.link, baseUrl = rssArticle.origin,
headerMapF = rssSource?.getHeaderMap()
).getResponseAwait(rssArticle.origin)
).getRes(rssArticle.origin)
.body
val analyzeRule = AnalyzeRule()
analyzeRule.setContent(body)

@ -63,7 +63,7 @@ object BookChapterList {
ruleUrl = nextUrl,
book = book,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait(bookSource.bookSourceUrl)
).getRes(bookSource.bookSourceUrl)
.body?.let { nextBody ->
chapterData = analyzeChapterList(
book, nextUrl, nextBody, tocRule, listRule, bookSource
@ -132,7 +132,7 @@ object BookChapterList {
ruleUrl = chapterData.nextUrl,
book = book,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait(bookSource.bookSourceUrl).body
).getRes(bookSource.bookSourceUrl).body
?: throw Exception("${chapterData.nextUrl}, 下载失败")
val nextChapterData = analyzeChapterList(
book, chapterData.nextUrl, nextBody, tocRule, listRule, bookSource,

@ -56,7 +56,7 @@ object BookContent {
ruleUrl = nextUrl,
book = book,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait(bookSource.bookSourceUrl).body?.let { nextBody ->
).getRes(bookSource.bookSourceUrl).body?.let { nextBody ->
contentData = analyzeContent(
book, nextUrl, nextBody, contentRule, bookChapter, bookSource, false
)
@ -78,7 +78,7 @@ object BookContent {
ruleUrl = item.nextUrl,
book = book,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait(bookSource.bookSourceUrl).body?.let {
).getRes(bookSource.bookSourceUrl).body?.let {
contentData = analyzeContent(
book, item.nextUrl, it, contentRule, bookChapter, bookSource, false
)

@ -46,7 +46,7 @@ class WebBook(val bookSource: BookSource) {
headerMapF = bookSource.getHeaderMap(),
book = variableBook
)
val res = analyzeUrl.getResponseAwait(bookSource.bookSourceUrl)
val res = analyzeUrl.getRes(bookSource.bookSourceUrl)
return BookList.analyzeBookList(
scope,
res.body,
@ -77,7 +77,7 @@ class WebBook(val bookSource: BookSource) {
baseUrl = sourceUrl,
headerMapF = bookSource.getHeaderMap()
)
val res = analyzeUrl.getResponseAwait(bookSource.bookSourceUrl)
val res = analyzeUrl.getRes(bookSource.bookSourceUrl)
BookList.analyzeBookList(
scope,
res.body,
@ -110,7 +110,7 @@ class WebBook(val bookSource: BookSource) {
baseUrl = sourceUrl,
headerMapF = bookSource.getHeaderMap(),
book = book
).getResponseAwait(bookSource.bookSourceUrl)
).getRes(bookSource.bookSourceUrl)
BookInfo.analyzeBookInfo(book, res.body, bookSource, book.bookUrl, canReName)
}
book
@ -141,7 +141,7 @@ class WebBook(val bookSource: BookSource) {
ruleUrl = book.tocUrl,
baseUrl = book.bookUrl,
headerMapF = bookSource.getHeaderMap()
).getResponseAwait(bookSource.bookSourceUrl)
).getRes(bookSource.bookSourceUrl)
BookChapterList.analyzeChapterList(
this,
book,
@ -201,7 +201,7 @@ class WebBook(val bookSource: BookSource) {
headerMapF = bookSource.getHeaderMap(),
book = book,
chapter = bookChapter
).getResponseAwait(
).getRes(
bookSource.bookSourceUrl,
jsStr = bookSource.getContentRule().webJs,
sourceRegex = bookSource.getContentRule().sourceRegex

@ -76,7 +76,7 @@ class HttpReadAloudService : BaseReadAloudService(),
it.url,
speakText = contentList[index],
speakSpeed = AppConfig.ttsSpeechRate
).getResponseBytes()?.let { bytes ->
).getByteArray().let { bytes ->
if (isActive) {
val file = getSpeakFile(index)
file.writeBytes(bytes)

@ -11,10 +11,11 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppConfig
import io.legado.app.help.SourceHelp
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.OldRule
import io.legado.app.help.storage.Restore
import io.legado.app.utils.*
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toText
import java.io.File
class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
@ -119,7 +120,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
}
private suspend fun importSourceUrl(url: String) {
HttpHelper.simpleGetAsync(url).let { body ->
RxHttp.get(url).toText("utf-8").await().let { body ->
val items: List<Map<String, Any>> = Restore.jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)

@ -7,11 +7,12 @@ import androidx.lifecycle.MutableLiveData
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.OldReplace
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.readText
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toText
import java.io.File
class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
@ -48,7 +49,7 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
fun import(text: String) {
execute {
if (text.isAbsUrl()) {
HttpHelper.simpleGetAsync(text).let {
RxHttp.get(text).toText("utf-8").await().let {
val rules = OldReplace.jsonToReplaceRules(it)
allRules.addAll(rules)
}

@ -11,9 +11,10 @@ import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssSource
import io.legado.app.help.AppConfig
import io.legado.app.help.SourceHelp
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore
import io.legado.app.utils.*
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toText
import java.io.File
class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
@ -114,7 +115,7 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
}
private suspend fun importSourceUrl(url: String) {
HttpHelper.simpleGetAsync(url).let { body ->
RxHttp.get(url).toText("utf-8").await().let { body ->
val items: List<Map<String, Any>> = Restore.jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)

@ -17,7 +17,6 @@ import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogReadBgTextBinding
import io.legado.app.databinding.ItemBgImageBinding
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.permission.Permissions
import io.legado.app.help.permission.PermissionsCompat
import io.legado.app.lib.dialogs.alert
@ -31,6 +30,8 @@ import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
import org.jetbrains.anko.sdk27.listeners.onCheckedChange
import org.jetbrains.anko.sdk27.listeners.onClick
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toByteArray
import java.io.File
class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
@ -286,9 +287,9 @@ class BgTextConfigDialog : BaseDialogFragment(), FilePickerDialog.CallBack {
private fun importNetConfig(url: String) {
execute {
HttpHelper.simpleGetBytesAsync(url)?.let {
RxHttp.get(url).toByteArray().await()?.let {
importConfig(it)
} ?: throw Exception("获取失败")
}
}.onError {
longToast(it.msg)
}

@ -5,9 +5,10 @@ import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.HttpTTS
import io.legado.app.help.DefaultData
import io.legado.app.help.http.HttpHelper
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toText
class SpeakEngineViewModel(application: Application) : BaseViewModel(application) {
@ -21,7 +22,7 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application
fun importOnLine(url: String, finally: (msg: String) -> Unit) {
execute {
HttpHelper.simpleGetAsync(url).let { json ->
RxHttp.get(url).toText("utf-8").await().let { json ->
GSON.fromJsonArray<HttpTTS>(json)?.let {
App.db.httpTTSDao.insert(*it.toTypedArray())
}

@ -5,9 +5,10 @@ import io.legado.app.App
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultData
import io.legado.app.help.http.HttpHelper
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toText
class TocRegexViewModel(application: Application) : BaseViewModel(application) {
@ -28,7 +29,7 @@ class TocRegexViewModel(application: Application) : BaseViewModel(application) {
fun importOnLine(url: String, finally: (msg: String) -> Unit) {
execute {
HttpHelper.simpleGetAsync(url).let { json ->
RxHttp.get(url).toText("utf-8").await().let { json ->
GSON.fromJsonArray<TxtTocRule>(json)?.let {
App.db.txtTocRule.insert(*it.toTypedArray())
}

@ -16,7 +16,6 @@ import io.legado.app.constant.AppConst
import io.legado.app.data.entities.RssArticle
import io.legado.app.data.entities.RssSource
import io.legado.app.data.entities.RssStar
import io.legado.app.help.http.HttpHelper
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.rss.Rss
import io.legado.app.utils.DocumentUtils
@ -25,6 +24,8 @@ import io.legado.app.utils.isContentScheme
import io.legado.app.utils.writeBytes
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import rxhttp.wrapper.param.RxHttp
import rxhttp.wrapper.param.toByteArray
import java.io.File
import java.util.*
@ -131,7 +132,7 @@ class ReadRssViewModel(application: Application) : BaseViewModel(application),
private suspend fun webData2bitmap(data: String): ByteArray? {
return if (URLUtil.isValidUrl(data)) {
HttpHelper.simpleGetBytesAsync(data)
RxHttp.get(data).toByteArray().await()
} else {
Base64.decode(data.split(",").toTypedArray()[1], Base64.DEFAULT)
}

Loading…
Cancel
Save