备份问题
This commit is contained in:
@@ -9,7 +9,9 @@ import io.legado.app.data.entities.Book
|
||||
import io.legado.app.data.entities.BookProgress
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.LocalConfig
|
||||
import io.legado.app.help.storage.Backup
|
||||
import io.legado.app.help.storage.BackupRestoreLock
|
||||
import io.legado.app.help.storage.Restore
|
||||
import io.legado.app.lib.webdav.Authorization
|
||||
import io.legado.app.lib.webdav.WebDav
|
||||
@@ -122,10 +124,13 @@ object AppWebDav {
|
||||
suspend fun restoreWebDav(name: String) {
|
||||
authorization?.let {
|
||||
val webDav = WebDav(rootWebDavUrl + name, it)
|
||||
webDav.downloadTo(Backup.zipFilePath, true)
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
ZipUtils.unZipToPath(File(Backup.zipFilePath), Backup.backupPath)
|
||||
Restore.restoreLocked(Backup.backupPath)
|
||||
BackupRestoreLock.withLock {
|
||||
webDav.downloadTo(Backup.zipFilePath, true)
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
ZipUtils.unZipToPath(File(Backup.zipFilePath), Backup.backupPath)
|
||||
Restore.restoreUnzipped(Backup.backupPath)
|
||||
LocalConfig.lastBackup = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ import io.legado.app.data.entities.Book
|
||||
import io.legado.app.data.entities.BookProgress
|
||||
import io.legado.app.exception.NoStackTraceException
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.help.config.LocalConfig
|
||||
import io.legado.app.help.storage.Backup
|
||||
import io.legado.app.help.storage.BackupRestoreLock
|
||||
import io.legado.app.help.storage.Restore
|
||||
import io.legado.app.lib.webdav.Authorization
|
||||
import io.legado.app.lib.webdav.WebDav
|
||||
@@ -137,10 +139,13 @@ class WebDavManager(
|
||||
val auth = requireAuthorization()
|
||||
val rootUrl = buildRootUrl(configFlow.value)
|
||||
val webDav = WebDav(rootUrl + name, auth)
|
||||
webDav.downloadTo(Backup.zipFilePath, true)
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
ZipUtils.unZipToPath(File(Backup.zipFilePath), Backup.backupPath)
|
||||
Restore.restoreLocked(Backup.backupPath)
|
||||
BackupRestoreLock.withLock {
|
||||
webDav.downloadTo(Backup.zipFilePath, true)
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
ZipUtils.unZipToPath(File(Backup.zipFilePath), Backup.backupPath)
|
||||
Restore.restoreUnzipped(Backup.backupPath)
|
||||
LocalConfig.lastBackup = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun hasBackUp(backUpName: String): Boolean {
|
||||
|
||||
@@ -34,8 +34,6 @@ import io.legado.app.utils.writeToOutputStream
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import splitties.init.appCtx
|
||||
import java.io.File
|
||||
@@ -58,8 +56,6 @@ object Backup {
|
||||
|
||||
private const val TAG = "Backup"
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
||||
private val backupFileNames by lazy {
|
||||
arrayOf(
|
||||
"bookshelf.json",
|
||||
@@ -107,7 +103,7 @@ object Backup {
|
||||
fun autoBack(context: Context) {
|
||||
if (shouldBackup()) {
|
||||
Coroutine.async {
|
||||
mutex.withLock {
|
||||
BackupRestoreLock.withLock {
|
||||
if (shouldBackup()) {
|
||||
val backupZipFileName = getNowZipFileName()
|
||||
if (!AppWebDav.hasBackUp(backupZipFileName)) {
|
||||
@@ -124,7 +120,7 @@ object Backup {
|
||||
}
|
||||
|
||||
suspend fun backupLocked(context: Context, path: String?, mode: String = "both") {
|
||||
mutex.withLock {
|
||||
BackupRestoreLock.withLock {
|
||||
withContext(IO) {
|
||||
backup(context, path, mode)
|
||||
}
|
||||
|
||||
@@ -55,8 +55,6 @@ import io.legado.app.utils.openInputStream
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
@@ -70,40 +68,45 @@ import java.io.FileInputStream
|
||||
object Restore : KoinComponent {
|
||||
|
||||
private val settingsRepository: SettingsRepository by inject()
|
||||
private val mutex = Mutex()
|
||||
|
||||
private const val TAG = "Restore"
|
||||
|
||||
suspend fun restore(context: Context, uri: Uri) {
|
||||
LogUtils.d(TAG, "开始恢复备份 uri:$uri")
|
||||
kotlin.runCatching {
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
if (uri.isContentScheme()) {
|
||||
DocumentFile.fromSingleUri(context, uri)!!.openInputStream()!!.use {
|
||||
ZipUtils.unZipToPath(it, Backup.backupPath)
|
||||
BackupRestoreLock.withLock {
|
||||
LogUtils.d(TAG, "开始恢复备份 uri:$uri")
|
||||
val unzipResult = kotlin.runCatching {
|
||||
FileUtils.delete(Backup.backupPath)
|
||||
if (uri.isContentScheme()) {
|
||||
DocumentFile.fromSingleUri(context, uri)!!.openInputStream()!!.use {
|
||||
ZipUtils.unZipToPath(it, Backup.backupPath)
|
||||
}
|
||||
} else {
|
||||
ZipUtils.unZipToPath(File(uri.path!!), Backup.backupPath)
|
||||
}
|
||||
}.onFailure {
|
||||
AppLog.put("复制解压文件出错\n${it.localizedMessage}", it)
|
||||
}
|
||||
if (unzipResult.isSuccess) {
|
||||
kotlin.runCatching {
|
||||
restoreUnzipped(Backup.backupPath)
|
||||
LocalConfig.lastBackup = System.currentTimeMillis()
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi("恢复备份出错\n${it.localizedMessage}")
|
||||
AppLog.put("恢复备份出错\n${it.localizedMessage}", it)
|
||||
}
|
||||
} else {
|
||||
ZipUtils.unZipToPath(File(uri.path!!), Backup.backupPath)
|
||||
}
|
||||
}.onFailure {
|
||||
AppLog.put("复制解压文件出错\n${it.localizedMessage}", it)
|
||||
return
|
||||
}
|
||||
kotlin.runCatching {
|
||||
restoreLocked(Backup.backupPath)
|
||||
LocalConfig.lastBackup = System.currentTimeMillis()
|
||||
}.onFailure {
|
||||
appCtx.toastOnUi("恢复备份出错\n${it.localizedMessage}")
|
||||
AppLog.put("恢复备份出错\n${it.localizedMessage}", it)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun restoreLocked(path: String) {
|
||||
mutex.withLock {
|
||||
restore(path)
|
||||
BackupRestoreLock.withLock {
|
||||
restoreUnzipped(path)
|
||||
}
|
||||
}
|
||||
|
||||
internal suspend fun restoreUnzipped(path: String) {
|
||||
restore(path)
|
||||
}
|
||||
|
||||
private suspend fun restore(path: String) {
|
||||
val aes = BackupAES()
|
||||
fileToListT<Book>(path, "bookshelf.json")?.let {
|
||||
|
||||
Reference in New Issue
Block a user