优化
This commit is contained in:
@@ -17,6 +17,7 @@ object AppPattern {
|
|||||||
val nameRegex = Regex("\\s+作\\s*者.*|\\s+\\S+\\s+著")
|
val nameRegex = Regex("\\s+作\\s*者.*|\\s+\\S+\\s+著")
|
||||||
val authorRegex = Regex("^\\s*作\\s*者[::\\s]+|\\s+著")
|
val authorRegex = Regex("^\\s*作\\s*者[::\\s]+|\\s+著")
|
||||||
val fileNameRegex = Regex("[\\\\/:*?\"<>|.]")
|
val fileNameRegex = Regex("[\\\\/:*?\"<>|.]")
|
||||||
|
val fileNameRegex2 = Regex("[\\\\/:*?\"<>|]")
|
||||||
val splitGroupRegex = Regex("[,;,;]")
|
val splitGroupRegex = Regex("[,;,;]")
|
||||||
val titleNumPattern: Pattern = Pattern.compile("(第)(.+?)(章)")
|
val titleNumPattern: Pattern = Pattern.compile("(第)(.+?)(章)")
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ import io.legado.app.utils.compress.ZipUtils
|
|||||||
import io.legado.app.utils.fromJsonObject
|
import io.legado.app.utils.fromJsonObject
|
||||||
import io.legado.app.utils.getPrefString
|
import io.legado.app.utils.getPrefString
|
||||||
import io.legado.app.utils.isJson
|
import io.legado.app.utils.isJson
|
||||||
|
import io.legado.app.utils.normalizeFileName
|
||||||
import io.legado.app.utils.removePref
|
import io.legado.app.utils.removePref
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
|
import kotlinx.coroutines.currentCoroutineContext
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.coroutines.coroutineContext
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* webDav初始化会访问网络,不要放到主线程
|
* webDav初始化会访问网络,不要放到主线程
|
||||||
@@ -219,7 +220,7 @@ object AppWebDav {
|
|||||||
WebDav(putUrl, it).upload(byteArray, "text/plain")
|
WebDav(putUrl, it).upload(byteArray, "text/plain")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
coroutineContext.ensureActive()
|
currentCoroutineContext().ensureActive()
|
||||||
AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
|
AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,12 +234,16 @@ object AppWebDav {
|
|||||||
WebDav(putUrl, it).upload(uri, "text/plain")
|
WebDav(putUrl, it).upload(uri, "text/plain")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
coroutineContext.ensureActive()
|
currentCoroutineContext().ensureActive()
|
||||||
AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
|
AppLog.put("WebDav导出失败\n${e.localizedMessage}", e, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun uploadBookProgress(book: Book) {
|
suspend fun uploadBookProgress(
|
||||||
|
book: Book,
|
||||||
|
toast: Boolean = false,
|
||||||
|
onSuccess: (() -> Unit)? = null
|
||||||
|
) {
|
||||||
val authorization = authorization ?: return
|
val authorization = authorization ?: return
|
||||||
if (!AppConfig.syncBookProgress) return
|
if (!AppConfig.syncBookProgress) return
|
||||||
if (!NetworkUtils.isAvailable()) return
|
if (!NetworkUtils.isAvailable()) return
|
||||||
@@ -248,9 +253,10 @@ object AppWebDav {
|
|||||||
val url = getProgressUrl(book.name, book.author)
|
val url = getProgressUrl(book.name, book.author)
|
||||||
WebDav(url, authorization).upload(json.toByteArray(), "application/json")
|
WebDav(url, authorization).upload(json.toByteArray(), "application/json")
|
||||||
book.syncTime = System.currentTimeMillis()
|
book.syncTime = System.currentTimeMillis()
|
||||||
|
onSuccess?.invoke()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
coroutineContext.ensureActive()
|
currentCoroutineContext().ensureActive()
|
||||||
AppLog.put("上传进度失败\n${e.localizedMessage}", e)
|
AppLog.put("上传进度失败\n${e.localizedMessage}", e, toast)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +270,7 @@ object AppWebDav {
|
|||||||
WebDav(url, authorization).upload(json.toByteArray(), "application/json")
|
WebDav(url, authorization).upload(json.toByteArray(), "application/json")
|
||||||
onSuccess?.invoke()
|
onSuccess?.invoke()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
coroutineContext.ensureActive()
|
currentCoroutineContext().ensureActive()
|
||||||
AppLog.put("上传进度失败\n${e.localizedMessage}", e)
|
AppLog.put("上传进度失败\n${e.localizedMessage}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -274,26 +280,25 @@ object AppWebDav {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getProgressFileName(name: String, author: String): String {
|
private fun getProgressFileName(name: String, author: String): String {
|
||||||
return UrlUtil.replaceReservedChar("${name}_${author}") + ".json"
|
return UrlUtil.replaceReservedChar("${name}_${author}".normalizeFileName()) + ".json"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取书籍进度
|
* 获取书籍进度
|
||||||
*/
|
*/
|
||||||
suspend fun getBookProgress(book: Book): BookProgress? {
|
suspend fun getBookProgress(book: Book): BookProgress? {
|
||||||
authorization?.let {
|
val url = getProgressUrl(book.name, book.author)
|
||||||
val url = getProgressUrl(book.name, book.author)
|
kotlin.runCatching {
|
||||||
kotlin.runCatching {
|
val authorization = authorization ?: return null
|
||||||
WebDav(url, it).download().let { byteArray ->
|
WebDav(url, authorization).download().let { byteArray ->
|
||||||
val json = String(byteArray)
|
val json = String(byteArray)
|
||||||
if (json.isJson()) {
|
if (json.isJson()) {
|
||||||
return GSON.fromJsonObject<BookProgress>(json).getOrNull()
|
return GSON.fromJsonObject<BookProgress>(json).getOrNull()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.onFailure {
|
|
||||||
coroutineContext.ensureActive()
|
|
||||||
AppLog.put("获取书籍进度失败\n${it.localizedMessage}", it)
|
|
||||||
}
|
}
|
||||||
|
}.onFailure {
|
||||||
|
currentCoroutineContext().ensureActive()
|
||||||
|
AppLog.put("获取书籍进度失败\n${it.localizedMessage}", it)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.legado.app.utils.exists
|
|||||||
import io.legado.app.utils.find
|
import io.legado.app.utils.find
|
||||||
import io.legado.app.utils.inputStream
|
import io.legado.app.utils.inputStream
|
||||||
import io.legado.app.utils.isUri
|
import io.legado.app.utils.isUri
|
||||||
|
import io.legado.app.utils.normalizeFileName
|
||||||
import io.legado.app.utils.toastOnUi
|
import io.legado.app.utils.toastOnUi
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -346,7 +347,7 @@ fun Book.getExportFileName(
|
|||||||
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
RhinoScriptEngine.eval(jsStr, bindings).toString() + "." + suffix
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
AppLog.put("导出书名规则错误,使用默认规则\n${it.localizedMessage}", it)
|
AppLog.put("导出书名规则错误,使用默认规则\n${it.localizedMessage}", it)
|
||||||
}.getOrDefault(default)
|
}.getOrDefault(default).normalizeFileName()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据当前日期计算章节总数
|
// 根据当前日期计算章节总数
|
||||||
|
|||||||
@@ -14,8 +14,20 @@ import io.legado.app.help.config.LocalConfig
|
|||||||
import io.legado.app.help.config.ReadBookConfig
|
import io.legado.app.help.config.ReadBookConfig
|
||||||
import io.legado.app.help.config.ThemeConfig
|
import io.legado.app.help.config.ThemeConfig
|
||||||
import io.legado.app.help.coroutine.Coroutine
|
import io.legado.app.help.coroutine.Coroutine
|
||||||
import io.legado.app.utils.*
|
import io.legado.app.utils.FileUtils
|
||||||
|
import io.legado.app.utils.GSON
|
||||||
|
import io.legado.app.utils.LogUtils
|
||||||
import io.legado.app.utils.compress.ZipUtils
|
import io.legado.app.utils.compress.ZipUtils
|
||||||
|
import io.legado.app.utils.createFolderIfNotExist
|
||||||
|
import io.legado.app.utils.defaultSharedPreferences
|
||||||
|
import io.legado.app.utils.externalFiles
|
||||||
|
import io.legado.app.utils.getFile
|
||||||
|
import io.legado.app.utils.getSharedPreferences
|
||||||
|
import io.legado.app.utils.isContentScheme
|
||||||
|
import io.legado.app.utils.normalizeFileName
|
||||||
|
import io.legado.app.utils.openOutputStream
|
||||||
|
import io.legado.app.utils.outputStream
|
||||||
|
import io.legado.app.utils.writeToOutputStream
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@@ -26,7 +38,8 @@ import java.io.File
|
|||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.coroutineContext
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
@@ -77,7 +90,7 @@ object Backup {
|
|||||||
"backup${backupDate}-${deviceName}.zip"
|
"backup${backupDate}-${deviceName}.zip"
|
||||||
} else {
|
} else {
|
||||||
"backup${backupDate}.zip"
|
"backup${backupDate}.zip"
|
||||||
}
|
}.normalizeFileName()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shouldBackup(): Boolean {
|
private fun shouldBackup(): Boolean {
|
||||||
|
|||||||
@@ -224,13 +224,14 @@ object ReadBook : CoroutineScope by MainScope() {
|
|||||||
nextTextChapter?.clearSearchResult()
|
nextTextChapter?.clearSearchResult()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun uploadProgress(successAction: (() -> Unit)? = null) {
|
fun uploadProgress(toast: Boolean = false, successAction: (() -> Unit)? = null) {
|
||||||
book?.let {
|
book?.let {
|
||||||
launch(IO) {
|
launch(IO) {
|
||||||
AppWebDav.uploadBookProgress(it)
|
AppWebDav.uploadBookProgress(it, toast) {
|
||||||
|
successAction?.invoke()
|
||||||
|
}
|
||||||
ensureActive()
|
ensureActive()
|
||||||
it.update()
|
it.update()
|
||||||
successAction?.invoke()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -482,10 +482,11 @@ object ReadManga : CoroutineScope by MainScope() {
|
|||||||
fun uploadProgress(successAction: (() -> Unit)? = null) {
|
fun uploadProgress(successAction: (() -> Unit)? = null) {
|
||||||
book?.let {
|
book?.let {
|
||||||
launch(IO) {
|
launch(IO) {
|
||||||
AppWebDav.uploadBookProgress(it)
|
AppWebDav.uploadBookProgress(it) {
|
||||||
|
successAction?.invoke()
|
||||||
|
}
|
||||||
ensureActive()
|
ensureActive()
|
||||||
it.update()
|
it.update()
|
||||||
successAction?.invoke()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ class ReadBookActivity : BaseReadBookActivity(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_cover_progress -> ReadBook.book?.let {
|
R.id.menu_cover_progress -> ReadBook.book?.let {
|
||||||
ReadBook.uploadProgress { toastOnUi(R.string.upload_book_success) }
|
ReadBook.uploadProgress(true) { toastOnUi(R.string.upload_book_success) }
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_same_title_removed -> {
|
R.id.menu_same_title_removed -> {
|
||||||
|
|||||||
@@ -140,3 +140,7 @@ fun String.escapeRegex(): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun String.encodeURI(): String = URLEncodeUtil.encodeQuery(this)
|
fun String.encodeURI(): String = URLEncodeUtil.encodeQuery(this)
|
||||||
|
|
||||||
|
fun String.normalizeFileName(): String {
|
||||||
|
return replace(AppPattern.fileNameRegex2, "_")
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ viewpager2 = "1.0.0"
|
|||||||
webkit = "1.13.0"
|
webkit = "1.13.0"
|
||||||
collection = "1.5.0"
|
collection = "1.5.0"
|
||||||
|
|
||||||
zxingLite = "3.2.0"
|
zxingLite = "3.3.0"
|
||||||
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
|
|||||||
Reference in New Issue
Block a user