优化
This commit is contained in:
@@ -68,7 +68,7 @@ object BookSourceController {
|
|||||||
|
|
||||||
fun deleteSources(postData: String?): ReturnData {
|
fun deleteSources(postData: String?): ReturnData {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
GSON.fromJsonArray<BookSource>(postData).getOrThrow()?.let {
|
GSON.fromJsonArray<BookSource>(postData).getOrThrow().let {
|
||||||
it.forEach { source ->
|
it.forEach { source ->
|
||||||
appDb.bookSourceDao.delete(source)
|
appDb.bookSourceDao.delete(source)
|
||||||
SourceConfig.removeSource(source.bookSourceUrl)
|
SourceConfig.removeSource(source.bookSourceUrl)
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ package io.legado.app.data.entities
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.room.*
|
import androidx.room.*
|
||||||
import com.jayway.jsonpath.DocumentContext
|
import com.google.gson.JsonDeserializationContext
|
||||||
|
import com.google.gson.JsonDeserializer
|
||||||
|
import com.google.gson.JsonElement
|
||||||
import io.legado.app.constant.AppPattern
|
import io.legado.app.constant.AppPattern
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.*
|
||||||
import kotlinx.parcelize.Parcelize
|
import kotlinx.parcelize.Parcelize
|
||||||
|
import java.lang.reflect.Type
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@Entity(tableName = "rssSources", indices = [(Index(value = ["sourceUrl"], unique = false))])
|
@Entity(tableName = "rssSources", indices = [(Index(value = ["sourceUrl"], unique = false))])
|
||||||
@@ -171,65 +174,35 @@ data class RssSource(
|
|||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
companion object {
|
companion object {
|
||||||
|
private val gson by lazy {
|
||||||
fun fromJsonDoc(doc: DocumentContext): Result<RssSource> {
|
GSON.newBuilder()
|
||||||
return kotlin.runCatching {
|
.registerTypeAdapter(String::class.java, RssJsonDeserializer())
|
||||||
val loginUi = doc.read<Any>("$.loginUi")
|
.create()
|
||||||
RssSource(
|
|
||||||
sourceUrl = doc.readString("$.sourceUrl")!!,
|
|
||||||
sourceName = doc.readString("$.sourceName")!!,
|
|
||||||
sourceIcon = doc.readString("$.sourceIcon") ?: "",
|
|
||||||
sourceGroup = doc.readString("$.sourceGroup"),
|
|
||||||
sourceComment = doc.readString("$.sourceComment"),
|
|
||||||
enabled = doc.readBool("$.enabled") ?: true,
|
|
||||||
concurrentRate = doc.readString("$.concurrentRate"),
|
|
||||||
header = doc.readString("$.header"),
|
|
||||||
loginUrl = doc.readString("$.loginUrl"),
|
|
||||||
loginUi = if (loginUi is List<*>) GSON.toJson(loginUi) else loginUi?.toString(),
|
|
||||||
loginCheckJs = doc.readString("$.loginCheckJs"),
|
|
||||||
sortUrl = doc.readString("$.sortUrl"),
|
|
||||||
singleUrl = doc.readBool("$.singleUrl") ?: false,
|
|
||||||
articleStyle = doc.readInt("$.articleStyle") ?: 0,
|
|
||||||
ruleArticles = doc.readString("$.ruleArticles"),
|
|
||||||
ruleNextPage = doc.readString("$.ruleNextPage"),
|
|
||||||
ruleTitle = doc.readString("$.ruleTitle"),
|
|
||||||
rulePubDate = doc.readString("$.rulePubDate"),
|
|
||||||
ruleDescription = doc.readString("$.ruleDescription"),
|
|
||||||
ruleImage = doc.readString("$.ruleImage"),
|
|
||||||
ruleLink = doc.readString("$.ruleLink"),
|
|
||||||
ruleContent = doc.readString("$.ruleContent"),
|
|
||||||
style = doc.readString("$.style"),
|
|
||||||
injectJs = doc.readString("$.injectJs"),
|
|
||||||
enableJs = doc.readBool("$.enableJs") ?: true,
|
|
||||||
loadWithBaseUrl = doc.readBool("$.loadWithBaseUrl") ?: true,
|
|
||||||
enabledCookieJar = doc.readBool("$.enabledCookieJar") ?: false,
|
|
||||||
customOrder = doc.readInt("$.customOrder") ?: 0,
|
|
||||||
lastUpdateTime = doc.readLong("$.lastUpdateTime") ?: 0L,
|
|
||||||
coverDecodeJs = doc.readString("$.coverDecodeJs"),
|
|
||||||
variableComment = doc.readString("$.variableComment"),
|
|
||||||
contentBlacklist = doc.readString("$.contentBlacklist"),
|
|
||||||
contentWhitelist = doc.readString("$.contentWhitelist")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fromJson(json: String): Result<RssSource> {
|
fun fromJson(json: String): Result<RssSource> {
|
||||||
return fromJsonDoc(jsonPath.parse(json))
|
return gson.fromJsonObject(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun fromJsonArray(jsonArray: String): Result<ArrayList<RssSource>> {
|
fun fromJsonArray(jsonArray: String): Result<List<RssSource>> {
|
||||||
return kotlin.runCatching {
|
return gson.fromJsonArray(jsonArray)
|
||||||
val sources = arrayListOf<RssSource>()
|
|
||||||
val doc = jsonPath.parse(jsonArray).read<List<*>>("$")
|
|
||||||
doc.forEach {
|
|
||||||
val jsonItem = jsonPath.parse(it)
|
|
||||||
fromJsonDoc(jsonItem).getOrThrow().let { source ->
|
|
||||||
sources.add(source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sources
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RssJsonDeserializer : JsonDeserializer<String?> {
|
||||||
|
|
||||||
|
override fun deserialize(
|
||||||
|
json: JsonElement,
|
||||||
|
typeOfT: Type?,
|
||||||
|
context: JsonDeserializationContext?
|
||||||
|
): String? {
|
||||||
|
return when {
|
||||||
|
json.isJsonPrimitive -> json.asString
|
||||||
|
json.isJsonNull -> null
|
||||||
|
else -> json.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ object DefaultData {
|
|||||||
appCtx.assets.open("defaultData${File.separator}coverRule.json")
|
appCtx.assets.open("defaultData${File.separator}coverRule.json")
|
||||||
.readBytes()
|
.readBytes()
|
||||||
)
|
)
|
||||||
GSON.fromJsonObject<BookCover.CoverRule>(json).getOrThrow()!!
|
GSON.fromJsonObject<BookCover.CoverRule>(json).getOrThrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
val dictRules: List<DictRule> by lazy {
|
val dictRules: List<DictRule> by lazy {
|
||||||
@@ -95,7 +95,7 @@ object DefaultData {
|
|||||||
appCtx.assets.open("defaultData${File.separator}dictRules.json")
|
appCtx.assets.open("defaultData${File.separator}dictRules.json")
|
||||||
.readBytes()
|
.readBytes()
|
||||||
)
|
)
|
||||||
GSON.fromJsonArray<DictRule>(json).getOrThrow()!!
|
GSON.fromJsonArray<DictRule>(json).getOrThrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
val keyboardAssists: List<KeyboardAssist> by lazy {
|
val keyboardAssists: List<KeyboardAssist> by lazy {
|
||||||
@@ -103,7 +103,7 @@ object DefaultData {
|
|||||||
appCtx.assets.open("defaultData${File.separator}keyboardAssists.json")
|
appCtx.assets.open("defaultData${File.separator}keyboardAssists.json")
|
||||||
.readBytes()
|
.readBytes()
|
||||||
)
|
)
|
||||||
GSON.fromJsonArray<KeyboardAssist>(json).getOrNull()!!
|
GSON.fromJsonArray<KeyboardAssist>(json).getOrThrow()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun importDefaultHttpTTS() {
|
fun importDefaultHttpTTS() {
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ suspend fun BookSource.exploreKinds(): List<ExploreKind> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ruleStr.isJsonArray()) {
|
if (ruleStr.isJsonArray()) {
|
||||||
GSON.fromJsonArray<ExploreKind?>(ruleStr).getOrThrow()?.let {
|
GSON.fromJsonArray<ExploreKind?>(ruleStr).getOrThrow().let {
|
||||||
kinds.addAll(it.filterNotNull())
|
kinds.addAll(it.filterNotNull())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ object LocalBook {
|
|||||||
SimpleBindings().also { it["src"] = tempFileName }
|
SimpleBindings().also { it["src"] = tempFileName }
|
||||||
).toString()
|
).toString()
|
||||||
val bookMess = GSON.fromJsonObject<HashMap<String, String>>(jsonStr)
|
val bookMess = GSON.fromJsonObject<HashMap<String, String>>(jsonStr)
|
||||||
.getOrThrow() ?: HashMap()
|
.getOrThrow()
|
||||||
name = bookMess["name"] ?: tempFileName
|
name = bookMess["name"] ?: tempFileName
|
||||||
author = bookMess["author"]?.takeIf { it.length != tempFileName.length } ?: ""
|
author = bookMess["author"]?.takeIf { it.length != tempFileName.length } ?: ""
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
|||||||
@@ -71,11 +71,11 @@ class ImportDictRuleViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
private suspend fun importSourceAwait(text: String) {
|
private suspend fun importSourceAwait(text: String) {
|
||||||
when {
|
when {
|
||||||
text.isJsonObject() -> {
|
text.isJsonObject() -> {
|
||||||
GSON.fromJsonObject<DictRule>(text).getOrThrow()?.let {
|
GSON.fromJsonObject<DictRule>(text).getOrThrow().let {
|
||||||
allSources.add(it)
|
allSources.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text.isJsonArray() -> GSON.fromJsonArray<DictRule>(text).getOrThrow()?.let { items ->
|
text.isJsonArray() -> GSON.fromJsonArray<DictRule>(text).getOrThrow().let { items ->
|
||||||
allSources.addAll(items)
|
allSources.addAll(items)
|
||||||
}
|
}
|
||||||
text.isAbsUrl() -> {
|
text.isAbsUrl() -> {
|
||||||
|
|||||||
@@ -104,12 +104,8 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mText.isJsonArray() -> {
|
mText.isJsonArray() -> {
|
||||||
val items: List<Map<String, Any>> = jsonPath.parse(mText).read("$")
|
RssSource.fromJsonArray(mText).getOrThrow().let {
|
||||||
for (item in items) {
|
allSources.addAll(it)
|
||||||
val jsonItem = jsonPath.parse(item)
|
|
||||||
RssSource.fromJsonDoc(jsonItem).getOrThrow().let {
|
|
||||||
allSources.add(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mText.isAbsUrl() -> {
|
mText.isAbsUrl() -> {
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ class ImportThemeViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
private suspend fun importSourceAwait(text: String) {
|
private suspend fun importSourceAwait(text: String) {
|
||||||
when {
|
when {
|
||||||
text.isJsonObject() -> {
|
text.isJsonObject() -> {
|
||||||
GSON.fromJsonObject<ThemeConfig.Config>(text).getOrThrow()?.let {
|
GSON.fromJsonObject<ThemeConfig.Config>(text).getOrThrow().let {
|
||||||
allSources.add(it)
|
allSources.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text.isJsonArray() -> GSON.fromJsonArray<ThemeConfig.Config>(text).getOrThrow()
|
text.isJsonArray() -> GSON.fromJsonArray<ThemeConfig.Config>(text).getOrThrow()
|
||||||
?.let { items ->
|
.let { items ->
|
||||||
allSources.addAll(items)
|
allSources.addAll(items)
|
||||||
}
|
}
|
||||||
text.isAbsUrl() -> {
|
text.isAbsUrl() -> {
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ class ImportTxtTocRuleViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
private suspend fun importSourceAwait(text: String) {
|
private suspend fun importSourceAwait(text: String) {
|
||||||
when {
|
when {
|
||||||
text.isJsonObject() -> {
|
text.isJsonObject() -> {
|
||||||
GSON.fromJsonObject<TxtTocRule>(text).getOrThrow()?.let {
|
GSON.fromJsonObject<TxtTocRule>(text).getOrThrow().let {
|
||||||
allSources.add(it)
|
allSources.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
text.isJsonArray() -> GSON.fromJsonArray<TxtTocRule>(text).getOrThrow()
|
text.isJsonArray() -> GSON.fromJsonArray<TxtTocRule>(text).getOrThrow()
|
||||||
?.let { items ->
|
.let { items ->
|
||||||
allSources.addAll(items)
|
allSources.addAll(items)
|
||||||
}
|
}
|
||||||
text.isAbsUrl() -> {
|
text.isAbsUrl() -> {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package io.legado.app.ui.book.toc.rule
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import io.legado.app.base.BaseViewModel
|
import io.legado.app.base.BaseViewModel
|
||||||
import io.legado.app.data.appDb
|
import io.legado.app.data.appDb
|
||||||
import io.legado.app.data.entities.DictRule
|
|
||||||
import io.legado.app.data.entities.TxtTocRule
|
import io.legado.app.data.entities.TxtTocRule
|
||||||
import io.legado.app.help.DefaultData
|
import io.legado.app.help.DefaultData
|
||||||
import io.legado.app.help.http.newCallResponseBody
|
import io.legado.app.help.http.newCallResponseBody
|
||||||
@@ -43,7 +42,7 @@ class TxtTocRuleViewModel(app: Application) : BaseViewModel(app) {
|
|||||||
okHttpClient.newCallResponseBody {
|
okHttpClient.newCallResponseBody {
|
||||||
url(url)
|
url(url)
|
||||||
}.text("utf-8").let { json ->
|
}.text("utf-8").let { json ->
|
||||||
GSON.fromJsonArray<TxtTocRule>(json).getOrThrow()?.let {
|
GSON.fromJsonArray<TxtTocRule>(json).getOrThrow().let {
|
||||||
appDb.txtTocRuleDao.insert(*it.toTypedArray())
|
appDb.txtTocRuleDao.insert(*it.toTypedArray())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ class DictRuleEditDialog() : BaseDialogFragment(R.layout.dialog_dict_rule_edit,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
execute {
|
execute {
|
||||||
GSON.fromJsonObject<DictRule>(text).getOrThrow()!!
|
GSON.fromJsonObject<DictRule>(text).getOrThrow()
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
success.invoke(it)
|
success.invoke(it)
|
||||||
}.onError {
|
}.onError {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class BookshelfViewModel(application: Application) : BaseViewModel(application)
|
|||||||
private fun importBookshelfByJson(json: String, groupId: Long) {
|
private fun importBookshelfByJson(json: String, groupId: Long) {
|
||||||
execute {
|
execute {
|
||||||
val bookSources = appDb.bookSourceDao.allEnabled
|
val bookSources = appDb.bookSourceDao.allEnabled
|
||||||
GSON.fromJsonArray<Map<String, String?>>(json).getOrThrow()?.forEach { bookInfo ->
|
GSON.fromJsonArray<Map<String, String?>>(json).getOrThrow().forEach { bookInfo ->
|
||||||
if (!isActive) return@execute
|
if (!isActive) return@execute
|
||||||
val name = bookInfo["name"] ?: ""
|
val name = bookInfo["name"] ?: ""
|
||||||
val author = bookInfo["author"] ?: ""
|
val author = bookInfo["author"] ?: ""
|
||||||
|
|||||||
@@ -27,29 +27,41 @@ val GSON: Gson by lazy {
|
|||||||
|
|
||||||
inline fun <reified T> genericType(): Type = object : TypeToken<T>() {}.type
|
inline fun <reified T> genericType(): Type = object : TypeToken<T>() {}.type
|
||||||
|
|
||||||
inline fun <reified T> Gson.fromJsonObject(json: String?): Result<T?> {
|
inline fun <reified T> Gson.fromJsonObject(json: String?): Result<T> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
fromJson(json, genericType<T>()) as? T
|
if (json == null) {
|
||||||
|
throw JsonSyntaxException("解析字符串为空")
|
||||||
|
}
|
||||||
|
fromJson(json, genericType<T>()) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> Gson.fromJsonArray(json: String?): Result<List<T>?> {
|
inline fun <reified T> Gson.fromJsonArray(json: String?): Result<List<T>> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
fromJson(json, ParameterizedTypeImpl(T::class.java)) as? List<T>
|
if (json == null) {
|
||||||
|
throw JsonSyntaxException("解析字符串为空")
|
||||||
|
}
|
||||||
|
fromJson(json, ParameterizedTypeImpl(T::class.java)) as List<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> Gson.fromJsonObject(inputStream: InputStream?): Result<T?> {
|
inline fun <reified T> Gson.fromJsonObject(inputStream: InputStream?): Result<T> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw JsonSyntaxException("解析流为空")
|
||||||
|
}
|
||||||
val reader = InputStreamReader(inputStream)
|
val reader = InputStreamReader(inputStream)
|
||||||
fromJson(reader, genericType<T>()) as? T
|
fromJson(reader, genericType<T>()) as T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T> Gson.fromJsonArray(inputStream: InputStream?): Result<List<T>?> {
|
inline fun <reified T> Gson.fromJsonArray(inputStream: InputStream?): Result<List<T>> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
|
if (inputStream == null) {
|
||||||
|
throw JsonSyntaxException("解析流为空")
|
||||||
|
}
|
||||||
val reader = InputStreamReader(inputStream)
|
val reader = InputStreamReader(inputStream)
|
||||||
fromJson(reader, ParameterizedTypeImpl(T::class.java)) as? List<T>
|
fromJson(reader, ParameterizedTypeImpl(T::class.java)) as List<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user