Merge pull request #2365 from Xwite/master

feat: 实现本地文件不存在时自动下载webDav文件
pull/2368/head
kunfei 2 years ago committed by GitHub
commit e230d92131
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      app/src/main/java/io/legado/app/data/entities/Book.kt
  2. 42
      app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
  3. 5
      app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
  4. 3
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt
  5. 4
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt
  6. 11
      app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.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 {

@ -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
}

Loading…
Cancel
Save