Merge pull request #2281 from 821938089/little-fix

优化书源导入
pull/2287/head
kunfei 2 years ago committed by GitHub
commit 026727018b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      app/src/main/java/io/legado/app/ui/association/BaseAssociationViewModel.kt
  2. 18
      app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt
  3. 7
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  4. 7
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  5. 25
      app/src/main/java/io/legado/app/utils/InputStreamExtensions.kt
  6. 5
      app/src/main/java/io/legado/app/utils/StringExtensions.kt
  7. 22
      app/src/main/java/io/legado/app/utils/UriExtensions.kt

@ -1,19 +1,29 @@
package io.legado.app.ui.association package io.legado.app.ui.association
import android.app.Application import android.app.Application
import android.net.Uri
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.utils.contains
import io.legado.app.utils.inputStream
import io.legado.app.utils.readText
abstract class BaseAssociationViewModel(application: Application) : BaseViewModel(application) { abstract class BaseAssociationViewModel(application: Application) : BaseViewModel(application) {
val successLive = MutableLiveData<Pair<String, String>>() val successLive = MutableLiveData<Pair<String, String>>()
val errorLive = MutableLiveData<String>() val errorLive = MutableLiveData<String>()
fun importJson(uri: Uri) {
when {
uri.inputStream(context).contains("bookSourceUrl") ->
successLive.postValue(Pair("bookSource", uri.toString()))
else -> importJson(uri.readText(context))
}
}
fun importJson(json: String) { fun importJson(json: String) {
//暂时根据文件内容判断属于什么 //暂时根据文件内容判断属于什么
when { when {
json.contains("bookSourceUrl") ->
successLive.postValue(Pair("bookSource", json))
json.contains("sourceUrl") -> json.contains("sourceUrl") ->
successLive.postValue(Pair("rssSource", json)) successLive.postValue(Pair("rssSource", json))
json.contains("pattern") -> json.contains("pattern") ->

@ -7,7 +7,9 @@ import androidx.lifecycle.MutableLiveData
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.AppPattern.bookFileRegex import io.legado.app.constant.AppPattern.bookFileRegex
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.IntentData
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.utils.inputStream
import io.legado.app.utils.isJson import io.legado.app.utils.isJson
import io.legado.app.utils.printOnDebug import io.legado.app.utils.printOnDebug
import java.io.File import java.io.File
@ -23,24 +25,19 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
fun dispatchIndent(uri: Uri) { fun dispatchIndent(uri: Uri) {
execute { execute {
lateinit var fileName: String lateinit var fileName: String
lateinit var content: String
lateinit var fileStream: InputStream
//如果是普通的url,需要根据返回的内容判断是什么 //如果是普通的url,需要根据返回的内容判断是什么
if (uri.scheme == "file" || uri.scheme == "content") { if (uri.scheme == "file" || uri.scheme == "content") {
if (uri.scheme == "file") { fileName = if (uri.scheme == "file") {
val file = File(uri.path.toString()) val file = File(uri.path.toString())
fileStream = file.inputStream() file.name
fileName = file.name
} else { } else {
val file = DocumentFile.fromSingleUri(context, uri) val file = DocumentFile.fromSingleUri(context, uri)
if (file?.exists() != true) throw NoStackTraceException("文件不存在") if (file?.exists() != true) throw NoStackTraceException("文件不存在")
fileStream = context.contentResolver.openInputStream(uri)!! file.name ?: ""
fileName = file.name ?: ""
} }
kotlin.runCatching { kotlin.runCatching {
content = fileStream.reader(Charsets.UTF_8).use { it.readText() } if (uri.inputStream(context).isJson()) {
if (content.isJson()) { importJson(uri)
importJson(content)
return@execute return@execute
} }
}.onFailure { }.onFailure {
@ -58,6 +55,7 @@ class FileAssociationViewModel(application: Application) : BaseAssociationViewMo
}.onError { }.onError {
it.printOnDebug() it.printOnDebug()
errorLive.postValue(it.localizedMessage) errorLive.postValue(it.localizedMessage)
AppLog.put("无法打开文件\n${it.localizedMessage}", it)
} }
} }

@ -1,6 +1,7 @@
package io.legado.app.ui.association package io.legado.app.ui.association
import android.app.Application import android.app.Application
import android.net.Uri
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import com.jayway.jsonpath.JsonPath import com.jayway.jsonpath.JsonPath
import io.legado.app.R import io.legado.app.R
@ -109,6 +110,12 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
mText.isAbsUrl() -> { mText.isAbsUrl() -> {
importSourceUrl(mText) importSourceUrl(mText)
} }
mText.isUri() -> {
val uri = Uri.parse(mText)
uri.inputStream(context)?.let {
allSources.addAll(BookSource.fromJsonArray(it).getOrThrow())
}
}
else -> throw NoStackTraceException(context.getString(R.string.wrong_format)) else -> throw NoStackTraceException(context.getString(R.string.wrong_format))
} }
}.onError { }.onError {

@ -21,6 +21,7 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.databinding.ActivityBookSourceBinding import io.legado.app.databinding.ActivityBookSourceBinding
import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.DirectLinkUpload import io.legado.app.help.DirectLinkUpload
import io.legado.app.help.IntentData
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
@ -77,11 +78,7 @@ class BookSourceActivity : VMBaseActivity<ActivityBookSourceBinding, BookSourceV
} }
private val importDoc = registerForActivityResult(HandleFileContract()) { private val importDoc = registerForActivityResult(HandleFileContract()) {
it.uri?.let { uri -> it.uri?.let { uri ->
try { showDialogFragment(ImportBookSourceDialog(uri.toString()))
showDialogFragment(ImportBookSourceDialog(uri.readText(this)))
} catch (e: Exception) {
toastOnUi("readTextError:${e.localizedMessage}")
}
} }
} }
private val exportDir = registerForActivityResult(HandleFileContract()) { private val exportDir = registerForActivityResult(HandleFileContract()) {

@ -0,0 +1,25 @@
package io.legado.app.utils
import java.io.InputStream
import java.util.*
fun InputStream?.isJson(): Boolean {
this ?: return false
this.use {
val byteArray = ByteArray(128)
it.read(byteArray)
val a = String(byteArray).trim()
it.skip(it.available() - 128L)
it.read(byteArray)
val b = String(byteArray).trim()
return (a + b).isJson()
}
}
fun InputStream?.contains(str: String): Boolean {
this ?: return false
this.use {
val scanner = Scanner(it)
return scanner.findWithinHorizon(str, 0) != null
}
}

@ -24,6 +24,11 @@ fun String.parseToUri(): Uri {
} }
} }
fun String?.isUri(): Boolean {
this ?: return false
return this.startsWith("file://", true) || isContentScheme()
}
fun String?.isAbsUrl() = fun String?.isAbsUrl() =
this?.let { this?.let {
it.startsWith("http://", true) || it.startsWith("https://", true) it.startsWith("http://", true) || it.startsWith("https://", true)

@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppLog
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.lib.permission.Permissions import io.legado.app.lib.permission.Permissions
import io.legado.app.lib.permission.PermissionsCompat import io.legado.app.lib.permission.PermissionsCompat
@ -154,3 +155,24 @@ fun Uri.writeBytes(
} }
return false return false
} }
fun Uri.inputStream(context: Context): InputStream? {
val uri = this
try {
if (isContentScheme()) {
val doc = DocumentFile.fromSingleUri(context, uri)
doc ?: throw NoStackTraceException("未获取到文件")
return context.contentResolver.openInputStream(uri)!!
} else {
RealPathUtil.getPath(context, uri)?.let { path ->
val file = File(path)
return FileInputStream(file)
}
}
} catch (e: Exception) {
e.printOnDebug()
context.toastOnUi("读取inputStream失败:${e.localizedMessage}")
AppLog.put("读取inputStream失败:${e.localizedMessage}", e)
}
return null
}
Loading…
Cancel
Save