Merge pull request #2365 from Xwite/master
feat: 实现本地文件不存在时自动下载webDav文件
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -207,12 +207,12 @@ class BookInfoActivity :
|
||||
|
||||
R.id.menu_upload -> {
|
||||
launch {
|
||||
val uri = Uri.parse(viewModel.bookData.value?.bookUrl.toString())
|
||||
viewModel.bookData.value?.let {
|
||||
val waitDialog = WaitDialog(this@BookInfoActivity)
|
||||
waitDialog.setText("上传中.....")
|
||||
waitDialog.show()
|
||||
try {
|
||||
val isUpload = RemoteBookWebDav.upload(uri)
|
||||
val isUpload = RemoteBookWebDav.upload(it)
|
||||
if (isUpload)
|
||||
toastOnUi(getString(R.string.upload_book_success))
|
||||
else
|
||||
@@ -225,6 +225,7 @@ class BookInfoActivity :
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onCompatOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user