فهرست منبع

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

Xwite 4 سال پیش
والد
کامیت
bd5c13ef8a

+ 35 - 7
app/src/main/java/io/legado/app/model/localBook/LocalBook.kt

@@ -7,6 +7,7 @@ import com.script.SimpleBindings
 import io.legado.app.R
 import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppLog
+import io.legado.app.constant.BookType
 import io.legado.app.data.appDb
 import io.legado.app.data.entities.BaseSource
 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.help.BookHelp
 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.utils.*
 import org.jsoup.nodes.Entities
 import splitties.init.appCtx
 import java.io.*
 import java.util.regex.Pattern
+import kotlinx.coroutines.runBlocking
 
 /**
  * 书籍文件导入 目录正文解析
@@ -38,13 +42,9 @@ object LocalBook {
     @Throws(FileNotFoundException::class, SecurityException::class)
     fun getBookInputStream(book: Book): InputStream {
         val uri = Uri.parse(book.bookUrl)
-        if (uri.isContentScheme()) {
-            return appCtx.contentResolver.openInputStream(uri)!!
-        }
-        val file = File(uri.path!!)
-        if (file.exists()) {
-            return FileInputStream(File(uri.path!!))
-        }
+        //文件不存在 尝试下载webDav文件 book.remoteUrl
+        val inputStream = uri.inputStream(appCtx) ?: downloadRemoteBook(book)
+        if (inputStream != null) return inputStream
         throw FileNotFoundException("${uri.path} 文件不存在")
     }
 
@@ -302,4 +302,32 @@ object 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
+    }
+
 }

+ 15 - 14
app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt

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

+ 2 - 1
app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt

@@ -1,12 +1,13 @@
 package io.legado.app.ui.book.remote
 
 import android.net.Uri
+import io.legado.app.data.entities.Book
 
 abstract class RemoteBookManager {
     protected val remoteBookFolder : String = "books"
     abstract suspend fun initRemoteContext()
     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
 
     /**

+ 3 - 1
app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt

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

+ 6 - 5
app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt

@@ -1,8 +1,8 @@
 package io.legado.app.ui.book.remote.manager
 
-
 import android.net.Uri
 import io.legado.app.constant.AppPattern.bookFileRegex
+import io.legado.app.data.entities.Book
 import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.AppWebDav
 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
-
-        val localBookName = localBookUri.path?.substringAfterLast(File.separator)
-        val putUrl = "${rootBookUrl}${File.separator}${localBookName}"
+        val localBookUri = Uri.parse(book.bookUrl)
+        val putUrl = "${rootBookUrl}${File.separator}${book.originName}"
         AppWebDav.authorization?.let {
             if (localBookUri.isContentScheme()) {
                 WebDav(putUrl, it).upload(
@@ -100,6 +99,8 @@ object RemoteBookWebDav : RemoteBookManager() {
                 WebDav(putUrl, it).upload(localBookUri.path!!)
             }
         }
+        book.origin = "webDav::" + putUrl
+        book.save()
         return true
     }