fix: 修复上传以及下载的部分BUG,功能已经基本可用

pull/1894/head
谢意帆 3 years ago
parent f05350f490
commit 1c8a0fd000
  1. 12
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookActivity.kt
  2. 9
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookAdapter.kt
  3. 14
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookManager.kt
  4. 47
      app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt
  5. 42
      app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt
  6. 4
      app/src/main/res/layout/item_remote_book.xml

@ -1,5 +1,6 @@
package io.legado.app.ui.book.remote package io.legado.app.ui.book.remote
import android.annotation.SuppressLint
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -46,8 +47,8 @@ class RemoteBookActivity : VMBaseActivity<ActivityRemoteBookBinding,RemoteBookVi
// viewModel.getRemoteBooks().observe(this, { // viewModel.getRemoteBooks().observe(this, {
// adapter.submitList(it) // adapter.submitList(it)
// }) // })
// viewModel.loadRemoteBookList() binding.refreshProgressBar.isAutoLoading = true
viewModel.loadRemoteBookList()
launch { launch {
viewModel.dataFlow.collect { remoteBooks -> viewModel.dataFlow.collect { remoteBooks ->
adapter.setItems(remoteBooks) adapter.setItems(remoteBooks)
@ -60,7 +61,10 @@ class RemoteBookActivity : VMBaseActivity<ActivityRemoteBookBinding,RemoteBookVi
} }
override fun download(remoteBook: RemoteBook) { @SuppressLint("NotifyDataSetChanged")
viewModel.downloadRemoteBook(remoteBook.urlName) override fun addToBookshelf(remoteBook: RemoteBook) {
viewModel.addToBookshelf(remoteBook){
adapter.notifyDataSetChanged()
}
} }
} }

