pull/1903/head
kunfei 3 years ago
parent adaace696b
commit 0a54940221
  1. 6
      app/src/main/java/io/legado/app/App.kt
  2. 2
      app/src/main/java/io/legado/app/api/controller/BookController.kt
  3. 11
      app/src/main/java/io/legado/app/help/AppWebDav.kt
  4. 1
      app/src/main/java/io/legado/app/help/storage/Backup.kt
  5. 3
      app/src/main/java/io/legado/app/model/ReadBook.kt
  6. 2
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  7. 2
      app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt
  8. 2
      app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt
  9. 16
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt
  10. 47
      app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt
  11. 6
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt
  12. 2
      app/src/main/java/io/legado/app/ui/config/ConfigViewModel.kt
  13. 2
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  14. 2
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt

@ -14,15 +14,11 @@ import io.legado.app.constant.AppConst.channelIdReadAloud
import io.legado.app.constant.AppConst.channelIdWeb import io.legado.app.constant.AppConst.channelIdWeb
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.help.BookHelp import io.legado.app.help.*
import io.legado.app.help.CrashHandler
import io.legado.app.help.LifecycleHelp
import io.legado.app.help.RuleBigDataHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ThemeConfig.applyDayNight import io.legado.app.help.config.ThemeConfig.applyDayNight
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.http.cronet.CronetLoader import io.legado.app.help.http.cronet.CronetLoader
import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.utils.defaultSharedPreferences import io.legado.app.utils.defaultSharedPreferences
import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.getPrefBoolean

@ -7,11 +7,11 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookProgress import io.legado.app.data.entities.BookProgress
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.CacheManager import io.legado.app.help.CacheManager
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.glide.ImageLoader import io.legado.app.help.glide.ImageLoader
import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.BookCover import io.legado.app.model.BookCover
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook

