优化
This commit is contained in:
@@ -7,9 +7,7 @@ import io.legado.app.exception.NoStackTraceException
|
|||||||
import io.legado.app.help.http.newCallResponse
|
import io.legado.app.help.http.newCallResponse
|
||||||
import io.legado.app.help.http.okHttpClient
|
import io.legado.app.help.http.okHttpClient
|
||||||
import io.legado.app.help.http.text
|
import io.legado.app.help.http.text
|
||||||
import io.legado.app.utils.NetworkUtils
|
import io.legado.app.utils.*
|
||||||
import io.legado.app.utils.printOnDebug
|
|
||||||
import io.legado.app.utils.toRequestBody
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
@@ -153,53 +151,51 @@ open class WebDav(val path: String, val authorization: Authorization) {
|
|||||||
private fun parseBody(s: String): List<WebDavFile> {
|
private fun parseBody(s: String): List<WebDavFile> {
|
||||||
val list = ArrayList<WebDavFile>()
|
val list = ArrayList<WebDavFile>()
|
||||||
val document = Jsoup.parse(s)
|
val document = Jsoup.parse(s)
|
||||||
val elements = document.getElementsByTag("d:response")
|
val ns = document.findNSPrefix("DAV:")
|
||||||
httpUrl?.let { urlStr ->
|
val elements = document.findNS("response", ns)
|
||||||
val baseUrl = NetworkUtils.getBaseUrl(urlStr)
|
val urlStr = httpUrl ?: return list
|
||||||
for (element in elements) {
|
val baseUrl = NetworkUtils.getBaseUrl(urlStr)
|
||||||
//依然是优化支持 caddy 自建的 WebDav ,其目录后缀都为“/”, 所以删除“/”的判定,不然无法获取该目录项
|
for (element in elements) {
|
||||||
var href = URLDecoder.decode(element.getElementsByTag("d:href")[0].text(), "UTF-8")
|
//依然是优化支持 caddy 自建的 WebDav ,其目录后缀都为“/”, 所以删除“/”的判定,不然无法获取该目录项
|
||||||
if (href.endsWith("/")) {
|
val href = URLDecoder.decode(element.findNS("href", ns)[0].text(), "UTF-8")
|
||||||
href = href.removeSuffix("/")
|
.removeSuffix("/")
|
||||||
}
|
val fileName = href.substringAfterLast("/")
|
||||||
val fileName = href.substring(href.lastIndexOf("/") + 1)
|
val webDavFile: WebDav
|
||||||
val webDavFile: WebDav
|
try {
|
||||||
try {
|
val urlName = href.ifEmpty {
|
||||||
val urlName = href.ifEmpty {
|
url.file.replace("/", "")
|
||||||
url.file.replace("/", "")
|
|
||||||
}
|
|
||||||
val contentType = element
|
|
||||||
.getElementsByTag("d:getcontenttype")
|
|
||||||
.firstOrNull()?.text().orEmpty()
|
|
||||||
val resourceType = element
|
|
||||||
.getElementsByTag("d:resourcetype")
|
|
||||||
.firstOrNull()?.html()?.trim().orEmpty()
|
|
||||||
val size = kotlin.runCatching {
|
|
||||||
element.getElementsByTag("d:getcontentlength")
|
|
||||||
.firstOrNull()?.text()?.toLong() ?: 0
|
|
||||||
}.getOrDefault(0)
|
|
||||||
val lastModify: Long = kotlin.runCatching {
|
|
||||||
element.getElementsByTag("d:getlastmodified")
|
|
||||||
.firstOrNull()?.text()?.let {
|
|
||||||
LocalDateTime.parse(it, dateTimeFormatter)
|
|
||||||
.toInstant(ZoneOffset.of("+8")).toEpochMilli()
|
|
||||||
}
|
|
||||||
}.getOrNull() ?: 0
|
|
||||||
val fullURL = NetworkUtils.getAbsoluteURL(baseUrl, href)
|
|
||||||
webDavFile = WebDavFile(
|
|
||||||
fullURL,
|
|
||||||
authorization,
|
|
||||||
displayName = fileName,
|
|
||||||
urlName = urlName,
|
|
||||||
size = size,
|
|
||||||
contentType = contentType,
|
|
||||||
resourceType = resourceType,
|
|
||||||
lastModify = lastModify
|
|
||||||
)
|
|
||||||
list.add(webDavFile)
|
|
||||||
} catch (e: MalformedURLException) {
|
|
||||||
e.printOnDebug()
|
|
||||||
}
|
}
|
||||||
|
val contentType = element
|
||||||
|
.findNS("getcontenttype", ns)
|
||||||
|
.firstOrNull()?.text().orEmpty()
|
||||||
|
val resourceType = element
|
||||||
|
.findNS("resourcetype", ns)
|
||||||
|
.firstOrNull()?.html()?.trim().orEmpty()
|
||||||
|
val size = kotlin.runCatching {
|
||||||
|
element.findNS("getcontentlength", ns)
|
||||||
|
.firstOrNull()?.text()?.toLong() ?: 0
|
||||||
|
}.getOrDefault(0)
|
||||||
|
val lastModify: Long = kotlin.runCatching {
|
||||||
|
element.findNS("getlastmodified", ns)
|
||||||
|
.firstOrNull()?.text()?.let {
|
||||||
|
LocalDateTime.parse(it, dateTimeFormatter)
|
||||||
|
.toInstant(ZoneOffset.of("+8")).toEpochMilli()
|
||||||
|
}
|
||||||
|
}.getOrNull() ?: 0
|
||||||
|
val fullURL = NetworkUtils.getAbsoluteURL(baseUrl, href)
|
||||||
|
webDavFile = WebDavFile(
|
||||||
|
fullURL,
|
||||||
|
authorization,
|
||||||
|
displayName = fileName,
|
||||||
|
urlName = urlName,
|
||||||
|
size = size,
|
||||||
|
contentType = contentType,
|
||||||
|
resourceType = resourceType,
|
||||||
|
lastModify = lastModify
|
||||||
|
)
|
||||||
|
list.add(webDavFile)
|
||||||
|
} catch (e: MalformedURLException) {
|
||||||
|
e.printOnDebug()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return list
|
return list
|
||||||
@@ -380,7 +376,9 @@ open class WebDav(val path: String, val authorization: Authorization) {
|
|||||||
val exception = document.getElementsByTag("s:exception").firstOrNull()?.text()
|
val exception = document.getElementsByTag("s:exception").firstOrNull()?.text()
|
||||||
val message = document.getElementsByTag("s:message").firstOrNull()?.text()
|
val message = document.getElementsByTag("s:message").firstOrNull()?.text()
|
||||||
if (exception == "ObjectNotFound") {
|
if (exception == "ObjectNotFound") {
|
||||||
throw ObjectNotFoundException(message ?: "$path doesn't exist. code:${response.code}")
|
throw ObjectNotFoundException(
|
||||||
|
message ?: "$path doesn't exist. code:${response.code}"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
throw WebDavException(message ?: "未知错误 code:${response.code}")
|
throw WebDavException(message ?: "未知错误 code:${response.code}")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.jsoup.nodes.CDataNode
|
|||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.nodes.Node
|
import org.jsoup.nodes.Node
|
||||||
import org.jsoup.nodes.TextNode
|
import org.jsoup.nodes.TextNode
|
||||||
|
import org.jsoup.select.Elements
|
||||||
import org.jsoup.select.NodeTraversor
|
import org.jsoup.select.NodeTraversor
|
||||||
import org.jsoup.select.NodeVisitor
|
import org.jsoup.select.NodeVisitor
|
||||||
|
|
||||||
@@ -37,6 +38,20 @@ fun Element.textArray(): Array<String> {
|
|||||||
return text.splitNotBlank("\n")
|
return text.splitNotBlank("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Element.findNS(tag: String, namespace: HashSet<String>): Elements {
|
||||||
|
return select("*|$tag").filter { el ->
|
||||||
|
namespace.contains(el.tagName().substringBefore(":"))
|
||||||
|
}.toElements()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Element.findNSPrefix(namespaceURI: String): HashSet<String> {
|
||||||
|
return select("[^xmlns]").map { element ->
|
||||||
|
element.attributes().filter { it.value == namespaceURI }.map { it.key.substring(6) }
|
||||||
|
}.flatten().toHashSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun List<Element>.toElements() = Elements(this)
|
||||||
|
|
||||||
private fun appendNormalisedText(sb: StringBuilder, textNode: TextNode) {
|
private fun appendNormalisedText(sb: StringBuilder, textNode: TextNode) {
|
||||||
val text = textNode.wholeText
|
val text = textNode.wholeText
|
||||||
if (preserveWhitespace(textNode.parentNode()) || textNode is CDataNode)
|
if (preserveWhitespace(textNode.parentNode()) || textNode is CDataNode)
|
||||||
|
|||||||
Reference in New Issue
Block a user