优化导入,导入时增加确认

pull/306/head
gedoor 5 years ago
parent 5810596e41
commit 92b9a6e1cd
  1. 85
      app/src/main/AndroidManifest.xml
  2. 24
      app/src/main/java/io/legado/app/base/BaseActivity.kt
  3. 2
      app/src/main/java/io/legado/app/constant/Theme.kt
  4. 16
      app/src/main/java/io/legado/app/help/storage/ImportOldData.kt
  5. 16
      app/src/main/java/io/legado/app/help/storage/OldReplace.kt
  6. 10
      app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt
  7. 2
      app/src/main/java/io/legado/app/ui/association/FileAssociationViewModel.kt
  8. 80
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt
  9. 105
      app/src/main/java/io/legado/app/ui/association/ImportBookSourceViewModel.kt
  10. 80
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt
  11. 64
      app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleViewModel.kt
  12. 80
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt
  13. 96
      app/src/main/java/io/legado/app/ui/association/ImportRssSourceViewModel.kt
  14. 53
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt
  15. 103
      app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt
  16. 50
      app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt
  17. 51
      app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleViewModel.kt
  18. 54
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt
  19. 96
      app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceViewModel.kt
  20. 5
      app/src/main/res/layout/activity_translucence.xml

@ -199,47 +199,15 @@
<!-- 书源管理 --> <!-- 书源管理 -->
<activity <activity
android:name=".ui.book.source.manage.BookSourceActivity" android:name=".ui.book.source.manage.BookSourceActivity"
android:launchMode="singleTop"> android:launchMode="singleTop" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="booksource"
android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 订阅源管理 --> <!-- 订阅源管理 -->
<activity <activity
android:name=".ui.rss.source.manage.RssSourceActivity" android:name=".ui.rss.source.manage.RssSourceActivity"
android:launchMode="singleTop"> android:launchMode="singleTop" />
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="rsssource"
android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 替换规则界面 --> <!-- 替换规则界面 -->
<activity <activity
android:name=".ui.replacerule.ReplaceRuleActivity" android:name=".ui.replacerule.ReplaceRuleActivity"
android:launchMode="singleTop"> android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="replace"
android:scheme="yuedu" />
</intent-filter>
</activity> </activity>
<!-- 书籍管理 --> <!-- 书籍管理 -->
<activity <activity
@ -308,8 +276,55 @@
<data android:mimeType="text/plain" /> <data android:mimeType="text/plain" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- 导入书源 -->
<activity
android:name=".ui.association.ImportBookSourceActivity"
android:theme="@style/AppTheme.Transparent">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="booksource"
android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 导入订阅源 -->
<activity
android:name=".ui.association.ImportRssSourceActivity"
android:theme="@style/AppTheme.Transparent">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="rsssource"
android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 导入替换规则 -->
<activity
android:name=".ui.association.ImportReplaceRuleActivity"
android:theme="@style/AppTheme.Transparent">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="replace"
android:scheme="yuedu" />
</intent-filter>
</activity>
<!-- 打开文件 -->
<activity <activity
android:name=".ui.config.FileAssociationActivity" android:name=".ui.association.FileAssociationActivity"
android:theme="@style/AppTheme.Transparent"
android:launchMode="singleTop"> android:launchMode="singleTop">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />

