导入书源直接解析流,防止书源太大报错

pull/1751/head
kunfei 3 years ago
parent 0ab23d5f03
commit fdb563d35d
  1. 5
      app/src/main/java/io/legado/app/data/entities/BookSource.kt
  2. 29
      app/src/main/java/io/legado/app/help/SourceAnalyzer.kt
  3. 6
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  4. 23
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  5. 16
      app/src/main/java/io/legado/app/utils/GsonExtensions.kt

@ -11,6 +11,7 @@ import io.legado.app.utils.*
import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import splitties.init.appCtx import splitties.init.appCtx
import java.io.InputStream
@Parcelize @Parcelize
@TypeConverters(BookSource.Converters::class) @TypeConverters(BookSource.Converters::class)
@ -210,6 +211,10 @@ data class BookSource(
fun fromJsonArray(json: String): List<BookSource> { fun fromJsonArray(json: String): List<BookSource> {
return SourceAnalyzer.jsonToBookSources(json) return SourceAnalyzer.jsonToBookSources(json)
} }
fun fromJsonArray(inputStream: InputStream): Result<MutableList<BookSource>> {
return SourceAnalyzer.jsonToBookSources(inputStream)
}
} }
class Converters { class Converters {

@ -8,6 +8,7 @@ import io.legado.app.constant.BookType
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.* import io.legado.app.data.entities.rule.*
import io.legado.app.utils.* import io.legado.app.utils.*
import java.io.InputStream
import java.util.regex.Pattern import java.util.regex.Pattern
@ -18,16 +19,36 @@ object SourceAnalyzer {
fun jsonToBookSources(json: String): List<BookSource> { fun jsonToBookSources(json: String): List<BookSource> {
val bookSources = mutableListOf<BookSource>() val bookSources = mutableListOf<BookSource>()
if (json.isJsonArray()) { val items: List<Map<String, Any>> = jsonPath.parse(json).read("$")
val items: List<Map<String, Any>> = jsonPath.parse(json).read("$") for (item in items) {
for (item in items) { val jsonItem = jsonPath.parse(item)
jsonToBookSource(jsonItem.jsonString())?.let {
bookSources.add(it)
}
}
return bookSources
}
fun jsonToBookSources(inputStream: InputStream): Result<MutableList<BookSource>> {
return kotlin.runCatching {
val bookSources = mutableListOf<BookSource>()
kotlin.runCatching {
val items: List<Map<String, Any>> = jsonPath.parse(inputStream).read("$")
for (item in items) {
val jsonItem = jsonPath.parse(item)
jsonToBookSource(jsonItem.jsonString())?.let {
bookSources.add(it)
}
}
}.onFailure {
val item: Map<String, Any> = jsonPath.parse(inputStream).read("$")
val jsonItem = jsonPath.parse(item) val jsonItem = jsonPath.parse(item)
jsonToBookSource(jsonItem.jsonString())?.let { jsonToBookSource(jsonItem.jsonString())?.let {
bookSources.add(it) bookSources.add(it)
} }
} }
bookSources
} }
return bookSources
} }
fun jsonToBookSource(json: String): BookSource? { fun jsonToBookSource(json: String): BookSource? {

@ -22,6 +22,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.io.FileInputStream
object Restore { object Restore {
@ -192,8 +193,9 @@ object Restore {
private inline fun <reified T> fileToListT(path: String, fileName: String): List<T>? { private inline fun <reified T> fileToListT(path: String, fileName: String): List<T>? {
try { try {
val file = FileUtils.createFileIfNotExist(path + File.separator + fileName) val file = FileUtils.createFileIfNotExist(path + File.separator + fileName)
val json = file.readText() FileInputStream(file).use {
return GSON.fromJsonArray<T>(json).getOrThrow() return GSON.fromJsonArray<T>(it).getOrThrow()
}
} catch (e: Exception) { } catch (e: Exception) {
AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e) AppLog.put("$fileName\n读取解析出错\n${e.localizedMessage}", e)
appCtx.toastOnUi("$fileName\n读取文件出错\n${e.localizedMessage}") appCtx.toastOnUi("$fileName\n读取文件出错\n${e.localizedMessage}")

@ -14,7 +14,6 @@ import io.legado.app.help.SourceHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.http.newCallResponseBody import io.legado.app.help.http.newCallResponseBody
import io.legado.app.help.http.okHttpClient import io.legado.app.help.http.okHttpClient
import io.legado.app.help.http.text
import io.legado.app.utils.* import io.legado.app.utils.*
@ -123,26 +122,8 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
private suspend fun importSourceUrl(url: String) { private suspend fun importSourceUrl(url: String) {
okHttpClient.newCallResponseBody { okHttpClient.newCallResponseBody {
url(url) url(url)
}.text("utf-8").let { body -> }.byteStream().let {
when { allSources.addAll(BookSource.fromJsonArray(it).getOrThrow())
body.isJsonArray() -> {
val items: List<Map<String, Any>> = 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))
}
}
} }
} }

@ -4,6 +4,8 @@ import com.google.gson.*
import com.google.gson.internal.LinkedTreeMap import com.google.gson.internal.LinkedTreeMap
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.google.gson.stream.JsonWriter import com.google.gson.stream.JsonWriter
import java.io.InputStream
import java.io.InputStreamReader
import java.io.OutputStream import java.io.OutputStream
import java.io.OutputStreamWriter import java.io.OutputStreamWriter
import java.lang.reflect.ParameterizedType import java.lang.reflect.ParameterizedType
@ -37,6 +39,20 @@ inline fun <reified T> Gson.fromJsonArray(json: String?): Result<List<T>?> {
} }
} }
inline fun <reified T> Gson.fromJsonObject(inputStream: InputStream?): Result<T?> {
return kotlin.runCatching {
val reader = InputStreamReader(inputStream)
fromJson(reader, genericType<T>()) as? T
}
}
inline fun <reified T> Gson.fromJsonArray(inputStream: InputStream?): Result<List<T>?> {
return kotlin.runCatching {
val reader = InputStreamReader(inputStream)
fromJson(reader, ParameterizedTypeImpl(T::class.java)) as? List<T>
}
}
fun Gson.writeToOutputStream(out: OutputStream, any: Any) { fun Gson.writeToOutputStream(out: OutputStream, any: Any) {
val writer = JsonWriter(OutputStreamWriter(out, "UTF-8")) val writer = JsonWriter(OutputStreamWriter(out, "UTF-8"))
writer.setIndent(" ") writer.setIndent(" ")

Loading…
Cancel
Save