feat: 实现本地文件不存在时自动下载webDav文件

pull/2365/head
Xwite 2 years ago
parent b5c6a17055
commit c6c0cf1ac1
  1. 42
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  2. 29
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  3. 3
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt
  4. 4
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt
  5. 11
      app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt

@ -7,6 +7,7 @@ import com.script.SimpleBindings
import io.legado.app.R import io.legado.app.R
import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.constant.BookType
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.BaseSource import io.legado.app.data.entities.BaseSource
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
@ -15,12 +16,15 @@ import io.legado.app.exception.NoStackTraceException
import io.legado.app.exception.TocEmptyException import io.legado.app.exception.TocEmptyException
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.AppWebDav
import io.legado.app.lib.webdav.WebDav
import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.utils.* import io.legado.app.utils.*
import org.jsoup.nodes.Entities import org.jsoup.nodes.Entities
import splitties.init.appCtx import splitties.init.appCtx
import java.io.* import java.io.*
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlinx.coroutines.runBlocking
/** /**
* 书籍文件导入 目录正文解析 * 书籍文件导入 目录正文解析
@ -38,13 +42,9 @@ object LocalBook {
@Throws(FileNotFoundException::class, SecurityException::class) @Throws(FileNotFoundException::class, SecurityException::class)
fun getBookInputStream(book: Book): InputStream { fun getBookInputStream(book: Book): InputStream {
val uri = Uri.parse(book.bookUrl) val uri = Uri.parse(book.bookUrl)
if (uri.isContentScheme()) { //文件不存在 尝试下载webDav文件 book.remoteUrl
return appCtx.contentResolver.openInputStream(uri)!! val inputStream = uri.inputStream(appCtx) ?: downloadRemoteBook(book)
} if (inputStream != null) return inputStream
val file = File(uri.path!!)
if (file.exists()) {
return FileInputStream(File(uri.path!!))
}
throw FileNotFoundException("${uri.path} 文件不存在") throw FileNotFoundException("${uri.path} 文件不存在")
} }
@ -302,4 +302,32 @@ object LocalBook {
return localBook return localBook
} }
//下载book.remoteUrl对应的远程文件并更新bookUrl 返回inputStream
private fun downloadRemoteBook(localBook: Book): InputStream? {
if (localBook.origin == BookType.local) return null
//webDav::${http}
val webDavUrl = localBook.origin.split("::").getOrNull(1)
webDavUrl ?: return null
try {
val uri = AppWebDav.authorization?.let {
val webdav = WebDav(webDavUrl, it)
runBlocking {
webdav.downloadInputStream().let { inputStream ->
saveBookFile(inputStream, localBook.originName)
}
}
}
return uri?.let {
localBook.bookUrl = if (it.isContentScheme()) it.toString()
else it.path!!
localBook.save()
it.inputStream(appCtx)
}
} catch (e: Exception) {
e.printOnDebug()
AppLog.put("自动下载webDav书籍失败", e)
}
return null
}
} }

@ -207,20 +207,21 @@ class BookInfoActivity :
R.id.menu_upload -> { R.id.menu_upload -> {
launch { launch {
val uri = Uri.parse(viewModel.bookData.value?.bookUrl.toString()) viewModel.bookData.value?.let {
val waitDialog = WaitDialog(this@BookInfoActivity) val waitDialog = WaitDialog(this@BookInfoActivity)
waitDialog.setText("上传中.....") waitDialog.setText("上传中.....")
waitDialog.show() waitDialog.show()
try { try {
val isUpload = RemoteBookWebDav.upload(uri) val isUpload = RemoteBookWebDav.upload(it)
if (isUpload) if (isUpload)
toastOnUi(getString(R.string.upload_book_success)) toastOnUi(getString(R.string.upload_book_success))
else else
toastOnUi(getString(R.string.upload_book_fail)) toastOnUi(getString(R.string.upload_book_fail))
} catch (e: Exception) { } catch (e: Exception) {
toastOnUi(e.localizedMessage) toastOnUi(e.localizedMessage)
} finally { } finally {
waitDialog.dismiss() waitDialog.dismiss()
}
} }
} }
} }

@ -1,12 +1,13 @@
package io.legado.app.ui.book.remote package io.legado.app.ui.book.remote
import android.net.Uri import android.net.Uri
import io.legado.app.data.entities.Book
abstract class RemoteBookManager { abstract class RemoteBookManager {
protected val remoteBookFolder : String = "books" protected val remoteBookFolder : String = "books"
abstract suspend fun initRemoteContext() abstract suspend fun initRemoteContext()
abstract suspend fun getRemoteBookList(path: String): MutableList<RemoteBook> abstract suspend fun getRemoteBookList(path: String): MutableList<RemoteBook>
abstract suspend fun upload(localBookUri: Uri): Boolean abstract suspend fun upload(book: Book): Boolean
abstract suspend fun delete(remoteBookUrl: String): Boolean abstract suspend fun delete(remoteBookUrl: String): Boolean
/** /**

@ -95,7 +95,9 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application)
remoteBooks.forEach { remoteBook -> remoteBooks.forEach { remoteBook ->
val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook) val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook)
downloadBookPath?.let { downloadBookPath?.let {
LocalBook.importFile(it) val localBook = LocalBook.importFile(it)
localBook.origin= "webDav::" + remoteBook.path
localBook.save()
remoteBook.isOnBookShelf = true remoteBook.isOnBookShelf = true
} }
} }

@ -1,8 +1,8 @@
package io.legado.app.ui.book.remote.manager package io.legado.app.ui.book.remote.manager
import android.net.Uri import android.net.Uri
import io.legado.app.constant.AppPattern.bookFileRegex import io.legado.app.constant.AppPattern.bookFileRegex
import io.legado.app.data.entities.Book
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.AppWebDav import io.legado.app.help.AppWebDav
import io.legado.app.lib.webdav.WebDav import io.legado.app.lib.webdav.WebDav
@ -85,11 +85,10 @@ object RemoteBookWebDav : RemoteBookManager() {
/** /**
* 上传本地导入的书籍到远程 * 上传本地导入的书籍到远程
*/ */
override suspend fun upload(localBookUri: Uri): Boolean { override suspend fun upload(book: Book): Boolean {
if (!NetworkUtils.isAvailable()) return false if (!NetworkUtils.isAvailable()) return false
val localBookUri = Uri.parse(book.bookUrl)
val localBookName = localBookUri.path?.substringAfterLast(File.separator) val putUrl = "${rootBookUrl}${File.separator}${book.originName}"
val putUrl = "${rootBookUrl}${File.separator}${localBookName}"
AppWebDav.authorization?.let { AppWebDav.authorization?.let {
if (localBookUri.isContentScheme()) { if (localBookUri.isContentScheme()) {
WebDav(putUrl, it).upload( WebDav(putUrl, it).upload(
@ -100,6 +99,8 @@ object RemoteBookWebDav : RemoteBookManager() {
WebDav(putUrl, it).upload(localBookUri.path!!) WebDav(putUrl, it).upload(localBookUri.path!!)
} }
} }
book.origin = "webDav::" + putUrl
book.save()
return true return true
} }

Loading…
Cancel
Save