feat: 实现本地文件不存在时自动下载webDav文件
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user