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