pull/1827/head
kunfei 3 years ago
parent 26de00c284
commit 32156d92b0
  1. 10
      app/src/main/java/io/legado/app/help/storage/AppWebDav.kt
  2. 30
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  3. 9
      app/src/main/java/io/legado/app/lib/webdav/WebDavException.kt
  4. 2
      app/src/main/java/io/legado/app/ui/config/BackupConfigFragment.kt

@ -79,8 +79,12 @@ object AppWebDav {
} }
@Throws(Exception::class) @Throws(Exception::class)
private suspend fun getWebDavFileNames(): ArrayList<String> { private suspend fun getWebDavFileNames(relativePath: String? = null): ArrayList<String> {
val url = rootWebDavUrl val url = if (relativePath == null) {
rootWebDavUrl
} else {
NetworkUtils.getAbsoluteURL(rootWebDavUrl, relativePath)
}
val names = arrayListOf<String>() val names = arrayListOf<String>()
authorization?.let { authorization?.let {
var files = WebDav(url, it).listFiles() var files = WebDav(url, it).listFiles()
@ -107,7 +111,7 @@ object AppWebDav {
Coroutine.async { Coroutine.async {
restoreWebDav(names[index]) restoreWebDav(names[index])
}.onError { }.onError {
appCtx.toastOnUi("WebDavError:${it.localizedMessage}") appCtx.toastOnUi("WebDavError\n${it.localizedMessage}")
} }
} }
} }

@ -69,6 +69,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
* *
* @return 文件列表 * @return 文件列表
*/ */
@Throws(WebDavException::class)
suspend fun listFiles(): List<WebDav> { suspend fun listFiles(): List<WebDav> {
propFindResponse()?.let { body -> propFindResponse()?.let { body ->
return parseDir(body) return parseDir(body)
@ -79,6 +80,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
/** /**
* @param propsList 指定列出文件的哪些属性 * @param propsList 指定列出文件的哪些属性
*/ */
@Throws(WebDavException::class)
private suspend fun propFindResponse(propsList: List<String> = emptyList()): String? { private suspend fun propFindResponse(propsList: List<String> = emptyList()): String? {
val requestProps = StringBuilder() val requestProps = StringBuilder()
for (p in propsList) { for (p in propsList) {
@ -90,8 +92,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
String.format(DIR, requestProps.toString() + "\n") String.format(DIR, requestProps.toString() + "\n")
} }
val url = httpUrl ?: return null val url = httpUrl ?: return null
return kotlin.runCatching { return okHttpClient.newCallResponse {
okHttpClient.newCallResponseBody {
url(url) url(url)
addHeader(authorization.name, authorization.data) addHeader(authorization.name, authorization.data)
addHeader("Depth", "1") addHeader("Depth", "1")
@ -99,10 +100,9 @@ class WebDav(urlStr: String, val authorization: Authorization) {
// 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。 // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。
val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType()) val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType())
method("PROPFIND", requestBody) method("PROPFIND", requestBody)
}.text() }.apply {
}.onFailure { e -> checkResult(this)
e.printOnDebug() }.body?.text()
}.getOrNull()
} }
private fun parseDir(s: String): List<WebDav> { private fun parseDir(s: String): List<WebDav> {
@ -143,10 +143,14 @@ class WebDav(urlStr: String, val authorization: Authorization) {
* 文件是否存在 * 文件是否存在
*/ */
suspend fun exists(): Boolean { suspend fun exists(): Boolean {
return kotlin.runCatching {
val response = propFindResponse() ?: return false val response = propFindResponse() ?: return false
val document = Jsoup.parse(response) val document = Jsoup.parse(response)
val elements = document.getElementsByTag("d:response") val elements = document.getElementsByTag("d:response")
return elements.isNotEmpty() return elements.isNotEmpty()
}.onFailure {
AppLog.put("WebDav检测是否存在出错\n${it.localizedMessage}")
}.getOrDefault(false)
} }
/** /**
@ -195,17 +199,17 @@ class WebDav(urlStr: String, val authorization: Authorization) {
/** /**
* 上传文件 * 上传文件
*/ */
@Throws(Exception::class) @Throws(WebDavException::class)
suspend fun upload( suspend fun upload(
localPath: String, localPath: String,
contentType: String = "application/octet-stream" contentType: String = "application/octet-stream"
) { ) {
kotlin.runCatching { kotlin.runCatching {
val file = File(localPath) val file = File(localPath)
if (!file.exists()) throw NoStackTraceException("文件不存在") if (!file.exists()) throw WebDavException("文件不存在")
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
val fileBody = file.asRequestBody(contentType.toMediaType()) val fileBody = file.asRequestBody(contentType.toMediaType())
val url = httpUrl ?: throw NoStackTraceException("url不能为空") val url = httpUrl ?: throw WebDavException("url不能为空")
okHttpClient.newCallResponse { okHttpClient.newCallResponse {
url(url) url(url)
put(fileBody) put(fileBody)
@ -214,11 +218,11 @@ class WebDav(urlStr: String, val authorization: Authorization) {
checkResult(it) checkResult(it)
} }
}.onFailure { }.onFailure {
throw NoStackTraceException("WebDav上传失败\n${it.localizedMessage}") throw WebDavException("WebDav上传失败\n${it.localizedMessage}")
} }
} }
@Throws(Exception::class) @Throws(WebDavException::class)
suspend fun upload(byteArray: ByteArray, contentType: String) { suspend fun upload(byteArray: ByteArray, contentType: String) {
// 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息 // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
kotlin.runCatching { kotlin.runCatching {
@ -232,7 +236,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
checkResult(it) checkResult(it)
} }
}.onFailure { }.onFailure {
throw NoStackTraceException("WebDav上传失败\n${it.localizedMessage}") throw WebDavException("WebDav上传失败\n${it.localizedMessage}")
} }
} }
@ -248,7 +252,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
private fun checkResult(response: Response) { private fun checkResult(response: Response) {
if (!response.isSuccessful) { if (!response.isSuccessful) {
throw NoStackTraceException("${url}\n${response.code}:${response.message}") throw WebDavException("${url}\n${response.code}:${response.message}")
} }
} }

@ -0,0 +1,9 @@
package io.legado.app.lib.webdav
class WebDavException(msg: String) : Exception(msg) {
override fun fillInStackTrace(): Throwable {
return this
}
}

@ -292,7 +292,7 @@ class BackupConfigFragment : BasePreferenceFragment(),
}.onError { }.onError {
alert { alert {
setTitle(R.string.restore) setTitle(R.string.restore)
setMessage("WebDavError:${it.localizedMessage}\n将从本地备份恢复。") setMessage("WebDavError\n${it.localizedMessage}\n将从本地备份恢复。")
okButton { okButton {
restoreFromLocal() restoreFromLocal()
} }

Loading…
Cancel
Save