@ -38,7 +38,7 @@ class RemoteBookAdapter (context: Context, val callBack: CallBack) :
payloads: MutableList<Any> payloads: MutableList<Any>
) { ) {
binding.run { binding.run {
tvName.text = item.filename tvName.text = item.filename.substringBeforeLast(".")
tvContentType.text = item.contentType tvContentType.text = item.contentType
tvSize.text = ConvertUtils.formatFileSize(item.size) tvSize.text = ConvertUtils.formatFileSize(item.size)
tvDate.text = LocalDateTimeUtil.format(LocalDateTimeUtil.of(item.lastModify), "yyyy-MM-dd") tvDate.text = LocalDateTimeUtil.format(LocalDateTimeUtil.of(item.lastModify), "yyyy-MM-dd")
@ -48,8 +48,9 @@ class RemoteBookAdapter (context: Context, val callBack: CallBack) :
override fun registerListener(holder: ItemViewHolder, binding: ItemRemoteBookBinding) { override fun registerListener(holder: ItemViewHolder, binding: ItemRemoteBookBinding) {
binding.btnDownload.setOnClickListener { binding.btnDownload.setOnClickListener {
getItem(holder.layoutPosition)?.let { getItem(holder.layoutPosition)?.let {
context.toastOnUi("开始下载") context.toastOnUi("开始加入")
callBack.download(it) callBack.addToBookshelf(it)
context.toastOnUi("加入成功")
} }
} }
@ -57,6 +58,6 @@ class RemoteBookAdapter (context: Context, val callBack: CallBack) :
} }
interface CallBack { interface CallBack {
fun download(remoteBook: RemoteBook) fun addToBookshelf(remoteBook: RemoteBook)
} }
} }

@ -1,13 +1,7 @@
package io.legado.app.ui.book.remote package io.legado.app.ui.book.remote
import android.content.ContentResolver
import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.provider.MediaStore
import android.provider.OpenableColumns
import android.webkit.MimeTypeMap
import java.io.File
import kotlin.random.Random
abstract class RemoteBookManager { abstract class RemoteBookManager {
@ -17,5 +11,9 @@ abstract class RemoteBookManager {
abstract suspend fun getRemoteBookList(): MutableList<RemoteBook> abstract suspend fun getRemoteBookList(): MutableList<RemoteBook>
abstract suspend fun upload(localBookUri: Uri): Boolean abstract suspend fun upload(localBookUri: Uri): Boolean
abstract suspend fun delete(remoteBookUrl: String): Boolean abstract suspend fun delete(remoteBookUrl: String): Boolean
abstract suspend fun getRemoteBook(remoteBookUrl: String): RemoteBook
/**
* @return String下载到本地的路径
*/
abstract suspend fun getRemoteBook(remoteBook: RemoteBook): String?
} }

@ -55,56 +55,37 @@ class RemoteBookViewModel(application: Application): BaseViewModel(application){
// } // }
awaitClose { awaitClose {
// dataCallback = null dataCallback = null
} }
}.flowOn(Dispatchers.IO) }.flowOn(Dispatchers.IO)
fun loadRemoteBookList() { fun loadRemoteBookList() {
execute { execute {
dataCallback?.clear() dataCallback?.clear()
RemoteBookWebDav.getRemoteBookList() val bookList = RemoteBookWebDav.getRemoteBookList()
dataCallback?.setItems(bookList)
} }
// dataCallback?.setItems()
} }
// dataCallback?.setItems(listOf("1", "2", "3"))
fun downloadRemoteBook(urlName: String) {
val saveFolder = "${appCtx.externalFiles.absolutePath}${File.separator}${remoteBookFolderName}"
val trueCodeURLName = String(urlName.toByteArray(Charset.forName("GBK")), Charset.forName("UTF-8"))
val saveFilePath = "${saveFolder}${trueCodeURLName}"
execute {
kotlin.runCatching {
authorization = null
val account = appCtx.getPrefString(PreferKey.webDavAccount)
val password = appCtx.getPrefString(PreferKey.webDavPassword)
if (!account.isNullOrBlank() && !password.isNullOrBlank()) {
val mAuthorization = Authorization(account, password)
authorization = mAuthorization
}
}
authorization?.let { it -> fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) {
FileUtils.createFolderIfNotExist(saveFolder).run{ execute {
withTimeout(15000L) { uriList.forEach {
val webdav = WebDav( LocalBook.importFile(Uri.parse(it))
"http://txc.qianfanguojin.top${trueCodeURLName}",
it
)
webdav.downloadTo(saveFilePath, true)
}
}
} }
}.onFinally { }.onFinally {
addToBookshelf(hashSetOf("${saveFolder}${trueCodeURLName}")){ finally.invoke()
Log.e("TAG", "downloadRemoteBook: add", )
} }
} }
} /**
fun addToBookshelf(uriList: HashSet<String>, finally: () -> Unit) { * 添加书籍到本地书架
*/
fun addToBookshelf(remoteBook: RemoteBook, finally: () -> Unit) {
execute { execute {
uriList.forEach { val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook)
downloadBookPath?.let {
LocalBook.importFile(Uri.parse(it)) LocalBook.importFile(Uri.parse(it))
} }
}.onFinally { }.onFinally {

@ -9,6 +9,7 @@ import io.legado.app.help.config.AppConfig
import io.legado.app.lib.webdav.Authorization import io.legado.app.lib.webdav.Authorization
import io.legado.app.lib.webdav.WebDav import io.legado.app.lib.webdav.WebDav
import io.legado.app.lib.webdav.WebDavException
import io.legado.app.lib.webdav.WebDavFile import io.legado.app.lib.webdav.WebDavFile
import io.legado.app.ui.book.info.BookInfoActivity import io.legado.app.ui.book.info.BookInfoActivity
@ -16,6 +17,7 @@ import io.legado.app.ui.book.remote.RemoteBook
import io.legado.app.ui.book.remote.RemoteBookManager import io.legado.app.ui.book.remote.RemoteBookManager
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import splitties.init.appCtx import splitties.init.appCtx
import java.io.File import java.io.File
import java.nio.charset.Charset import java.nio.charset.Charset
@ -24,7 +26,7 @@ object RemoteBookWebDav : RemoteBookManager() {
private const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/" private const val defaultWebDavUrl = "https://dav.jianguoyun.com/dav/"
private var authorization: Authorization? = null private var authorization: Authorization? = null
private val remoteBookUrl get() = "${rootWebDavUrl}${remoteBookFolder}" private val remoteBookUrl get() = "${rootWebDavUrl}${remoteBookFolder}"
private val localSaveFolder get() = "${appCtx.externalFiles.absolutePath}${File.separator}${remoteBookFolder}"
init { init {
runBlocking { runBlocking {
initRemoteContext() initRemoteContext()
@ -63,38 +65,52 @@ object RemoteBookWebDav : RemoteBookManager() {
@Throws(Exception::class) @Throws(Exception::class)
override suspend fun getRemoteBookList(): MutableList<RemoteBook> { override suspend fun getRemoteBookList(): MutableList<RemoteBook> {
val remoteBooks = mutableListOf<RemoteBook>() val remoteBooks = mutableListOf<RemoteBook>()
authorization?.let { authorization?.let {
//读取文件列表
var remoteWebDavFileList : List<WebDavFile>? = null var remoteWebDavFileList : List<WebDavFile>? = null
kotlin.runCatching { kotlin.runCatching {
remoteWebDavFileList = WebDav(remoteBookUrl, it).listFiles() remoteWebDavFileList = WebDav(remoteBookUrl, it).listFiles()
} }
//逆序文件排序
remoteWebDavFileList = remoteWebDavFileList!!.reversed() remoteWebDavFileList = remoteWebDavFileList!!.reversed()
//转化远程文件信息到本地对象
remoteWebDavFileList!!.forEach { webDavFile -> remoteWebDavFileList!!.forEach { webDavFile ->
val webDavFileName = webDavFile.displayName val webDavFileName = webDavFile.displayName
val webDavUrlName = webDavFile.urlName val webDavUrlName = "${remoteBookUrl}${File.separator}${webDavFile.displayName}"
// 转码 // 转码
val trueFileName = String(webDavFileName.toByteArray(Charset.forName("GBK")), Charset.forName("UTF-8")) //val trueFileName = String(webDavFileName.toByteArray(Charset.forName("GBK")), Charset.forName("UTF-8"))
val trueUrlName = String(webDavUrlName.toByteArray(Charset.forName("GBK")), Charset.forName("UTF-8")) //val trueUrlName = String(webDavUrlName.toByteArray(Charset.forName("GBK")), Charset.forName("UTF-8"))
//分割文件名和后缀 //分割后缀
val filename = trueFileName.substringBeforeLast(".") val fileExtension = webDavFileName.substringAfterLast(".")
val fileExtension = trueFileName.substringAfterLast(".")
//扩展名符合阅读的格式则认为是书籍 //扩展名符合阅读的格式则认为是书籍
if (contentTypeList.contains(fileExtension)) { if (contentTypeList.contains(fileExtension)) {
remoteBooks.add(RemoteBook(filename,trueUrlName,webDavFile.size,fileExtension,webDavFile.lastModify)) remoteBooks.add(RemoteBook(webDavFileName,webDavUrlName,webDavFile.size,fileExtension,webDavFile.lastModify))
} }
} }
} ?: throw NoStackTraceException("webDav没有配置") } ?: throw NoStackTraceException("webDav没有配置")
return remoteBooks return remoteBooks
} }
override suspend fun getRemoteBook(remoteBookUrl: String): RemoteBook { override suspend fun getRemoteBook(remoteBook: RemoteBook): String? {
TODO("Not yet implemented") val saveFilePath= "${localSaveFolder}${File.separator}${remoteBook.filename}"
kotlin.runCatching {
authorization?.let {
FileUtils.createFolderIfNotExist(localSaveFolder).run{
val webdav = WebDav(
remoteBook.urlName,
it
)
webdav.downloadTo(saveFilePath, true)
}
}
}.onFailure {
it.printStackTrace()
return null
}
return saveFilePath
} }
/** /**

@ -97,12 +97,12 @@
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
> >
<Button <Button
android:id="@+id/btn_download" android:id="@+id/btn_download"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="下载" android:text="加入书架">
>
</Button> </Button>
</LinearLayout> </LinearLayout>

Loading…
Cancel
Save