diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index d5ff08514..426913043 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -14,6 +14,7 @@ import io.legado.app.model.ReadBook import io.legado.app.utils.GSON import io.legado.app.utils.MD5Utils import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.isUri import kotlinx.coroutines.runBlocking import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize @@ -108,7 +109,9 @@ data class Book( ) : Parcelable, BaseBook { fun isLocalBook(): Boolean { - return origin == BookType.local + //通过判断书籍链接来判断http* file:// content:// + //origin判断不可靠 http* BookType.local webDav:: + return origin == BookType.local || bookUrl.isUri() } fun isLocalTxt(): Boolean { diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt index 28a5593c1..97e7e2cfe 100644 --- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt +++ b/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 + } + } diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt index a21ab4aa8..b8571b3e3 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt +++ b/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() + } } } } diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt index 72f975c05..6116b5051 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt +++ b/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 - abstract suspend fun upload(localBookUri: Uri): Boolean + abstract suspend fun upload(book: Book): Boolean abstract suspend fun delete(remoteBookUrl: String): Boolean /** diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt index 49dc60b74..24615a770 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt +++ b/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 } } diff --git a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt b/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt index d5659fab7..1a02b06ff 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt +++ b/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 }