@ -24,7 +24,8 @@ import kotlinx.coroutines.cancel
abstract class BaseActivity( abstract class BaseActivity(
private val layoutID: Int, private val layoutID: Int,
private val fullScreen: Boolean = true, private val fullScreen: Boolean = true,
private val theme: Theme = Theme.Auto private val theme: Theme = Theme.Auto,
private val transparent: Boolean = false
) : AppCompatActivity(), ) : AppCompatActivity(),
CoroutineScope by MainScope() { CoroutineScope by MainScope() {
@ -92,14 +93,23 @@ abstract class BaseActivity(
} }
private fun initTheme() { private fun initTheme() {
ATH.applyBackgroundTint(window.decorView)
when (theme) { when (theme) {
Theme.Dark -> setTheme(R.style.AppTheme_Dark) Theme.Transparent -> setTheme(R.style.AppTheme_Transparent)
Theme.Light -> setTheme(R.style.AppTheme_Light) Theme.Dark -> {
else -> if (ColorUtils.isColorLight(primaryColor)) {
setTheme(R.style.AppTheme_Light)
} else {
setTheme(R.style.AppTheme_Dark) setTheme(R.style.AppTheme_Dark)
ATH.applyBackgroundTint(window.decorView)
}
Theme.Light -> {
setTheme(R.style.AppTheme_Light)
ATH.applyBackgroundTint(window.decorView)
}
else -> {
if (ColorUtils.isColorLight(primaryColor)) {
setTheme(R.style.AppTheme_Light)
} else {
setTheme(R.style.AppTheme_Dark)
}
ATH.applyBackgroundTint(window.decorView)
} }
} }
} }

@ -3,7 +3,7 @@ package io.legado.app.constant
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
enum class Theme { enum class Theme {
Dark, Light, Auto; Dark, Light, Auto, Transparent;
companion object { companion object {
fun getTheme(): Theme { fun getTheme(): Theme {

@ -5,7 +5,6 @@ import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.App import io.legado.app.App
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.utils.DocumentUtils import io.legado.app.utils.DocumentUtils
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileUtils
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
@ -102,17 +101,8 @@ object ImportOldData {
} }
fun importOldReplaceRule(json: String): Int { fun importOldReplaceRule(json: String): Int {
val replaceRules = mutableListOf<ReplaceRule>() val rules = OldReplace.jsonToReplaceRules(json)
val items: List<Map<String, Any>> = Restore.jsonPath.parse(json).read("$") App.db.replaceRuleDao().insert(*rules.toTypedArray())
for (item in items) { return rules.size
val jsonItem = Restore.jsonPath.parse(item)
OldReplace.jsonToReplaceRule(jsonItem.jsonString())?.let {
if (it.isValid()){
replaceRules.add(it)
}
}
}
App.db.replaceRuleDao().insert(*replaceRules.toTypedArray())
return replaceRules.size
} }
} }

@ -5,7 +5,21 @@ import io.legado.app.utils.*
object OldReplace { object OldReplace {
fun jsonToReplaceRule(json: String): ReplaceRule? { fun jsonToReplaceRules(json: String): List<ReplaceRule> {
val replaceRules = mutableListOf<ReplaceRule>()
val items: List<Map<String, Any>> = Restore.jsonPath.parse(json).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)
jsonToReplaceRule(jsonItem.jsonString())?.let {
if (it.isValid()) {
replaceRules.add(it)
}
}
}
return replaceRules
}
private fun jsonToReplaceRule(json: String): ReplaceRule? {
var replaceRule: ReplaceRule? = null var replaceRule: ReplaceRule? = null
runCatching { runCatching {
replaceRule = GSON.fromJsonObject<ReplaceRule>(json.trim()) replaceRule = GSON.fromJsonObject<ReplaceRule>(json.trim())

@ -1,15 +1,19 @@
package io.legado.app.ui.config package io.legado.app.ui.association
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
import io.legado.app.ui.main.MainActivity import io.legado.app.ui.main.MainActivity
import io.legado.app.utils.getViewModel import io.legado.app.utils.getViewModel
class FileAssociationActivity : class FileAssociationActivity : VMBaseActivity<FileAssociationViewModel>(
VMBaseActivity<FileAssociationViewModel>(R.layout.activity_file_association) { R.layout.activity_translucence,
theme = Theme.Transparent
) {
override val viewModel: FileAssociationViewModel override val viewModel: FileAssociationViewModel
get() = getViewModel(FileAssociationViewModel::class.java) get() = getViewModel(FileAssociationViewModel::class.java)

@ -1,4 +1,4 @@
package io.legado.app.ui.config package io.legado.app.ui.association
import android.app.Application import android.app.Application
import android.content.Intent import android.content.Intent

@ -0,0 +1,80 @@
package io.legado.app.ui.association
import android.os.Bundle
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
import io.legado.app.data.entities.BookSource
import io.legado.app.help.SourceHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton
import io.legado.app.utils.applyTint
import io.legado.app.utils.getViewModel
import org.jetbrains.anko.toast
class ImportBookSourceActivity : VMBaseActivity<ImportBookSourceViewModel>(
R.layout.activity_translucence,
theme = Theme.Transparent
) {
override val viewModel: ImportBookSourceViewModel
get() = getViewModel(ImportBookSourceViewModel::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.errorLiveData.observe(this, Observer {
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
successDialog(it)
})
initData()
}
private fun initData() {
intent.getStringExtra("source")?.let {
viewModel.importSource(it)
return
}
intent.getStringExtra("filePath")?.let {
viewModel.importSourceFromFilePath(it)
return
}
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
if (url.startsWith("http", false)) {
viewModel.importSource(url)
} else {
viewModel.importSourceFromFilePath(url)
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun errorDialog(msg: String) {
alert("导入出错", msg) {
okButton { }
}.show().applyTint().setOnDismissListener {
finish()
}
}
private fun successDialog(allSource: ArrayList<BookSource>) {
alert("解析结果", "${allSource.size}个书源,是否确认导入?") {
okButton {
SourceHelp.insertBookSource(*allSource.toTypedArray())
}
noButton {
}
}.show().applyTint().setOnDismissListener {
finish()
}
}
}

@ -0,0 +1,105 @@
package io.legado.app.ui.association
import android.app.Application
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.MutableLiveData
import com.jayway.jsonpath.JsonPath
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.BookSource
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.OldRule
import io.legado.app.help.storage.Restore
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
class ImportBookSourceViewModel(app: Application) : BaseViewModel(app) {
val errorLiveData = MutableLiveData<String>()
val successLiveData = MutableLiveData<ArrayList<BookSource>>()
private val allSources = arrayListOf<BookSource>()
fun importSourceFromFilePath(path: String) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (content != null) {
importSource(content)
} else {
withContext(Dispatchers.Main) {
errorLiveData.postValue("打开文件出错")
}
}
}.onError {
errorLiveData.postValue(it.localizedMessage ?: "打开文件出错")
}
}
fun importSource(text: String) {
execute {
val text1 = text.trim()
when {
text1.isJsonObject() -> {
val json = JsonPath.parse(text1)
val urls = json.read<List<String>>("$.sourceUrls")
if (!urls.isNullOrEmpty()) {
urls.forEach {
importSourceUrl(it)
}
} else {
OldRule.jsonToBookSource(text1)?.let {
allSources.add(it)
}
}
}
text1.isJsonArray() -> {
val items: List<Map<String, Any>> = Restore.jsonPath.parse(text1).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)
OldRule.jsonToBookSource(jsonItem.jsonString())?.let {
allSources.add(it)
}
}
}
text1.isAbsUrl() -> {
importSourceUrl(text1)
}
else -> throw Exception("格式不对")
}
}.onError {
it.printStackTrace()
errorLiveData.postValue(it.localizedMessage ?: "")
}.onSuccess {
successLiveData.postValue(allSources)
}
}
private fun importSourceUrl(url: String) {
HttpHelper.simpleGet(url, "UTF-8").let { body ->
if (body == null) {
throw Exception("访问网站失败")
}
val items: List<Map<String, Any>> = Restore.jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)
OldRule.jsonToBookSource(jsonItem.jsonString())?.let { source ->
allSources.add(source)
}
}
}
}
}

@ -0,0 +1,80 @@
package io.legado.app.ui.association
import android.os.Bundle
import androidx.lifecycle.Observer
import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton
import io.legado.app.utils.applyTint
import io.legado.app.utils.getViewModel
import org.jetbrains.anko.toast
class ImportReplaceRuleActivity : VMBaseActivity<ImportReplaceRuleViewModel>(
R.layout.activity_translucence,
theme = Theme.Transparent
) {
override val viewModel: ImportReplaceRuleViewModel
get() = getViewModel(ImportReplaceRuleViewModel::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.errorLiveData.observe(this, Observer {
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
successDialog(it)
})
initData()
}
private fun initData() {
intent.getStringExtra("source")?.let {
viewModel.import(it)
return
}
intent.getStringExtra("filePath")?.let {
viewModel.importFromFilePath(it)
return
}
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
if (url.startsWith("http", false)) {
viewModel.import(url)
} else {
viewModel.importFromFilePath(url)
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun errorDialog(msg: String) {
alert("导入出错", msg) {
okButton { }
}.show().applyTint().setOnDismissListener {
finish()
}
}
private fun successDialog(allSource: ArrayList<ReplaceRule>) {
alert("解析结果", "${allSource.size}个替换规则,是否确认导入?") {
okButton {
App.db.replaceRuleDao().insert(*allSource.toTypedArray())
}
noButton {
}
}.show().applyTint().setOnDismissListener {
finish()
}
}
}

@ -0,0 +1,64 @@
package io.legado.app.ui.association
import android.app.Application
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.MutableLiveData
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.OldReplace
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.isContentPath
import io.legado.app.utils.readText
import java.io.File
class ImportReplaceRuleViewModel(app: Application) : BaseViewModel(app) {
val errorLiveData = MutableLiveData<String>()
val successLiveData = MutableLiveData<ArrayList<ReplaceRule>>()
private val allRules = arrayListOf<ReplaceRule>()
fun importFromFilePath(path: String) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (content != null) {
import(content)
} else {
errorLiveData.postValue("打开文件出错")
}
}.onError {
errorLiveData.postValue(it.localizedMessage ?: "打开文件出错")
}
}
fun import(text: String) {
execute {
if (text.isAbsUrl()) {
HttpHelper.simpleGet(text)?.let {
val rules = OldReplace.jsonToReplaceRules(it)
allRules.addAll(rules)
}
} else {
val rules = OldReplace.jsonToReplaceRules(text)
allRules.addAll(rules)
}
}.onError {
errorLiveData.postValue(it.localizedMessage ?: "ERROR")
}.onSuccess {
errorLiveData.postValue(context.getString(R.string.success))
}
}
}

@ -0,0 +1,80 @@
package io.legado.app.ui.association
import android.os.Bundle
import androidx.lifecycle.Observer
import io.legado.app.R
import io.legado.app.base.VMBaseActivity
import io.legado.app.constant.Theme
import io.legado.app.data.entities.RssSource
import io.legado.app.help.SourceHelp
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.dialogs.noButton
import io.legado.app.lib.dialogs.okButton
import io.legado.app.utils.applyTint
import io.legado.app.utils.getViewModel
import org.jetbrains.anko.toast
class ImportRssSourceActivity : VMBaseActivity<ImportRssSourceViewModel>(
R.layout.activity_translucence,
theme = Theme.Transparent
) {
override val viewModel: ImportRssSourceViewModel
get() = getViewModel(ImportRssSourceViewModel::class.java)
override fun onActivityCreated(savedInstanceState: Bundle?) {
viewModel.errorLiveData.observe(this, Observer {
errorDialog(it)
})
viewModel.successLiveData.observe(this, Observer {
successDialog(it)
})
initData()
}
private fun initData() {
intent.getStringExtra("source")?.let {
viewModel.importSource(it)
return
}
intent.getStringExtra("filePath")?.let {
viewModel.importSourceFromFilePath(it)
return
}
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
if (url.startsWith("http", false)) {
viewModel.importSource(url)
} else {
viewModel.importSourceFromFilePath(url)
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun errorDialog(msg: String) {
alert("导入出错", msg) {
okButton { }
}.show().applyTint().setOnDismissListener {
finish()
}
}
private fun successDialog(allSource: ArrayList<RssSource>) {
alert("解析结果", "${allSource.size}个订阅源,是否确认导入?") {
okButton {
SourceHelp.insertRssSource(*allSource.toTypedArray())
}
noButton {
}
}.show().applyTint().setOnDismissListener {
finish()
}
}
}

@ -0,0 +1,96 @@
package io.legado.app.ui.association
import android.app.Application
import android.net.Uri
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.MutableLiveData
import com.jayway.jsonpath.JsonPath
import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssSource
import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore
import io.legado.app.utils.*
import java.io.File
class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
val errorLiveData = MutableLiveData<String>()
val successLiveData = MutableLiveData<ArrayList<RssSource>>()
private val allSources = arrayListOf<RssSource>()
fun importSourceFromFilePath(path: String) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (null != content) {
GSON.fromJsonArray<RssSource>(content)?.let {
allSources.addAll(it)
}
}
}.onSuccess {
successLiveData.postValue(allSources)
}
}
fun importSource(text: String) {
execute {
val text1 = text.trim()
when {
text1.isJsonObject() -> {
val json = JsonPath.parse(text1)
val urls = json.read<List<String>>("$.sourceUrls")
if (!urls.isNullOrEmpty()) {
urls.forEach {
importSourceUrl(it)
}
} else {
GSON.fromJsonArray<RssSource>(text1)?.let {
allSources.addAll(it)
}
}
}
text1.isJsonArray() -> {
val items: List<Map<String, Any>> = Restore.jsonPath.parse(text1).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)
GSON.fromJsonObject<RssSource>(jsonItem.jsonString())?.let {
allSources.add(it)
}
}
}
text1.isAbsUrl() -> {
importSourceUrl(text1)
}
else -> throw Exception("格式不对")
}
}.onError {
errorLiveData.postValue("ImportError:${it.localizedMessage}")
}.onSuccess {
successLiveData.postValue(allSources)
}
}
private fun importSourceUrl(url: String) {
HttpHelper.simpleGet(url, "UTF-8")?.let { body ->
val items: List<Map<String, Any>> = Restore.jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = Restore.jsonPath.parse(item)
GSON.fromJsonObject<RssSource>(jsonItem.jsonString())?.let { source ->
allSources.add(source)
}
}
}
}
}

@ -15,7 +15,6 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@ -25,6 +24,7 @@ import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.primaryTextColor import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.service.help.CheckSource import io.legado.app.service.help.CheckSource
import io.legado.app.ui.association.ImportBookSourceActivity
import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity
import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.ui.filechooser.FilePicker import io.legado.app.ui.filechooser.FilePicker
@ -38,7 +38,6 @@ import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.view_search.* import kotlinx.android.synthetic.main.view_search.*
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.io.File import java.io.File
import java.text.Collator import java.text.Collator
@ -60,7 +59,6 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
private var sort = 0 private var sort = 0
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initUriScheme()
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
initLiveDataBookSource() initLiveDataBookSource()
@ -128,28 +126,6 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
return super.onCompatOptionsItemSelected(item) return super.onCompatOptionsItemSelected(item)
} }
private fun initUriScheme() {
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show()
if (url.startsWith("http", false)) {
viewModel.importSource(url) { msg ->
title_bar.snackbar(msg)
}
} else {
viewModel.importSourceFromFilePath(url) { msg ->
title_bar.snackbar(msg)
}
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(recycler_view)
recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = LinearLayoutManager(this)
@ -309,10 +285,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
cacheUrls.add(0, it) cacheUrls.add(0, it)
aCache.put(importRecordKey, cacheUrls.joinToString(",")) aCache.put(importRecordKey, cacheUrls.joinToString(","))
} }
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportBookSourceActivity>(Pair("source", it))
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
} }
} }
cancelButton() cancelButton()
@ -365,10 +338,7 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
File(currentPath) File(currentPath)
) )
importRequestCode -> { importRequestCode -> {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportBookSourceActivity>(Pair("filePath", currentPath))
viewModel.importSourceFromFilePath(currentPath) { msg ->
title_bar.snackbar(msg)
}
} }
} }
} }
@ -378,25 +348,12 @@ class BookSourceActivity : VMBaseActivity<BookSourceViewModel>(R.layout.activity
when (requestCode) { when (requestCode) {
qrRequestCode -> if (resultCode == RESULT_OK) { qrRequestCode -> if (resultCode == RESULT_OK) {
data?.getStringExtra("result")?.let { data?.getStringExtra("result")?.let {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportBookSourceActivity>("source" to it)
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
} }
} }
importRequestCode -> if (resultCode == Activity.RESULT_OK) { importRequestCode -> if (resultCode == Activity.RESULT_OK) {
data?.data?.let { uri -> data?.data?.let { uri ->
try { startActivity<ImportBookSourceActivity>("filePath" to uri.toString())
uri.readText(this)?.let {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE)
.show()
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
}
} catch (e: Exception) {
toast(e.localizedMessage ?: "ERROR")
}
} }
} }
exportRequestCode -> { exportRequestCode -> {

@ -1,20 +1,15 @@
package io.legado.app.ui.book.source.manage package io.legado.app.ui.book.source.manage
import android.app.Application import android.app.Application
import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.jayway.jsonpath.JsonPath
import io.legado.app.App import io.legado.app.App
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.SourceHelp import io.legado.app.utils.FileUtils
import io.legado.app.help.http.HttpHelper import io.legado.app.utils.GSON
import io.legado.app.help.storage.OldRule import io.legado.app.utils.splitNotBlank
import io.legado.app.help.storage.Restore.jsonPath import io.legado.app.utils.writeText
import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import java.io.File import java.io.File
@ -166,94 +161,4 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application)
} }
} }
fun importSourceFromFilePath(path: String, finally: (msg: String) -> Unit) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (content != null) {
importSource(content, finally)
} else {
withContext(Dispatchers.Main) {
finally("打开文件出错")
}
}
}.onError {
finally(it.localizedMessage ?: "打开文件出错")
}
}
fun importSource(text: String, finally: (msg: String) -> Unit) {
execute {
val text1 = text.trim()
when {
text1.isJsonObject() -> {
val json = JsonPath.parse(text1)
val urls = json.read<List<String>>("$.sourceUrls")
var count = 0
if (!urls.isNullOrEmpty()) {
urls.forEach {
count += importSourceUrl(it)
}
} else {
OldRule.jsonToBookSource(text1)?.let {
SourceHelp.insertBookSource(it)
count = 1
}
}
"导入${count}"
}
text1.isJsonArray() -> {
val bookSources = mutableListOf<BookSource>()
val items: List<Map<String, Any>> = jsonPath.parse(text1).read("$")
for (item in items) {
val jsonItem = jsonPath.parse(item)
OldRule.jsonToBookSource(jsonItem.jsonString())?.let {
bookSources.add(it)
}
}
SourceHelp.insertBookSource(*bookSources.toTypedArray())
"导入${bookSources.size}"
}
text1.isAbsUrl() -> {
val count = importSourceUrl(text1)
"导入${count}"
}
else -> "格式不对"
}
}.onError {
it.printStackTrace()
finally(it.localizedMessage ?: "")
}.onSuccess {
finally(it)
}
}
private fun importSourceUrl(url: String): Int {
HttpHelper.simpleGet(url, "UTF-8").let { body ->
if (body == null) {
toast("访问网站失败")
return 0
}
val bookSources = mutableListOf<BookSource>()
val items: List<Map<String, Any>> = jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = jsonPath.parse(item)
OldRule.jsonToBookSource(jsonItem.jsonString())?.let { source ->
bookSources.add(source)
}
}
SourceHelp.insertBookSource(*bookSources.toTypedArray())
return bookSources.size
}
}
} }