@ -1,4 +1,4 @@
package io.legado.app.help.storage package io.legado.app.help
import android.content.Context import android.content.Context
import io.legado.app.R import io.legado.app.R
@ -10,6 +10,8 @@ import io.legado.app.data.entities.BookProgress
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.Restore
import io.legado.app.lib.dialogs.selector import io.legado.app.lib.dialogs.selector
import io.legado.app.lib.webdav.Authorization import io.legado.app.lib.webdav.Authorization
import io.legado.app.lib.webdav.WebDav import io.legado.app.lib.webdav.WebDav
@ -29,13 +31,14 @@ import java.util.*
* webDav初始化会访问网络,不要放到主线程 * webDav初始化会访问网络,不要放到主线程
*/ */
object AppWebDav { object AppWebDav {
private const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/" const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/"
private val zipFilePath = "${appCtx.externalFiles.absolutePath}${File.separator}backup.zip" private val zipFilePath = "${appCtx.externalFiles.absolutePath}${File.separator}backup.zip"
private val bookProgressUrl get() = "${rootWebDavUrl}bookProgress/" private val bookProgressUrl get() = "${rootWebDavUrl}bookProgress/"
private val exportsWebDavUrl get() = "$rootWebDavUrl${EncoderUtils.escape("exports")}/" private val exportsWebDavUrl get() = "$rootWebDavUrl${EncoderUtils.escape("exports")}/"
val syncBookProgress get() = appCtx.getPrefBoolean(PreferKey.syncBookProgress, true) val syncBookProgress get() = appCtx.getPrefBoolean(PreferKey.syncBookProgress, true)
var authorization: Authorization? = null var authorization: Authorization? = null
private set
val isOk get() = authorization != null val isOk get() = authorization != null
@ -132,7 +135,7 @@ object AppWebDav {
suspend fun hasBackUp(): Boolean { suspend fun hasBackUp(): Boolean {
authorization?.let { authorization?.let {
val url = "${rootWebDavUrl}${backupFileName}" val url = "$rootWebDavUrl$backupFileName"
return WebDav(url, it).exists() return WebDav(url, it).exists()
} }
return false return false
@ -166,7 +169,7 @@ object AppWebDav {
} }
FileUtils.delete(zipFilePath) FileUtils.delete(zipFilePath)
if (ZipUtils.zipFiles(paths, zipFilePath)) { if (ZipUtils.zipFiles(paths, zipFilePath)) {
val putUrl = "${rootWebDavUrl}${backupFileName}" val putUrl = "$rootWebDavUrl$backupFileName"
WebDav(putUrl, it).upload(zipFilePath) WebDav(putUrl, it).upload(zipFilePath)
} }
} }

@ -6,6 +6,7 @@ import androidx.documentfile.provider.DocumentFile
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.help.AppWebDav
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadBookConfig
import io.legado.app.help.config.ThemeConfig import io.legado.app.help.config.ThemeConfig

@ -4,17 +4,16 @@ import io.legado.app.constant.AppLog
import io.legado.app.constant.BookType import io.legado.app.constant.BookType
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.* import io.legado.app.data.entities.*
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadBookConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.BaseReadAloudService import io.legado.app.service.BaseReadAloudService
import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.entities.TextChapter
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.book.read.page.provider.ImageProvider
import io.legado.app.utils.msg import io.legado.app.utils.msg
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope

@ -18,10 +18,10 @@ import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.storage.AppWebDav
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ensureActive import kotlinx.coroutines.ensureActive

@ -24,12 +24,12 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookProgress import io.legado.app.data.entities.BookProgress
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.IntentData import io.legado.app.help.IntentData
import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadBookConfig
import io.legado.app.help.config.ReadTipConfig import io.legado.app.help.config.ReadTipConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.AppWebDav
import io.legado.app.help.storage.Backup import io.legado.app.help.storage.Backup
import io.legado.app.lib.dialogs.SelectItem import io.legado.app.lib.dialogs.SelectItem
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert

@ -14,11 +14,11 @@ import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.BookProgress import io.legado.app.data.entities.BookProgress
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.ContentProcessor import io.legado.app.help.ContentProcessor
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.ReadAloud import io.legado.app.model.ReadAloud
import io.legado.app.model.ReadBook import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook

@ -2,7 +2,6 @@ package io.legado.app.ui.book.remote
import android.app.Application import android.app.Application
import android.net.Uri import android.net.Uri
import androidx.lifecycle.MutableLiveData
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.model.localBook.LocalBook import io.legado.app.model.localBook.LocalBook
import io.legado.app.ui.book.remote.manager.RemoteBookWebDav import io.legado.app.ui.book.remote.manager.RemoteBookWebDav
@ -13,11 +12,7 @@ import kotlinx.coroutines.flow.flowOn
import java.util.* import java.util.*
class RemoteBookViewModel(application: Application): BaseViewModel(application){ class RemoteBookViewModel(application: Application): BaseViewModel(application){
private val remoteBookFolderName = "book_remote"
private var dataCallback : DataCallback? = null private var dataCallback : DataCallback? = null
var isRemoteBookLiveData = MutableLiveData<Boolean>()
var dataFlowStart: (() -> Unit)? = null
val dataFlow = callbackFlow<List<RemoteBook>> { val dataFlow = callbackFlow<List<RemoteBook>> {
@ -41,15 +36,18 @@ class RemoteBookViewModel(application: Application): BaseViewModel(application){
trySend(emptyList()) trySend(emptyList())
} }
} }
// withContext(Dispatchers.Main) {
// dataFlowStart?.invoke()
// }
awaitClose { awaitClose {
dataCallback = null dataCallback = null
} }
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
init {
execute {
RemoteBookWebDav.initRemoteContext()
}
}
fun loadRemoteBookList() { fun loadRemoteBookList() {
execute { execute {
dataCallback?.clear() dataCallback?.clear()
@ -58,8 +56,6 @@ class RemoteBookViewModel(application: Application): BaseViewModel(application){
} }
} }
fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) { fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) {
execute { execute {
uriList.forEach { uriList.forEach {

@ -3,30 +3,22 @@ package io.legado.app.ui.book.remote.manager
import android.net.Uri import android.net.Uri
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.lib.webdav.Authorization
import io.legado.app.lib.webdav.WebDav import io.legado.app.lib.webdav.WebDav
import io.legado.app.lib.webdav.WebDavException
import io.legado.app.lib.webdav.WebDavFile import io.legado.app.lib.webdav.WebDavFile
import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.remote.RemoteBook import io.legado.app.ui.book.remote.RemoteBook
import io.legado.app.ui.book.remote.RemoteBookManager import io.legado.app.ui.book.remote.RemoteBookManager
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.nio.charset.Charset
object RemoteBookWebDav : RemoteBookManager() { object RemoteBookWebDav : RemoteBookManager() {
private const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/"
private var authorization: Authorization? = null
private val remoteBookUrl get() = "${rootWebDavUrl}${remoteBookFolder}" private val remoteBookUrl get() = "${rootWebDavUrl}${remoteBookFolder}"
private val localSaveFolder get() = "${appCtx.externalFiles.absolutePath}${File.separator}${remoteBookFolder}" private val localSaveFolder get() = "${appCtx.externalFiles.absolutePath}${File.separator}${remoteBookFolder}"
init { init {
runBlocking { runBlocking {
initRemoteContext() initRemoteContext()
@ -36,7 +28,7 @@ object RemoteBookWebDav : RemoteBookManager() {
private val rootWebDavUrl: String private val rootWebDavUrl: String
get() { get() {
val configUrl = appCtx.getPrefString(PreferKey.webDavUrl)?.trim() val configUrl = appCtx.getPrefString(PreferKey.webDavUrl)?.trim()
var url = if (configUrl.isNullOrEmpty()) defaultWebDavUrl else configUrl var url = if (configUrl.isNullOrEmpty()) AppWebDav.defaultWebDavUrl else configUrl
if (!url.endsWith("/")) url = "${url}/" if (!url.endsWith("/")) url = "${url}/"
AppConfig.webDavDir?.trim()?.let { AppConfig.webDavDir?.trim()?.let {
if (it.isNotEmpty()) { if (it.isNotEmpty()) {
@ -47,27 +39,17 @@ object RemoteBookWebDav : RemoteBookManager() {
} }
override suspend fun initRemoteContext() { override suspend fun initRemoteContext() {
kotlin.runCatching { AppWebDav.authorization?.let {
authorization = null WebDav(remoteBookUrl, it).makeAsDir()
val account = appCtx.getPrefString(PreferKey.webDavAccount)
val password = appCtx.getPrefString(PreferKey.webDavPassword)
if (!account.isNullOrBlank() && !password.isNullOrBlank()) {
val mAuthorization = Authorization(account, password)
WebDav(rootWebDavUrl, mAuthorization).makeAsDir()
WebDav(remoteBookUrl, mAuthorization).makeAsDir()
authorization = mAuthorization
}
}.onFailure {
it.printStackTrace()
} }
} }
@Throws(Exception::class) @Throws(Exception::class)
override suspend fun getRemoteBookList(): MutableList<RemoteBook> { override suspend fun getRemoteBookList(): MutableList<RemoteBook> {
val remoteBooks = mutableListOf<RemoteBook>() val remoteBooks = mutableListOf<RemoteBook>()
authorization?.let { AppWebDav.authorization?.let {
//读取文件列表 //读取文件列表
var remoteWebDavFileList : List<WebDavFile>? = null var remoteWebDavFileList: List<WebDavFile>? = null
kotlin.runCatching { kotlin.runCatching {
remoteWebDavFileList = WebDav(remoteBookUrl, it).listFiles() remoteWebDavFileList = WebDav(remoteBookUrl, it).listFiles()
} }
@ -97,8 +79,8 @@ object RemoteBookWebDav : RemoteBookManager() {
override suspend fun getRemoteBook(remoteBook: RemoteBook): String? { override suspend fun getRemoteBook(remoteBook: RemoteBook): String? {
val saveFilePath= "${localSaveFolder}${File.separator}${remoteBook.filename}" val saveFilePath= "${localSaveFolder}${File.separator}${remoteBook.filename}"
kotlin.runCatching { kotlin.runCatching {
authorization?.let { AppWebDav.authorization?.let {
FileUtils.createFolderIfNotExist(localSaveFolder).run{ FileUtils.createFolderIfNotExist(localSaveFolder).run {
val webdav = WebDav( val webdav = WebDav(
remoteBook.urlName, remoteBook.urlName,
it it
@ -122,10 +104,13 @@ object RemoteBookWebDav : RemoteBookManager() {
val localBookName = localBookUri.path?.substringAfterLast(File.separator) val localBookName = localBookUri.path?.substringAfterLast(File.separator)
val putUrl = "${remoteBookUrl}${File.separator}${localBookName}" val putUrl = "${remoteBookUrl}${File.separator}${localBookName}"
kotlin.runCatching { kotlin.runCatching {
authorization?.let { AppWebDav.authorization?.let {
if (localBookUri.isContentScheme()){ if (localBookUri.isContentScheme()) {
WebDav(putUrl, it).upload(byteArray = localBookUri.readBytes(appCtx),contentType = "application/octet-stream") WebDav(putUrl, it).upload(
}else{ byteArray = localBookUri.readBytes(appCtx),
contentType = "application/octet-stream"
)
} else {
WebDav(putUrl, it).upload(localBookUri.path!!) WebDav(putUrl, it).upload(localBookUri.path!!)
} }
} }

@ -17,10 +17,14 @@ import androidx.preference.Preference
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.help.AppWebDav
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.* import io.legado.app.help.storage.Backup
import io.legado.app.help.storage.BackupConfig
import io.legado.app.help.storage.ImportOldData
import io.legado.app.help.storage.Restore
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
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

@ -3,8 +3,8 @@ package io.legado.app.ui.config
import android.app.Application import android.app.Application
import io.legado.app.R import io.legado.app.R
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.storage.AppWebDav
import io.legado.app.utils.FileUtils import io.legado.app.utils.FileUtils
import io.legado.app.utils.toastOnUi import io.legado.app.utils.toastOnUi

@ -21,11 +21,11 @@ import io.legado.app.constant.AppConst.appInfo
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.databinding.ActivityMainBinding import io.legado.app.databinding.ActivityMainBinding
import io.legado.app.help.AppWebDav
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
import io.legado.app.help.storage.AppWebDav
import io.legado.app.help.storage.Backup import io.legado.app.help.storage.Backup
import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.elevation import io.legado.app.lib.theme.elevation

@ -10,10 +10,10 @@ import io.legado.app.constant.EventBus
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.BookSource
import io.legado.app.help.AppWebDav
import io.legado.app.help.DefaultData import io.legado.app.help.DefaultData
import io.legado.app.help.config.AppConfig import io.legado.app.help.config.AppConfig
import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.LocalConfig
import io.legado.app.help.storage.AppWebDav
import io.legado.app.model.CacheBook import io.legado.app.model.CacheBook
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
import io.legado.app.service.CacheBookService import io.legado.app.service.CacheBookService

Loading…
Cancel
Save