diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index 226830295..d29f868ee 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -11,6 +11,7 @@ import io.legado.app.utils.* import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import splitties.init.appCtx +import java.io.InputStream @Parcelize @TypeConverters(BookSource.Converters::class) @@ -210,6 +211,10 @@ data class BookSource( fun fromJsonArray(json: String): List { return SourceAnalyzer.jsonToBookSources(json) } + + fun fromJsonArray(inputStream: InputStream): Result> { + return SourceAnalyzer.jsonToBookSources(inputStream) + } } class Converters { diff --git a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt b/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt index 4db179cf6..da9682b9f 100644 --- a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt +++ b/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt @@ -8,6 +8,7 @@ import io.legado.app.constant.BookType import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.* import io.legado.app.utils.* +import java.io.InputStream import java.util.regex.Pattern @@ -18,16 +19,36 @@ object SourceAnalyzer { fun jsonToBookSources(json: String): List { val bookSources = mutableListOf() - if (json.isJsonArray()) { - val items: List> = jsonPath.parse(json).read("$") - for (item in items) { + val items: List> = jsonPath.parse(json).read("$") + for (item in items) { + val jsonItem = jsonPath.parse(item) + jsonToBookSource(jsonItem.jsonString())?.let { + bookSources.add(it) + } + } + return bookSources + } + + fun jsonToBookSources(inputStream: InputStream): Result> { + return kotlin.runCatching { + val bookSources = mutableListOf() + kotlin.runCatching { + val items: List> = jsonPath.parse(inputStream).read("$") + for (item in items) { + val jsonItem = jsonPath.parse(item) + jsonToBookSource(jsonItem.jsonString())?.let { + bookSources.add(it) + } + } + }.onFailure { + val item: Map = jsonPath.parse(inputStream).read("$") val jsonItem = jsonPath.parse(item) jsonToBookSource(jsonItem.jsonString())?.let { bookSources.add(it) } } + bookSources } - return bookSources } fun jsonToBookSource(json: String): BookSource? { diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index af7660d25..884cb923b 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.withContext import splitties.init.appCtx import java.io.File +import java.io.FileInputStream object Restore { @@ -192,8 +193,9 @@ object Restore { private inline fun fileToListT(path: String, fileName: String): List? { try { val file = FileUtils.createFileIfNotExist(path + File.separator + fileName) - val json = file.readText() - return GSON.fromJsonArray(json).getOrThrow() + FileInputStream(file).use { + return GSON.fromJsonArray(it).getOrThrow() + } } catch (e: Exception) { AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e) appCtx.toastOnUi("$fileName\n读取文件出错\n${e.localizedMessage}") 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 6d1a97dde..5ccb368b2 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 @@ -14,7 +14,6 @@ import io.legado.app.help.SourceHelp import io.legado.app.help.config.AppConfig 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.* @@ -123,26 +122,8 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) { private suspend fun importSourceUrl(url: String) { okHttpClient.newCallResponseBody { url(url) - }.text("utf-8").let { body -> - when { - body.isJsonArray() -> { - val items: List> = jsonPath.parse(body).read("$") - for (item in items) { - val jsonItem = jsonPath.parse(item) - BookSource.fromJson(jsonItem.jsonString())?.let { source -> - allSources.add(source) - } - } - } - body.isJsonObject() -> { - BookSource.fromJson(body)?.let { - allSources.add(it) - } - } - else -> { - throw NoStackTraceException(context.getString(R.string.wrong_format)) - } - } + }.byteStream().let { + allSources.addAll(BookSource.fromJsonArray(it).getOrThrow()) } } diff --git a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt index 443b95560..9329613e3 100644 --- a/app/src/main/java/io/legado/app/utils/GsonExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/GsonExtensions.kt @@ -4,6 +4,8 @@ import com.google.gson.* import com.google.gson.internal.LinkedTreeMap import com.google.gson.reflect.TypeToken import com.google.gson.stream.JsonWriter +import java.io.InputStream +import java.io.InputStreamReader import java.io.OutputStream import java.io.OutputStreamWriter import java.lang.reflect.ParameterizedType @@ -37,6 +39,20 @@ inline fun Gson.fromJsonArray(json: String?): Result?> { } } +inline fun Gson.fromJsonObject(inputStream: InputStream?): Result { + return kotlin.runCatching { + val reader = InputStreamReader(inputStream) + fromJson(reader, genericType()) as? T + } +} + +inline fun Gson.fromJsonArray(inputStream: InputStream?): Result?> { + return kotlin.runCatching { + val reader = InputStreamReader(inputStream) + fromJson(reader, ParameterizedTypeImpl(T::class.java)) as? List + } +} + fun Gson.writeToOutputStream(out: OutputStream, any: Any) { val writer = JsonWriter(OutputStreamWriter(out, "UTF-8")) writer.setIndent(" ")