pull/1835/head
kunfei 3 years ago
parent 2d9ffadcba
commit d14f6e9bb3
  1. 31
      app/src/main/java/io/legado/app/help/storage/AppWebDav.kt
  2. 3
      app/src/main/java/io/legado/app/help/storage/Backup.kt
  3. 56
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  4. 16
      app/src/main/java/io/legado/app/lib/webdav/WebDavFile.kt

@ -14,6 +14,7 @@ import io.legado.app.lib.dialogs.selector
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.WebDavException
import io.legado.app.lib.webdav.WebDavFile
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
@ -80,19 +81,14 @@ object AppWebDav {
} }
@Throws(Exception::class) @Throws(Exception::class)
private suspend fun getWebDavFileNames(relativePath: String? = null): ArrayList<String> { private suspend fun getBackupNames(): ArrayList<String> {
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(rootWebDavUrl, it).listFiles()
files = files.reversed() files = files.reversed()
files.forEach { webDav -> files.forEach { webDav ->
val name = webDav.displayName val name = webDav.displayName
if (name?.startsWith("backup") == true) { if (name.startsWith("backup")) {
names.add(name) names.add(name)
} }
} }
@ -101,7 +97,7 @@ object AppWebDav {
} }
suspend fun showRestoreDialog(context: Context) { suspend fun showRestoreDialog(context: Context) {
val names = withContext(IO) { getWebDavFileNames() } val names = withContext(IO) { getBackupNames() }
if (names.isNotEmpty()) { if (names.isNotEmpty()) {
withContext(Main) { withContext(Main) {
context.selector( context.selector(
@ -134,12 +130,21 @@ object AppWebDav {
} }
} }
suspend fun hasBackUp(): Boolean { suspend fun lastBackUp(): WebDavFile? {
authorization?.let { authorization?.let {
val url = "${rootWebDavUrl}${backupFileName}" var lastBackupFile: WebDavFile? = null
return WebDav(url, it).exists() WebDav(rootWebDavUrl, it).listFiles().forEach { webDavFile ->
if (webDavFile.displayName.startsWith("backup")) {
if (lastBackupFile == null
|| webDavFile.lastModify > lastBackupFile!!.lastModify
) {
lastBackupFile = webDavFile
}
} }
return false }
return lastBackupFile
}
return null
} }
@Throws(Exception::class) @Throws(Exception::class)

@ -51,7 +51,8 @@ object Backup {
val lastBackup = LocalConfig.lastBackup val lastBackup = LocalConfig.lastBackup
if (lastBackup + TimeUnit.DAYS.toMillis(1) < System.currentTimeMillis()) { if (lastBackup + TimeUnit.DAYS.toMillis(1) < System.currentTimeMillis()) {
Coroutine.async { Coroutine.async {
if (!AppWebDav.hasBackUp()) { val lastBackupWebDav = AppWebDav.lastBackUp()
if (lastBackupWebDav == null || lastBackup > lastBackupWebDav.lastModify.time) {
backup(context, context.getPrefString(PreferKey.backupPath), true) backup(context, context.getPrefString(PreferKey.backupPath), true)
} else { } else {
LocalConfig.lastBackup = System.currentTimeMillis() LocalConfig.lastBackup = System.currentTimeMillis()

@ -1,5 +1,6 @@
package io.legado.app.lib.webdav package io.legado.app.lib.webdav
import android.annotation.SuppressLint
import io.legado.app.constant.AppLog import io.legado.app.constant.AppLog
import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.NoStackTraceException
import io.legado.app.help.http.newCallResponse import io.legado.app.help.http.newCallResponse
@ -18,10 +19,16 @@ import java.io.InputStream
import java.net.MalformedURLException import java.net.MalformedURLException
import java.net.URL import java.net.URL
import java.net.URLEncoder import java.net.URLEncoder
import java.text.SimpleDateFormat
import java.util.*
@Suppress("unused", "MemberVisibilityCanBePrivate") @Suppress("unused", "MemberVisibilityCanBePrivate")
class WebDav(urlStr: String, val authorization: Authorization) { open class WebDav(urlStr: String, val authorization: Authorization) {
companion object { companion object {
@SuppressLint("SimpleDateFormat")
private val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZ")
// 指定返回哪些属性 // 指定返回哪些属性
@Language("xml") @Language("xml")
private const val DIR = private const val DIR =
@ -50,11 +57,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
} }
val host: String? get() = url.host val host: String? get() = url.host
val path get() = url.toString() val path get() = url.toString()
var displayName: String? = null
var size: Long = 0
var parent = ""
var urlName = ""
var contentType = ""
/** /**
* 填充文件信息实例化WebDAVFile对象时并没有将远程文件的信息填充到实例中需要手动填充 * 填充文件信息实例化WebDAVFile对象时并没有将远程文件的信息填充到实例中需要手动填充
@ -70,7 +73,7 @@ class WebDav(urlStr: String, val authorization: Authorization) {
* @return 文件列表 * @return 文件列表
*/ */
@Throws(WebDavException::class) @Throws(WebDavException::class)
suspend fun listFiles(): List<WebDav> { suspend fun listFiles(): List<WebDavFile> {
propFindResponse()?.let { body -> propFindResponse()?.let { body ->
return parseDir(body) return parseDir(body)
} }
@ -108,8 +111,8 @@ class WebDav(urlStr: String, val authorization: Authorization) {
}.body?.text() }.body?.text()
} }
private fun parseDir(s: String): List<WebDav> { private fun parseDir(s: String): List<WebDavFile> {
val list = ArrayList<WebDav>() val list = ArrayList<WebDavFile>()
val document = Jsoup.parse(s) val document = Jsoup.parse(s)
val elements = document.getElementsByTag("d:response") val elements = document.getElementsByTag("d:response")
httpUrl?.let { urlStr -> httpUrl?.let { urlStr ->
@ -120,18 +123,31 @@ class WebDav(urlStr: String, val authorization: Authorization) {
val fileName = href.substring(href.lastIndexOf("/") + 1) val fileName = href.substring(href.lastIndexOf("/") + 1)
val webDavFile: WebDav val webDavFile: WebDav
try { try {
webDavFile = WebDav(baseUrl + fileName, authorization) val urlName = href.ifEmpty {
webDavFile.displayName = fileName url.file.replace("/", "")
webDavFile.contentType = element
.getElementsByTag("d:getcontenttype")
.getOrNull(0)?.text() ?: ""
if (href.isEmpty()) {
webDavFile.urlName =
if (parent.isEmpty()) url.file.replace("/", "")
else url.toString().replace(parent, "").replace("/", "")
} else {
webDavFile.urlName = href
} }
val contentType = element
.getElementsByTag("d:getcontenttype")
.firstOrNull()?.text().orEmpty()
val size = kotlin.runCatching {
element.getElementsByTag("d:getcontentlength")
.firstOrNull()?.text()?.toLong() ?: 0
}.getOrDefault(0)
val lastModify: Date = kotlin.runCatching {
element.getElementsByTag("d:getcontentlength")
.firstOrNull()?.text()?.let {
dateFormat.parse(it)
}
}.getOrNull() ?: Date()
webDavFile = WebDavFile(
baseUrl + fileName,
authorization,
displayName = fileName,
urlName = urlName,
size = size,
contentType = contentType,
lastModify = lastModify
)
list.add(webDavFile) list.add(webDavFile)
} catch (e: MalformedURLException) { } catch (e: MalformedURLException) {
e.printOnDebug() e.printOnDebug()

@ -0,0 +1,16 @@
package io.legado.app.lib.webdav
import java.util.*
/**
* webDavFile
*/
class WebDavFile(
urlStr: String,
authorization: Authorization,
val displayName: String,
val urlName: String,
val size: Long,
val contentType: String,
val lastModify: Date
) : WebDav(urlStr, authorization)
Loading…
Cancel
Save