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
import android.app.Application
import android.net.Uri
import androidx.lifecycle.MutableLiveData
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) {
val successLive = MutableLiveData<Pair<String, 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) {
//暂时根据文件内容判断属于什么
when {
json.contains("bookSourceUrl") ->
successLive.postValue(Pair("bookSource", json))
json.contains("sourceUrl") ->
successLive.postValue(Pair("rssSource", json))
json.contains("pattern") ->

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

@ -1,6 +1,7 @@
package io.legado.app.ui.association
import android.app.Application
import android.net.Uri
import androidx.lifecycle.MutableLiveData
import com.jayway.jsonpath.JsonPath
import io.legado.app.R
@ -109,6 +110,12 @@ class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
mText.isAbsUrl() -> {
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))
}
}.onError {

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

@ -6,6 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import io.legado.app.R
import io.legado.app.constant.AppLog
import io.legado.app.exception.NoStackTraceException
import io.legado.app.lib.permission.Permissions
import io.legado.app.lib.permission.PermissionsCompat
@ -154,3 +155,24 @@ fun Uri.writeBytes(
}
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