优化
This commit is contained in:
@@ -12,7 +12,13 @@
|
|||||||
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
|
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
|
||||||
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
|
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
|
||||||
|
|
||||||
|
**2023/08/02**
|
||||||
|
|
||||||
|
* 书签导出md格式
|
||||||
|
* 优化进度同步,减少webDav下载次数
|
||||||
|
|
||||||
**2023/07/30**
|
**2023/07/30**
|
||||||
|
|
||||||
* 更新cronet: 115.0.5790.138
|
* 更新cronet: 115.0.5790.138
|
||||||
|
|
||||||
* 更新cronet: 115.0.5790.136
|
* 更新cronet: 115.0.5790.136
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ object AppWebDav {
|
|||||||
/**
|
/**
|
||||||
* 获取云端所有背景名称
|
* 获取云端所有背景名称
|
||||||
*/
|
*/
|
||||||
suspend fun getAllBgNames(): Result<List<WebDavFile>> {
|
suspend fun getAllBgWebDavFiles(): Result<List<WebDavFile>> {
|
||||||
return kotlin.runCatching {
|
return kotlin.runCatching {
|
||||||
if (!NetworkUtils.isAvailable())
|
if (!NetworkUtils.isAvailable())
|
||||||
throw NoStackTraceException("网络未连接")
|
throw NoStackTraceException("网络未连接")
|
||||||
@@ -170,6 +170,21 @@ object AppWebDav {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传背景图片
|
||||||
|
*/
|
||||||
|
suspend fun upBgs(files: List<File>) {
|
||||||
|
val authorization = authorization ?: return
|
||||||
|
if (!NetworkUtils.isAvailable()) return
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载背景图片
|
||||||
|
*/
|
||||||
|
suspend fun downBgs(fileNames: String) {
|
||||||
|
val authorization = authorization ?: return
|
||||||
|
if (!NetworkUtils.isAvailable()) return
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun exportWebDav(byteArray: ByteArray, fileName: String) {
|
suspend fun exportWebDav(byteArray: ByteArray, fileName: String) {
|
||||||
if (!NetworkUtils.isAvailable()) return
|
if (!NetworkUtils.isAvailable()) return
|
||||||
|
|||||||
@@ -113,7 +113,9 @@ class Coroutine<T>(
|
|||||||
return this@Coroutine
|
return this@Coroutine
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果协程被取消,有可能会不执行
|
/**
|
||||||
|
* 如果协程被取消,不执行
|
||||||
|
*/
|
||||||
fun onFinally(
|
fun onFinally(
|
||||||
context: CoroutineContext? = null,
|
context: CoroutineContext? = null,
|
||||||
block: suspend CoroutineScope.() -> Unit
|
block: suspend CoroutineScope.() -> Unit
|
||||||
@@ -187,7 +189,9 @@ class Coroutine<T>(
|
|||||||
|
|
||||||
private suspend inline fun dispatchVoidCallback(scope: CoroutineScope, callback: VoidCallback) {
|
private suspend inline fun dispatchVoidCallback(scope: CoroutineScope, callback: VoidCallback) {
|
||||||
if (null == callback.context) {
|
if (null == callback.context) {
|
||||||
callback.block.invoke(scope)
|
withContext(scope.coroutineContext) {
|
||||||
|
callback.block.invoke(scope)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
withContext(scope.coroutineContext + callback.context) {
|
withContext(scope.coroutineContext + callback.context) {
|
||||||
callback.block.invoke(this)
|
callback.block.invoke(this)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.io.FileOutputStream
|
|||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备份
|
* 备份
|
||||||
@@ -92,113 +93,113 @@ object Backup {
|
|||||||
|
|
||||||
suspend fun backup(context: Context, path: String?) {
|
suspend fun backup(context: Context, path: String?) {
|
||||||
LocalConfig.lastBackup = System.currentTimeMillis()
|
LocalConfig.lastBackup = System.currentTimeMillis()
|
||||||
withContext(IO) {
|
val aes = BackupAES()
|
||||||
val aes = BackupAES()
|
FileUtils.delete(backupPath)
|
||||||
FileUtils.delete(backupPath)
|
writeListToJson(appDb.bookDao.all, "bookshelf.json", backupPath)
|
||||||
writeListToJson(appDb.bookDao.all, "bookshelf.json", backupPath)
|
writeListToJson(appDb.bookmarkDao.all, "bookmark.json", backupPath)
|
||||||
writeListToJson(appDb.bookmarkDao.all, "bookmark.json", backupPath)
|
writeListToJson(appDb.bookGroupDao.all, "bookGroup.json", backupPath)
|
||||||
writeListToJson(appDb.bookGroupDao.all, "bookGroup.json", backupPath)
|
writeListToJson(appDb.bookSourceDao.all, "bookSource.json", backupPath)
|
||||||
writeListToJson(appDb.bookSourceDao.all, "bookSource.json", backupPath)
|
writeListToJson(appDb.rssSourceDao.all, "rssSources.json", backupPath)
|
||||||
writeListToJson(appDb.rssSourceDao.all, "rssSources.json", backupPath)
|
writeListToJson(appDb.rssStarDao.all, "rssStar.json", backupPath)
|
||||||
writeListToJson(appDb.rssStarDao.all, "rssStar.json", backupPath)
|
writeListToJson(appDb.replaceRuleDao.all, "replaceRule.json", backupPath)
|
||||||
ensureActive()
|
writeListToJson(appDb.readRecordDao.all, "readRecord.json", backupPath)
|
||||||
writeListToJson(appDb.replaceRuleDao.all, "replaceRule.json", backupPath)
|
writeListToJson(appDb.searchKeywordDao.all, "searchHistory.json", backupPath)
|
||||||
writeListToJson(appDb.readRecordDao.all, "readRecord.json", backupPath)
|
writeListToJson(appDb.ruleSubDao.all, "sourceSub.json", backupPath)
|
||||||
writeListToJson(appDb.searchKeywordDao.all, "searchHistory.json", backupPath)
|
writeListToJson(appDb.txtTocRuleDao.all, "txtTocRule.json", backupPath)
|
||||||
writeListToJson(appDb.ruleSubDao.all, "sourceSub.json", backupPath)
|
writeListToJson(appDb.httpTTSDao.all, "httpTTS.json", backupPath)
|
||||||
writeListToJson(appDb.txtTocRuleDao.all, "txtTocRule.json", backupPath)
|
writeListToJson(appDb.keyboardAssistsDao.all, "keyboardAssists.json", backupPath)
|
||||||
writeListToJson(appDb.httpTTSDao.all, "httpTTS.json", backupPath)
|
writeListToJson(appDb.dictRuleDao.all, "dictRule.json", backupPath)
|
||||||
writeListToJson(appDb.keyboardAssistsDao.all, "keyboardAssists.json", backupPath)
|
GSON.toJson(appDb.serverDao.all).let { json ->
|
||||||
writeListToJson(appDb.dictRuleDao.all, "dictRule.json", backupPath)
|
aes.runCatching {
|
||||||
GSON.toJson(appDb.serverDao.all).let { json ->
|
encryptBase64(json)
|
||||||
aes.runCatching {
|
}.getOrDefault(json).let {
|
||||||
encryptBase64(json)
|
FileUtils.createFileIfNotExist(backupPath + File.separator + "servers.json")
|
||||||
}.getOrDefault(json).let {
|
|
||||||
FileUtils.createFileIfNotExist(backupPath + File.separator + "servers.json")
|
|
||||||
.writeText(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ensureActive()
|
|
||||||
GSON.toJson(ReadBookConfig.configList).let {
|
|
||||||
FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.configFileName)
|
|
||||||
.writeText(it)
|
.writeText(it)
|
||||||
}
|
}
|
||||||
GSON.toJson(ReadBookConfig.shareConfig).let {
|
}
|
||||||
FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.shareConfigFileName)
|
coroutineContext.ensureActive()
|
||||||
.writeText(it)
|
GSON.toJson(ReadBookConfig.configList).let {
|
||||||
}
|
FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.configFileName)
|
||||||
GSON.toJson(ThemeConfig.configList).let {
|
.writeText(it)
|
||||||
FileUtils.createFileIfNotExist(backupPath + File.separator + ThemeConfig.configFileName)
|
}
|
||||||
.writeText(it)
|
GSON.toJson(ReadBookConfig.shareConfig).let {
|
||||||
}
|
FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.shareConfigFileName)
|
||||||
DirectLinkUpload.getConfig()?.let {
|
.writeText(it)
|
||||||
FileUtils.createFileIfNotExist(backupPath + File.separator + DirectLinkUpload.ruleFileName)
|
}
|
||||||
.writeText(GSON.toJson(it))
|
GSON.toJson(ThemeConfig.configList).let {
|
||||||
}
|
FileUtils.createFileIfNotExist(backupPath + File.separator + ThemeConfig.configFileName)
|
||||||
ensureActive()
|
.writeText(it)
|
||||||
appCtx.getSharedPreferences(backupPath, "config")?.let { sp ->
|
}
|
||||||
val edit = sp.edit()
|
DirectLinkUpload.getConfig()?.let {
|
||||||
appCtx.defaultSharedPreferences.all.forEach { (key, value) ->
|
FileUtils.createFileIfNotExist(backupPath + File.separator + DirectLinkUpload.ruleFileName)
|
||||||
if (BackupConfig.keyIsNotIgnore(key)) {
|
.writeText(GSON.toJson(it))
|
||||||
when (key) {
|
}
|
||||||
PreferKey.webDavPassword -> {
|
coroutineContext.ensureActive()
|
||||||
edit.putString(key, aes.runCatching {
|
appCtx.getSharedPreferences(backupPath, "config")?.let { sp ->
|
||||||
encryptBase64(value.toString())
|
val edit = sp.edit()
|
||||||
}.getOrDefault(value.toString()))
|
appCtx.defaultSharedPreferences.all.forEach { (key, value) ->
|
||||||
}
|
if (BackupConfig.keyIsNotIgnore(key)) {
|
||||||
|
when (key) {
|
||||||
|
PreferKey.webDavPassword -> {
|
||||||
|
edit.putString(key, aes.runCatching {
|
||||||
|
encryptBase64(value.toString())
|
||||||
|
}.getOrDefault(value.toString()))
|
||||||
|
}
|
||||||
|
|
||||||
else -> when (value) {
|
else -> when (value) {
|
||||||
is Int -> edit.putInt(key, value)
|
is Int -> edit.putInt(key, value)
|
||||||
is Boolean -> edit.putBoolean(key, value)
|
is Boolean -> edit.putBoolean(key, value)
|
||||||
is Long -> edit.putLong(key, value)
|
is Long -> edit.putLong(key, value)
|
||||||
is Float -> edit.putFloat(key, value)
|
is Float -> edit.putFloat(key, value)
|
||||||
is String -> edit.putString(key, value)
|
is String -> edit.putString(key, value)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
edit.commit()
|
|
||||||
}
|
}
|
||||||
ensureActive()
|
edit.commit()
|
||||||
val zipFileName = getNowZipFileName()
|
|
||||||
val paths = arrayListOf(*backupFileNames)
|
|
||||||
for (i in 0 until paths.size) {
|
|
||||||
paths[i] = backupPath + File.separator + paths[i]
|
|
||||||
}
|
|
||||||
FileUtils.delete(zipFilePath)
|
|
||||||
FileUtils.delete(zipFilePath.replace("tmp_", ""))
|
|
||||||
val backupFileName = if (AppConfig.onlyLatestBackup) {
|
|
||||||
"backup.zip"
|
|
||||||
} else {
|
|
||||||
zipFileName
|
|
||||||
}
|
|
||||||
if (ZipUtils.zipFiles(paths, zipFilePath)) {
|
|
||||||
when {
|
|
||||||
path.isNullOrBlank() -> {
|
|
||||||
copyBackup(context.getExternalFilesDir(null)!!, backupFileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
path.isContentScheme() -> {
|
|
||||||
copyBackup(context, Uri.parse(path), backupFileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {
|
|
||||||
copyBackup(File(path), backupFileName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AppWebDav.backUpWebDav(zipFileName)
|
|
||||||
}
|
|
||||||
FileUtils.delete(backupPath)
|
|
||||||
FileUtils.delete(zipFilePath)
|
|
||||||
}
|
}
|
||||||
|
coroutineContext.ensureActive()
|
||||||
|
val zipFileName = getNowZipFileName()
|
||||||
|
val paths = arrayListOf(*backupFileNames)
|
||||||
|
for (i in 0 until paths.size) {
|
||||||
|
paths[i] = backupPath + File.separator + paths[i]
|
||||||
|
}
|
||||||
|
FileUtils.delete(zipFilePath)
|
||||||
|
FileUtils.delete(zipFilePath.replace("tmp_", ""))
|
||||||
|
val backupFileName = if (AppConfig.onlyLatestBackup) {
|
||||||
|
"backup.zip"
|
||||||
|
} else {
|
||||||
|
zipFileName
|
||||||
|
}
|
||||||
|
if (ZipUtils.zipFiles(paths, zipFilePath)) {
|
||||||
|
when {
|
||||||
|
path.isNullOrBlank() -> {
|
||||||
|
copyBackup(context.getExternalFilesDir(null)!!, backupFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
path.isContentScheme() -> {
|
||||||
|
copyBackup(context, Uri.parse(path), backupFileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
copyBackup(File(path), backupFileName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AppWebDav.backUpWebDav(zipFileName)
|
||||||
|
}
|
||||||
|
FileUtils.delete(backupPath)
|
||||||
|
FileUtils.delete(zipFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeListToJson(list: List<Any>, fileName: String, path: String) {
|
private suspend fun writeListToJson(list: List<Any>, fileName: String, path: String) {
|
||||||
if (list.isNotEmpty()) {
|
coroutineContext.ensureActive()
|
||||||
val file = FileUtils.createFileIfNotExist(path + File.separator + fileName)
|
withContext(IO) {
|
||||||
FileOutputStream(file).use { fos ->
|
if (list.isNotEmpty()) {
|
||||||
BufferedOutputStream(fos, 64 * 1024).use {
|
val file = FileUtils.createFileIfNotExist(path + File.separator + fileName)
|
||||||
GSON.writeToOutputStream(it, list)
|
FileOutputStream(file).use { fos ->
|
||||||
|
BufferedOutputStream(fos, 64 * 1024).use {
|
||||||
|
GSON.writeToOutputStream(it, list)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -269,7 +269,7 @@ class SearchActivity : VMBaseActivity<ActivityBookSearchBinding, SearchViewModel
|
|||||||
viewModel.searchBookLiveData.observe(this) {
|
viewModel.searchBookLiveData.observe(this) {
|
||||||
adapter.setItems(it)
|
adapter.setItems(it)
|
||||||
}
|
}
|
||||||
lifecycleScope.launch(IO) {
|
lifecycleScope.launch {
|
||||||
appDb.bookSourceDao.flowEnabledGroups().collect {
|
appDb.bookSourceDao.flowEnabledGroups().collect {
|
||||||
groups = it
|
groups = it
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user