@ -15,7 +15,6 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@ -26,6 +25,7 @@ import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.dialogs.* import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.primaryTextColor import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.ui.association.ImportReplaceRuleActivity
import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.ui.filechooser.FilePicker import io.legado.app.ui.filechooser.FilePicker
import io.legado.app.ui.replacerule.edit.ReplaceEditDialog import io.legado.app.ui.replacerule.edit.ReplaceEditDialog
@ -36,7 +36,7 @@ import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_replace_rule.* import kotlinx.android.synthetic.main.activity_replace_rule.*
import kotlinx.android.synthetic.main.dialog_edit_text.view.* import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.view_search.* import kotlinx.android.synthetic.main.view_search.*
import org.jetbrains.anko.toast import org.jetbrains.anko.startActivity
import java.io.File import java.io.File
@ -57,7 +57,6 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
private var dataInit = false private var dataInit = false
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initUriScheme()
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
initSelectActionView() initSelectActionView()
@ -76,29 +75,6 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
return super.onPrepareOptionsMenu(menu) return super.onPrepareOptionsMenu(menu)
} }
private fun initUriScheme() {
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show()
if (url.startsWith("http", false)){
viewModel.importSource(url) { msg ->
title_bar.snackbar(msg)
}
}
else{
viewModel.importSourceFromFilePath(url) { msg ->
title_bar.snackbar(msg)
}
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(recycler_view)
recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = LinearLayoutManager(this)
@ -242,10 +218,7 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
cacheUrls.add(0, it) cacheUrls.add(0, it)
aCache.put(importRecordKey, cacheUrls.joinToString(",")) aCache.put(importRecordKey, cacheUrls.joinToString(","))
} }
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportReplaceRuleActivity>("source" to it)
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
} }
} }
cancelButton() cancelButton()
@ -264,10 +237,7 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
override fun onFilePicked(requestCode: Int, currentPath: String) { override fun onFilePicked(requestCode: Int, currentPath: String) {
when (requestCode) { when (requestCode) {
importRequestCode -> { importRequestCode -> {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportReplaceRuleActivity>("filePath" to currentPath)
viewModel.importSource(File(currentPath).readText()) { msg ->
title_bar.snackbar(msg)
}
} }
exportRequestCode -> viewModel.exportSelection( exportRequestCode -> viewModel.exportSelection(
adapter.getSelection(), adapter.getSelection(),
@ -281,17 +251,7 @@ class ReplaceRuleActivity : VMBaseActivity<ReplaceRuleViewModel>(R.layout.activi
when (requestCode) { when (requestCode) {
importRequestCode -> if (resultCode == Activity.RESULT_OK) { importRequestCode -> if (resultCode == Activity.RESULT_OK) {
data?.data?.let { uri -> data?.data?.let { uri ->
try { startActivity<ImportReplaceRuleActivity>("filePath" to uri.toString())
uri.readText(this)?.let {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE)
.show()
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
}
} catch (e: Exception) {
toast(e.localizedMessage ?: "ERROR")
}
} }
} }
exportRequestCode -> if (resultCode == RESULT_OK) { exportRequestCode -> if (resultCode == RESULT_OK) {

@ -1,62 +1,19 @@
package io.legado.app.ui.replacerule package io.legado.app.ui.replacerule
import android.app.Application import android.app.Application
import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.App import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.ReplaceRule import io.legado.app.data.entities.ReplaceRule
import io.legado.app.help.http.HttpHelper import io.legado.app.utils.FileUtils
import io.legado.app.help.storage.ImportOldData import io.legado.app.utils.GSON
import io.legado.app.utils.* import io.legado.app.utils.splitNotBlank
import kotlinx.coroutines.Dispatchers import io.legado.app.utils.writeText
import kotlinx.coroutines.withContext
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import java.io.File import java.io.File
class ReplaceRuleViewModel(application: Application) : BaseViewModel(application) { class ReplaceRuleViewModel(application: Application) : BaseViewModel(application) {
fun importSourceFromFilePath(path: String, finally: (msg: String) -> Unit) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (content != null) {
importSource(content, finally)
} else {
withContext(Dispatchers.Main) {
finally("打开文件出错")
}
}
}.onError {
finally(it.localizedMessage ?: "打开文件出错")
}
}
fun importSource(text: String, showMsg: (msg: String) -> Unit) {
execute {
if (text.isAbsUrl()) {
HttpHelper.simpleGet(text)?.let {
ImportOldData.importOldReplaceRule(it)
}
} else {
ImportOldData.importOldReplaceRule(text)
}
}.onError {
showMsg(it.localizedMessage ?: "ERROR")
}.onSuccess {
showMsg(context.getString(R.string.success))
}
}
fun update(vararg rule: ReplaceRule) { fun update(vararg rule: ReplaceRule) {
execute { execute {

@ -15,7 +15,6 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.snackbar.Snackbar
import io.legado.app.App import io.legado.app.App
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.VMBaseActivity import io.legado.app.base.VMBaseActivity
@ -24,6 +23,7 @@ import io.legado.app.help.ItemTouchCallback
import io.legado.app.lib.dialogs.* import io.legado.app.lib.dialogs.*
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.primaryTextColor import io.legado.app.lib.theme.primaryTextColor
import io.legado.app.ui.association.ImportRssSourceActivity
import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FileChooserDialog
import io.legado.app.ui.filechooser.FilePicker import io.legado.app.ui.filechooser.FilePicker
import io.legado.app.ui.qrcode.QrCodeActivity import io.legado.app.ui.qrcode.QrCodeActivity
@ -37,7 +37,6 @@ import kotlinx.android.synthetic.main.dialog_edit_text.view.*
import kotlinx.android.synthetic.main.view_search.* import kotlinx.android.synthetic.main.view_search.*
import org.jetbrains.anko.startActivity import org.jetbrains.anko.startActivity
import org.jetbrains.anko.startActivityForResult import org.jetbrains.anko.startActivityForResult
import org.jetbrains.anko.toast
import java.io.File import java.io.File
import java.text.Collator import java.text.Collator
import java.util.* import java.util.*
@ -60,7 +59,6 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
private var groupMenu: SubMenu? = null private var groupMenu: SubMenu? = null
override fun onActivityCreated(savedInstanceState: Bundle?) { override fun onActivityCreated(savedInstanceState: Bundle?) {
initUriScheme()
initRecyclerView() initRecyclerView()
initSearchView() initSearchView()
initLiveDataGroup() initLiveDataGroup()
@ -112,29 +110,6 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
return true return true
} }
private fun initUriScheme() {
intent.data?.let {
when (it.path) {
"/importonline" -> it.getQueryParameter("src")?.let { url ->
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show()
if (url.startsWith("http", false)){
viewModel.importSource(url) { msg ->
title_bar.snackbar(msg)
}
}
else{
viewModel.importSourceFromFilePath(url) { msg ->
title_bar.snackbar(msg)
}
}
}
else -> {
toast("格式不对")
}
}
}
}
private fun initRecyclerView() { private fun initRecyclerView() {
ATH.applyEdgeEffectColor(recycler_view) ATH.applyEdgeEffectColor(recycler_view)
recycler_view.layoutManager = LinearLayoutManager(this) recycler_view.layoutManager = LinearLayoutManager(this)
@ -256,10 +231,7 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
cacheUrls.add(0, it) cacheUrls.add(0, it)
aCache.put(importRecordKey, cacheUrls.joinToString(",")) aCache.put(importRecordKey, cacheUrls.joinToString(","))
} }
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportRssSourceActivity>("source" to it)
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
} }
} }
cancelButton() cancelButton()
@ -269,10 +241,7 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
override fun onFilePicked(requestCode: Int, currentPath: String) { override fun onFilePicked(requestCode: Int, currentPath: String) {
when (requestCode) { when (requestCode) {
importRequestCode -> { importRequestCode -> {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE).show() startActivity<ImportRssSourceActivity>("filePath" to currentPath)
viewModel.importSourceFromFilePath(currentPath) { msg ->
title_bar.snackbar(msg)
}
} }
exportRequestCode -> viewModel.exportSelection( exportRequestCode -> viewModel.exportSelection(
adapter.getSelection(), adapter.getSelection(),
@ -286,25 +255,12 @@ class RssSourceActivity : VMBaseActivity<RssSourceViewModel>(R.layout.activity_r
when (requestCode) { when (requestCode) {
importRequestCode -> if (resultCode == Activity.RESULT_OK) { importRequestCode -> if (resultCode == Activity.RESULT_OK) {
data?.data?.let { uri -> data?.data?.let { uri ->
try { startActivity<ImportRssSourceActivity>("filePath" to uri.toString())
uri.readText(this)?.let {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE)
.show()
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
}
} catch (e: Exception) {
toast(e.localizedMessage ?: "ERROR")
}
} }
} }
qrRequestCode -> if (resultCode == RESULT_OK) { qrRequestCode -> if (resultCode == RESULT_OK) {
data?.getStringExtra("result")?.let { data?.getStringExtra("result")?.let {
Snackbar.make(title_bar, R.string.importing, Snackbar.LENGTH_INDEFINITE) startActivity<ImportRssSourceActivity>("source" to it)
viewModel.importSource(it) { msg ->
title_bar.snackbar(msg)
}
} }
} }
exportRequestCode -> if (resultCode == RESULT_OK) { exportRequestCode -> if (resultCode == RESULT_OK) {

@ -1,18 +1,15 @@
package io.legado.app.ui.rss.source.manage package io.legado.app.ui.rss.source.manage
import android.app.Application import android.app.Application
import android.net.Uri
import android.text.TextUtils import android.text.TextUtils
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import com.jayway.jsonpath.JsonPath
import io.legado.app.App import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.help.SourceHelp import io.legado.app.utils.FileUtils
import io.legado.app.help.http.HttpHelper import io.legado.app.utils.GSON
import io.legado.app.help.storage.Restore.jsonPath import io.legado.app.utils.splitNotBlank
import io.legado.app.utils.* import io.legado.app.utils.writeText
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import java.io.File import java.io.File
@ -147,89 +144,4 @@ class RssSourceViewModel(application: Application) : BaseViewModel(application)
} }
} }
fun importSourceFromFilePath(path: String, finally: (msg: String) -> Unit) {
execute {
val content = if (path.isContentPath()) {
//在前面被解码了,如果不进行编码,中文会无法识别
val newPath = Uri.encode(path, ":/.")
DocumentFile.fromSingleUri(context, Uri.parse(newPath))?.readText(context)
} else {
val file = File(path)
if (file.exists()) {
file.readText()
} else {
null
}
}
if (null != content) {
GSON.fromJsonArray<RssSource>(content)?.let {
SourceHelp.insertRssSource(*it.toTypedArray())
}
}
}.onSuccess {
finally.invoke(context.getString(R.string.success))
}
}
fun importSource(text: String, finally: (msg: String) -> Unit) {
execute {
val text1 = text.trim()
when {
text1.isJsonObject() -> {
val json = JsonPath.parse(text1)
val urls = json.read<List<String>>("$.sourceUrls")
var count = 0
if (!urls.isNullOrEmpty()) {
urls.forEach {
count += importSourceUrl(it)
}
} else {
GSON.fromJsonArray<RssSource>(text1)?.let {
SourceHelp.insertRssSource(*it.toTypedArray())
count = 1
}
}
"导入${count}"
}
text1.isJsonArray() -> {
val rssSources = mutableListOf<RssSource>()
val items: List<Map<String, Any>> = jsonPath.parse(text1).read("$")
for (item in items) {
val jsonItem = jsonPath.parse(item)
GSON.fromJsonObject<RssSource>(jsonItem.jsonString())?.let {
rssSources.add(it)
}
}
SourceHelp.insertRssSource(*rssSources.toTypedArray())
"导入${rssSources.size}"
}
text1.isAbsUrl() -> {
val count = importSourceUrl(text1)
"导入${count}"
}
else -> "格式不对"
}
}.onError {
finally(it.localizedMessage ?: "")
}.onSuccess {
finally(it)
}
}
private fun importSourceUrl(url: String): Int {
HttpHelper.simpleGet(url, "UTF-8")?.let { body ->
val sources = mutableListOf<RssSource>()
val items: List<Map<String, Any>> = jsonPath.parse(body).read("$")
for (item in items) {
val jsonItem = jsonPath.parse(item)
GSON.fromJsonObject<RssSource>(jsonItem.jsonString())?.let { source ->
sources.add(source)
}
}
SourceHelp.insertRssSource(*sources.toTypedArray())
return sources.size
}
return 0
}
} }

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="io.legado.app.ui.config.FileAssociationActivity"> android:background="@color/transparent30">
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save