diff --git a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt index b4ead2bb5..5f893b411 100644 --- a/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt +++ b/app/src/main/java/io/legado/app/help/http/OkHttpUtils.kt @@ -16,9 +16,11 @@ import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import okhttp3.ResponseBody +import okhttp3.internal.http.RealResponseBody +import okio.buffer +import okio.source import java.io.File import java.io.IOException -import java.io.InputStream import java.nio.charset.Charset import java.util.zip.ZipInputStream import kotlin.coroutines.resume @@ -77,36 +79,37 @@ suspend fun Call.await(): Response = suspendCancellableCoroutine { block -> } fun ResponseBody.text(encode: String? = null): String { - return unCompress { - val responseBytes = Utf8BomUtils.removeUTF8BOM(it.readBytes()) - var charsetName: String? = encode + val responseBytes = Utf8BomUtils.removeUTF8BOM(bytes()) + var charsetName: String? = encode - charsetName?.let { - return@unCompress String(responseBytes, Charset.forName(charsetName)) - } - - //根据http头判断 - contentType()?.charset()?.let { charset -> - return@unCompress String(responseBytes, charset) - } - - //根据内容判断 - charsetName = EncodingDetect.getHtmlEncode(responseBytes) - return@unCompress String(responseBytes, Charset.forName(charsetName)) + charsetName?.let { + return String(responseBytes, Charset.forName(charsetName)) } + + //根据http头判断 + contentType()?.charset()?.let { charset -> + return String(responseBytes, charset) + } + + //根据内容判断 + charsetName = EncodingDetect.getHtmlEncode(responseBytes) + return String(responseBytes, Charset.forName(charsetName)) } -fun ResponseBody.unCompress(success: (inputStream: InputStream) -> T): T { - return if (contentType() == "application/zip".toMediaType()) { - byteStream().use { byteStream -> - ZipInputStream(byteStream).use { - it.nextEntry - success.invoke(it) - } - } - } else { - byteStream().use(success) +fun ResponseBody.decompressed(): ResponseBody { + val contentType = contentType()?.toString() + if (contentType != "application/zip") { + return this } + val source = ZipInputStream(byteStream()).apply { + try { + nextEntry + } catch (e: Exception) { + close() + throw e + } + }.source().buffer() + return RealResponseBody(contentType, contentLength(), source) } fun Request.Builder.addHeaders(headers: Map) { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt index 9eaa513cc..350123e10 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt @@ -15,9 +15,9 @@ import io.legado.app.data.entities.BookSourcePart import io.legado.app.exception.NoStackTraceException import io.legado.app.help.book.ContentProcessor import io.legado.app.help.config.AppConfig +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient -import io.legado.app.help.http.unCompress import io.legado.app.help.source.SourceHelp import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray @@ -194,7 +194,7 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.unCompress { + }.decompressed().byteStream().use { GSON.fromJsonArray(it).getOrThrow().let { list -> val source = list.firstOrNull() ?: return@let if (source.bookSourceUrl.isEmpty()) { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt index b2ba12553..5dfd9fc74 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportDictRuleViewModel.kt @@ -9,10 +9,16 @@ import io.legado.app.constant.AppLog import io.legado.app.data.appDb import io.legado.app.data.entities.DictRule import io.legado.app.exception.NoStackTraceException +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text -import io.legado.app.utils.* +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.isAbsUrl +import io.legado.app.utils.isJsonArray +import io.legado.app.utils.isJsonObject class ImportDictRuleViewModel(app: Application) : BaseViewModel(app) { @@ -94,7 +100,7 @@ class ImportDictRuleViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.text().let { + }.decompressed().text().let { importSourceAwait(it) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt index a68bd8376..38a5971b4 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportHttpTtsViewModel.kt @@ -9,6 +9,7 @@ import io.legado.app.constant.AppLog import io.legado.app.data.appDb import io.legado.app.data.entities.HttpTTS import io.legado.app.exception.NoStackTraceException +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text @@ -96,7 +97,7 @@ class ImportHttpTtsViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.text().let { + }.decompressed().text().let { importSourceAwait(it) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt index 0902bab7a..e8a149f5c 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt @@ -10,6 +10,7 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.ReplaceRule import io.legado.app.exception.NoStackTraceException import io.legado.app.help.ReplaceAnalyzer +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text @@ -95,10 +96,12 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) { val rules = ReplaceAnalyzer.jsonToReplaceRules(text).getOrThrow() allRules.addAll(rules) } + text.isJsonObject() -> { val rule = ReplaceAnalyzer.jsonToReplaceRule(text).getOrThrow() allRules.add(rule) } + else -> throw NoStackTraceException("格式不对") } } @@ -111,7 +114,7 @@ class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.text("utf-8").let { + }.decompressed().text("utf-8").let { importAwait(it) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt index c3dce969a..e62b2fd14 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt @@ -12,9 +12,9 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.RssSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.config.AppConfig +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient -import io.legado.app.help.http.unCompress import io.legado.app.help.source.SourceHelp import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray @@ -153,7 +153,7 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.unCompress { body -> + }.decompressed().byteStream().use { body -> val items: List> = jsonPath.parse(body).read("$") for (item in items) { if (!item.containsKey("sourceUrl")) { diff --git a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt index f7fa14827..06d802a52 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportThemeViewModel.kt @@ -8,6 +8,7 @@ import io.legado.app.constant.AppConst import io.legado.app.constant.AppLog import io.legado.app.exception.NoStackTraceException import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text @@ -92,7 +93,7 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.text().let { + }.decompressed().text().let { importSourceAwait(it) } } diff --git a/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt index d2ff9ae56..c83cb8f4e 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportTxtTocRuleViewModel.kt @@ -9,10 +9,16 @@ import io.legado.app.constant.AppLog import io.legado.app.data.appDb import io.legado.app.data.entities.TxtTocRule import io.legado.app.exception.NoStackTraceException +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text -import io.legado.app.utils.* +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray +import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.isAbsUrl +import io.legado.app.utils.isJsonArray +import io.legado.app.utils.isJsonObject class ImportTxtTocRuleViewModel(app: Application) : BaseViewModel(app) { @@ -95,7 +101,7 @@ class ImportTxtTocRuleViewModel(app: Application) : BaseViewModel(app) { } else { url(url) } - }.text().let { + }.decompressed().text().let { importSourceAwait(it) } } diff --git a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt index 28c5bcdaf..d6f949280 100644 --- a/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/association/OnLineImportViewModel.kt @@ -5,6 +5,7 @@ import androidx.core.net.toUri import io.legado.app.R import io.legado.app.constant.AppConst import io.legado.app.help.config.ReadBookConfig +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text @@ -24,7 +25,7 @@ class OnLineImportViewModel(app: Application) : BaseAssociationViewModel(app) { } else { url(url) } - }.text("utf-8") + }.decompressed().text("utf-8") }.onSuccess { success.invoke(it) }.onError { diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt index 2dfe91631..a43195b49 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt @@ -8,9 +8,6 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.HttpTTS import io.legado.app.exception.NoStackTraceException import io.legado.app.help.DefaultData -import io.legado.app.help.http.newCallResponseBody -import io.legado.app.help.http.okHttpClient -import io.legado.app.help.http.text import io.legado.app.utils.isJsonArray import io.legado.app.utils.isJsonObject import io.legado.app.utils.readText @@ -31,20 +28,6 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application } } - fun importOnLine(url: String) { - execute { - okHttpClient.newCallResponseBody { - url(url) - }.text("utf-8").let { json -> - import(json) - } - }.onSuccess { - context.toastOnUi("导入成功") - }.onError { - context.toastOnUi("导入失败") - } - } - fun importLocal(uri: Uri) { execute { import(uri.readText(context)) @@ -62,11 +45,13 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application appDb.httpTTSDao.insert(*it.toTypedArray()) } } + text.isJsonObject() -> { HttpTTS.fromJson(text).getOrThrow().let { appDb.httpTTSDao.insert(it) } } + else -> { throw NoStackTraceException("格式不对") } diff --git a/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt b/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt index c4fa6d6b3..fd3597fde 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/rule/TxtTocRuleViewModel.kt @@ -5,11 +5,6 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.TxtTocRule import io.legado.app.help.DefaultData -import io.legado.app.help.http.newCallResponseBody -import io.legado.app.help.http.okHttpClient -import io.legado.app.help.http.text -import io.legado.app.utils.GSON -import io.legado.app.utils.fromJsonArray class TxtTocRuleViewModel(app: Application) : BaseViewModel(app) { @@ -37,22 +32,6 @@ class TxtTocRuleViewModel(app: Application) : BaseViewModel(app) { } } - fun importOnLine(url: String, finally: (msg: String) -> Unit) { - execute { - okHttpClient.newCallResponseBody { - url(url) - }.text("utf-8").let { json -> - GSON.fromJsonArray(json).getOrThrow().let { - appDb.txtTocRuleDao.insert(*it.toTypedArray()) - } - } - }.onSuccess { - finally("导入成功") - }.onError { - finally("导入失败\n${it.localizedMessage}") - } - } - fun toTop(vararg rules: TxtTocRule) { execute { val minOrder = appDb.txtTocRuleDao.minOrder - 1 diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index c1f2b6a29..4b40d9623 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -11,6 +11,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSourcePart import io.legado.app.exception.NoStackTraceException import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.http.decompressed import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.text @@ -132,7 +133,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application) text.isAbsUrl() -> { okHttpClient.newCallResponseBody { url(text) - }.text().let { + }.decompressed().text().let { importBookshelf(it, groupId) } }