kunfei 4 anni fa
parent
commit
753d01699a

+ 29 - 28
app/src/main/java/io/legado/app/help/storage/AppWebDav.kt

@@ -12,7 +12,7 @@ import io.legado.app.exception.NoStackTraceException
 import io.legado.app.help.config.AppConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.lib.dialogs.selector
-import io.legado.app.lib.webdav.HttpAuth
+import io.legado.app.lib.webdav.Authorization
 import io.legado.app.lib.webdav.WebDav
 import io.legado.app.utils.*
 import kotlinx.coroutines.Dispatchers.IO
@@ -31,7 +31,9 @@ object AppWebDav {
 
     val syncBookProgress get() = appCtx.getPrefBoolean(PreferKey.syncBookProgress, true)
 
-    var isOk = false
+    var authorization: Authorization? = null
+
+    val isOk get() = authorization != null
 
     init {
         runBlocking {
@@ -61,14 +63,15 @@ object AppWebDav {
 
     suspend fun upConfig() {
         kotlin.runCatching {
-            isOk = false
+            authorization = null
             val account = appCtx.getPrefString(PreferKey.webDavAccount)
             val password = appCtx.getPrefString(PreferKey.webDavPassword)
             if (!account.isNullOrBlank() && !password.isNullOrBlank()) {
-                HttpAuth.auth = HttpAuth.Auth(account, password)
-                WebDav(rootWebDavUrl).makeAsDir()
-                WebDav(bookProgressUrl).makeAsDir()
-                isOk = true
+                val mAuthorization = Authorization(account, password)
+                WebDav(rootWebDavUrl, mAuthorization).makeAsDir()
+                WebDav(bookProgressUrl, mAuthorization).makeAsDir()
+
+                authorization = mAuthorization
             }
         }
     }
@@ -77,18 +80,16 @@ object AppWebDav {
     private suspend fun getWebDavFileNames(): ArrayList<String> {
         val url = rootWebDavUrl
         val names = arrayListOf<String>()
-        if (isOk) {
-            var files = WebDav(url).listFiles()
+        authorization?.let {
+            var files = WebDav(url, it).listFiles()
             files = files.reversed()
-            files.forEach {
-                val name = it.displayName
+            files.forEach { webDav ->
+                val name = webDav.displayName
                 if (name?.startsWith("backup") == true) {
                     names.add(name)
                 }
             }
-        } else {
-            throw NoStackTraceException("webDav没有配置")
-        }
+        } ?: throw NoStackTraceException("webDav没有配置")
         return names
     }
 
@@ -115,8 +116,8 @@ object AppWebDav {
     }
 
     private suspend fun restoreWebDav(name: String) {
-        rootWebDavUrl.let {
-            val webDav = WebDav(it + name)
+        authorization?.let {
+            val webDav = WebDav(rootWebDavUrl + name, it)
             webDav.downloadTo(zipFilePath, true)
             @Suppress("BlockingMethodInNonBlockingContext")
             ZipUtils.unzipFile(zipFilePath, Backup.backupPath)
@@ -126,16 +127,16 @@ object AppWebDav {
     }
 
     suspend fun hasBackUp(): Boolean {
-        if (isOk) {
+        authorization?.let {
             val url = "${rootWebDavUrl}${backupFileName}"
-            return WebDav(url).exists()
+            return WebDav(url, it).exists()
         }
         return false
     }
 
     suspend fun backUpWebDav(path: String) {
         try {
-            if (isOk && NetworkUtils.isAvailable()) {
+            authorization?.let {
                 val paths = arrayListOf(*Backup.backupFileNames)
                 for (i in 0 until paths.size) {
                     paths[i] = path + File.separator + paths[i]
@@ -143,7 +144,7 @@ object AppWebDav {
                 FileUtils.delete(zipFilePath)
                 if (ZipUtils.zipFiles(paths, zipFilePath)) {
                     val putUrl = "${rootWebDavUrl}${backupFileName}"
-                    WebDav(putUrl).upload(zipFilePath)
+                    WebDav(putUrl, it).upload(zipFilePath)
                 }
             }
         } catch (e: Exception) {
@@ -153,14 +154,14 @@ object AppWebDav {
 
     suspend fun exportWebDav(byteArray: ByteArray, fileName: String) {
         try {
-            if (isOk && NetworkUtils.isAvailable()) {
+            authorization?.let {
                 // 默认导出到legado文件夹下exports目录
                 val exportsWebDavUrl = rootWebDavUrl + EncoderUtils.escape("exports") + "/"
                 // 在legado文件夹创建exports目录,如果不存在的话
-                WebDav(exportsWebDavUrl).makeAsDir()
+                WebDav(exportsWebDavUrl, it).makeAsDir()
                 // 如果导出的本地文件存在,开始上传
                 val putUrl = exportsWebDavUrl + fileName
-                WebDav(putUrl).upload(byteArray, "text/plain")
+                WebDav(putUrl, it).upload(byteArray, "text/plain")
             }
         } catch (e: Exception) {
             Handler(Looper.getMainLooper()).post {
@@ -170,14 +171,14 @@ object AppWebDav {
     }
 
     fun uploadBookProgress(book: Book) {
-        if (!isOk) return
+        val authorization = authorization ?: return
         if (!syncBookProgress) return
         if (!NetworkUtils.isAvailable()) return
         Coroutine.async {
             val bookProgress = BookProgress(book)
             val json = GSON.toJson(bookProgress)
             val url = getProgressUrl(book)
-            WebDav(url).upload(json.toByteArray(), "application/json")
+            WebDav(url, authorization).upload(json.toByteArray(), "application/json")
         }
     }
 
@@ -189,9 +190,9 @@ object AppWebDav {
      * 获取书籍进度
      */
     suspend fun getBookProgress(book: Book): BookProgress? {
-        if (isOk && NetworkUtils.isAvailable()) {
+        authorization?.let {
             val url = getProgressUrl(book)
-            WebDav(url).download()?.let { byteArray ->
+            WebDav(url, it).download()?.let { byteArray ->
                 val json = String(byteArray)
                 if (json.isJson()) {
                     return GSON.fromJsonObject<BookProgress>(json).getOrNull()
@@ -202,7 +203,7 @@ object AppWebDav {
     }
 
     suspend fun downloadAllBookProgress() {
-        if (!isOk) return
+        authorization ?: return
         appDb.bookDao.all.forEach { book ->
             getBookProgress(book)?.let { bookProgress ->
                 if (bookProgress.durChapterIndex > book.durChapterIndex ||

+ 19 - 0
app/src/main/java/io/legado/app/lib/webdav/Authorization.kt

@@ -0,0 +1,19 @@
+package io.legado.app.lib.webdav
+
+import okhttp3.Credentials
+import java.nio.charset.Charset
+import java.nio.charset.StandardCharsets
+
+data class Authorization(
+    val username: String,
+    val password: String,
+    val charset: Charset = StandardCharsets.ISO_8859_1
+) {
+
+    val data: String = Credentials.basic(username, password, charset)
+
+    override fun toString(): String {
+        return data
+    }
+
+}

+ 0 - 9
app/src/main/java/io/legado/app/lib/webdav/HttpAuth.kt

@@ -1,9 +0,0 @@
-package io.legado.app.lib.webdav
-
-object HttpAuth {
-
-    var auth: Auth? = null
-
-    class Auth internal constructor(val user: String, val pass: String)
-
-}

+ 58 - 74
app/src/main/java/io/legado/app/lib/webdav/WebDav.kt

@@ -1,17 +1,17 @@
 package io.legado.app.lib.webdav
 
+import android.util.Log
 import io.legado.app.constant.AppLog
+import io.legado.app.help.http.newCallResponse
 import io.legado.app.help.http.newCallResponseBody
 import io.legado.app.help.http.okHttpClient
 import io.legado.app.help.http.text
 import io.legado.app.utils.printOnDebug
-import okhttp3.Credentials
 import okhttp3.MediaType.Companion.toMediaType
 import okhttp3.RequestBody.Companion.asRequestBody
 import okhttp3.RequestBody.Companion.toRequestBody
 import org.intellij.lang.annotations.Language
 import org.jsoup.Jsoup
-
 import java.io.File
 import java.io.InputStream
 import java.net.MalformedURLException
@@ -19,7 +19,7 @@ import java.net.URL
 import java.net.URLEncoder
 
 @Suppress("unused", "MemberVisibilityCanBePrivate")
-class WebDav(urlStr: String) {
+class WebDav(urlStr: String, val authorization: Authorization) {
     companion object {
         // 指定返回哪些属性
         @Language("xml")
@@ -88,24 +88,20 @@ class WebDav(urlStr: String) {
         } else {
             String.format(DIR, requestProps.toString() + "\n")
         }
-        val url = httpUrl
-        val auth = HttpAuth.auth
-        if (url != null && auth != null) {
-            return kotlin.runCatching {
-                okHttpClient.newCallResponseBody {
-                    url(url)
-                    addHeader("Authorization", Credentials.basic(auth.user, auth.pass))
-                    addHeader("Depth", "1")
-                    // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性
-                    // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。
-                    val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType())
-                    method("PROPFIND", requestBody)
-                }.text()
-            }.onFailure { e ->
-                e.printOnDebug()
-            }.getOrNull()
-        }
-        return null
+        val url = httpUrl ?: return null
+        return kotlin.runCatching {
+            okHttpClient.newCallResponseBody {
+                url(url)
+                addHeader("Authorization", authorization.data)
+                addHeader("Depth", "1")
+                // 添加RequestBody对象,可以只返回的属性。如果设为null,则会返回全部属性
+                // 注意:尽量手动指定需要返回的属性。若返回全部属性,可能后由于Prop.java里没有该属性名,而崩溃。
+                val requestBody = requestPropsStr.toRequestBody("text/plain".toMediaType())
+                method("PROPFIND", requestBody)
+            }.text()
+        }.onFailure { e ->
+            e.printOnDebug()
+        }.getOrNull()
     }
 
     private fun parseDir(s: String): List<WebDav> {
@@ -120,7 +116,7 @@ class WebDav(urlStr: String) {
                     val fileName = href.substring(href.lastIndexOf("/") + 1)
                     val webDavFile: WebDav
                     try {
-                        webDavFile = WebDav(baseUrl + fileName)
+                        webDavFile = WebDav(baseUrl + fileName, authorization)
                         webDavFile.displayName = fileName
                         webDavFile.contentType = element
                             .getElementsByTag("d:getcontenttype")
@@ -157,23 +153,19 @@ class WebDav(urlStr: String) {
      * @return 是否创建成功
      */
     suspend fun makeAsDir(): Boolean {
-        val url = httpUrl
-        val auth = HttpAuth.auth
-        if (url != null && auth != null) {
-            //防止报错
-            return kotlin.runCatching {
-                if (!exists()) {
-                    okHttpClient.newCallResponseBody {
-                        url(url)
-                        method("MKCOL", null)
-                        addHeader("Authorization", Credentials.basic(auth.user, auth.pass))
-                    }.close()
-                }
-            }.onFailure {
-                AppLog.put(it.localizedMessage)
-            }.isSuccess
-        }
-        return false
+        val url = httpUrl ?: return false
+        //防止报错
+        return kotlin.runCatching {
+            if (!exists()) {
+                okHttpClient.newCallResponseBody {
+                    url(url)
+                    method("MKCOL", null)
+                    addHeader("Authorization", authorization.data)
+                }.close()
+            }
+        }.onFailure {
+            AppLog.put(it.localizedMessage)
+        }.isSuccess
     }
 
     /**
@@ -208,49 +200,41 @@ class WebDav(urlStr: String) {
         if (!file.exists()) return false
         // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
         val fileBody = file.asRequestBody(contentType.toMediaType())
-        val url = httpUrl
-        val auth = HttpAuth.auth
-        if (url != null && auth != null) {
-            return kotlin.runCatching {
-                okHttpClient.newCallResponseBody {
-                    url(url)
-                    put(fileBody)
-                    addHeader("Authorization", Credentials.basic(auth.user, auth.pass))
-                }.close()
-            }.isSuccess
-        }
-        return false
+        val url = httpUrl ?: return false
+        return kotlin.runCatching {
+            okHttpClient.newCallResponse {
+                url(url)
+                put(fileBody)
+                addHeader("Authorization", authorization.data)
+            }.body?.string()?.let {
+                Log.d("webDav", it)
+            }
+        }.onFailure {
+            it.printOnDebug()
+        }.isSuccess
     }
 
     suspend fun upload(byteArray: ByteArray, contentType: String): Boolean {
         // 务必注意RequestBody不要嵌套,不然上传时内容可能会被追加多余的文件信息
         val fileBody = byteArray.toRequestBody(contentType.toMediaType())
-        val url = httpUrl
-        val auth = HttpAuth.auth
-        if (url != null && auth != null) {
-            return kotlin.runCatching {
-                okHttpClient.newCallResponseBody {
-                    url(url)
-                    put(fileBody)
-                    addHeader("Authorization", Credentials.basic(auth.user, auth.pass))
-                }.close()
-            }.isSuccess
-        }
-        return false
+        val url = httpUrl ?: return false
+        return kotlin.runCatching {
+            okHttpClient.newCallResponseBody {
+                url(url)
+                put(fileBody)
+                addHeader("Authorization", authorization.data)
+            }.close()
+        }.isSuccess
     }
 
     private suspend fun getInputStream(): InputStream? {
-        val url = httpUrl
-        val auth = HttpAuth.auth
-        if (url != null && auth != null) {
-            return kotlin.runCatching {
-                okHttpClient.newCallResponseBody {
-                    url(url)
-                    addHeader("Authorization", Credentials.basic(auth.user, auth.pass))
-                }.byteStream()
-            }.getOrNull()
-        }
-        return null
+        val url = httpUrl ?: return null
+        return kotlin.runCatching {
+            okHttpClient.newCallResponseBody {
+                url(url)
+                addHeader("Authorization", authorization.data)
+            }.byteStream()
+        }.getOrNull()
     }
 
 }