Merge remote-tracking branch 'origin/master'

This commit is contained in:
kunfei
2023-03-15 22:53:26 +08:00
2 changed files with 47 additions and 13 deletions
@@ -22,6 +22,7 @@ import io.legado.app.help.AppWebDav
import io.legado.app.help.book.*
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.webdav.ObjectNotFoundException
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.model.BookCover
import io.legado.app.model.ReadBook
import io.legado.app.model.localBook.LocalBook
@@ -242,7 +243,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
webFiles.clear()
val fileName = "${book.name} 作者:${book.author}"
book.downloadUrls!!.map {
val mFileName = UrlUtil.getFileName(it) ?: fileName
val mFileName = UrlUtil.getFileName(AnalyzeUrl(it, source = bookSource)) ?: fileName
WebFile(it, mFileName)
}
}.onError {
@@ -456,7 +457,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) {
}
// 后缀
val suffix: String = name.substringAfterLast(".")
val suffix: String = UrlUtil.getSuffix(name)
// txt epub umd pdf等文件
val isSupported: Boolean = AppPattern.bookFileRegex.matches(name)
@@ -1,5 +1,7 @@
package io.legado.app.utils
import io.legado.app.model.analyzeRule.AnalyzeUrl
import io.legado.app.constant.AppLog
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLDecoder
@@ -29,19 +31,33 @@ object UrlUtil {
.replace("|", "%7C")
}
/* 阅读定义的url,{urlOption} */
fun getFileName(analyzeUrl: AnalyzeUrl): String? {
return getFileName(analyzeUrl.url, analyzeUrl.headerMap)
}
/**
* 根据网络url获取文件名
* 根据网络url获取文件信息 文件
*/
fun getFileName(fileUrl: String): String? {
fun getFileName(fileUrl: String, headerMap: Map<String, String>? = null): String? {
// 如果获取到后缀可直接截取链接
if (getSuffix(fileUrl, "") != "") return fileUrl.substringAfterLast("/")
return kotlin.runCatching {
var fileName: String
var fileName: String = ""
val url = URL(fileUrl)
val conn: HttpURLConnection = url.openConnection() as HttpURLConnection
// head方式
// HEAD方式获取返回头信息
conn.requestMethod = "HEAD"
// 下载链接可能还需要书源header才能成功访问
headerMap?.forEach { key, value ->
conn.setRequestProperty(key, value)
}
conn.connect()
// 方法一
// val contentLength = conn.getContentLengthLong()
// Content-Disposition
// 解析文件名 filename= filename*=
val raw: String? = conn.getHeaderField("Content-Disposition")
if (raw != null && raw.indexOf("=") > 0) {
fileName = raw.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[1]
@@ -50,22 +66,39 @@ object UrlUtil {
fileName.toByteArray(StandardCharsets.ISO_8859_1),
StandardCharsets.UTF_8 //?
)
} else {
// 方法二 截取
} else if (conn.getHeaderField("Location") != null) {
// Location跳转到实际的下载链接
var newUrl: String = conn.url.path ?: return null
newUrl = URLDecoder.decode(newUrl, "UTF-8")
fileName = newUrl.substringAfterLast("/")
if (getSuffix(newUrl, "") != "") {
fileName = newUrl.substringAfterLast("/")
}
} else {
// 其余情况 返回响应头
val headers = conn.getHeaderFields()
val headersString = buildString {
headers.forEach { key, value ->
value.forEach {
append(key)
append(": ")
append(it)
append("\n")
}
}
}
AppLog.putDebug("Cannot obtain URL file name:\n$headersString")
}
fileName
}.getOrNull()
}
fun getSuffix(url: String, default: String): String {
val suffix = url.substringAfterLast(".").substringBeforeLast(",")
/* 获取合法的文件后缀 */
fun getSuffix(str: String, default: String? = null): String {
val suffix = str.substringAfterLast(".").substringBeforeLast(",")
//检查截取的后缀字符是否合法 [a-zA-Z0-9]
val fileSuffixRegex = Regex("^[a-z\\d]+$", RegexOption.IGNORE_CASE)
return if (suffix.length > 5 || !suffix.matches(fileSuffixRegex)) {
default
default ?: throw IllegalArgumentException("Cannot find illegal suffix:\n target: $str\nsuffix: $suffix")
} else {
suffix
}