Add initial local archive export support.

This commit is contained in:
Cody Henthorne
2024-08-13 17:01:31 -04:00
committed by mtang-signal
parent c39a1ebdb6
commit 8eb0b2f960
31 changed files with 1474 additions and 133 deletions

View File

@@ -81,6 +81,7 @@ class InternalBackupPlaygroundFragment : ComposeFragment() {
private val viewModel: InternalBackupPlaygroundViewModel by viewModels()
private lateinit var exportFileLauncher: ActivityResultLauncher<Intent>
private lateinit var importFileLauncher: ActivityResultLauncher<Intent>
private lateinit var importDirectoryLauncher: ActivityResultLauncher<Intent>
private lateinit var validateFileLauncher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) {
@@ -107,6 +108,12 @@ class InternalBackupPlaygroundFragment : ComposeFragment() {
}
}
importDirectoryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
viewModel.import(result.data!!.data!!)
}
}
validateFileLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
result.data?.data?.let { uri ->
@@ -144,6 +151,10 @@ class InternalBackupPlaygroundFragment : ComposeFragment() {
importFileLauncher.launch(intent)
},
onImportDirectoryClicked = {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
importDirectoryLauncher.launch(intent)
},
onPlaintextClicked = { viewModel.onPlaintextToggled() },
onSaveToDiskClicked = {
val intent = Intent().apply {
@@ -251,6 +262,7 @@ fun Screen(
onExportClicked: () -> Unit = {},
onImportMemoryClicked: () -> Unit = {},
onImportFileClicked: () -> Unit = {},
onImportDirectoryClicked: () -> Unit = {},
onPlaintextClicked: () -> Unit = {},
onSaveToDiskClicked: () -> Unit = {},
onValidateFileClicked: () -> Unit = {},
@@ -310,6 +322,11 @@ fun Screen(
) {
Text("Import from file")
}
Buttons.LargeTonal(
onClick = onImportDirectoryClicked
) {
Text("Import from directory")
}
Buttons.LargeTonal(
onClick = onValidateFileClicked

View File

@@ -5,6 +5,7 @@
package org.thoughtcrime.securesms.components.settings.app.internal.backup
import android.net.Uri
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
@@ -21,6 +22,11 @@ import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
import org.thoughtcrime.securesms.backup.v2.BackupMetadata
import org.thoughtcrime.securesms.backup.v2.BackupRepository
import org.thoughtcrime.securesms.backup.v2.local.ArchiveFileSystem
import org.thoughtcrime.securesms.backup.v2.local.ArchiveResult
import org.thoughtcrime.securesms.backup.v2.local.LocalArchiver
import org.thoughtcrime.securesms.backup.v2.local.LocalArchiver.FailureCause
import org.thoughtcrime.securesms.backup.v2.local.SnapshotFileSystem
import org.thoughtcrime.securesms.database.MessageType
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.dependencies.AppDependencies
@@ -111,6 +117,27 @@ class InternalBackupPlaygroundViewModel : ViewModel() {
}
}
fun import(uri: Uri) {
_state.value = _state.value.copy(backupState = BackupState.IMPORT_IN_PROGRESS)
val self = Recipient.self()
val selfData = BackupRepository.SelfData(self.aci.get(), self.pni.get(), self.e164.get(), ProfileKey(self.profileKey))
disposables += Single.fromCallable {
val archiveFileSystem = ArchiveFileSystem.fromUri(AppDependencies.application, uri)!!
val snapshotInfo = archiveFileSystem.listSnapshots().firstOrNull() ?: return@fromCallable ArchiveResult.failure(FailureCause.MAIN_STREAM)
val snapshotFileSystem = SnapshotFileSystem(AppDependencies.application, snapshotInfo.file)
LocalArchiver.import(snapshotFileSystem, selfData)
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy {
backupData = null
_state.value = _state.value.copy(backupState = BackupState.NONE)
}
}
fun validate(length: Long, inputStreamFactory: () -> InputStream) {
val self = Recipient.self()
val selfData = BackupRepository.SelfData(self.aci.get(), self.pni.get(), self.e164.get(), ProfileKey(self.profileKey))
@@ -218,6 +245,7 @@ class InternalBackupPlaygroundViewModel : ViewModel() {
reUploadAndArchiveMedia(result.result.mediaIdToAttachmentId(it.mediaId))
}
}
else -> _mediaState.set { copy(error = MediaStateError(errorText = "$result")) }
}
}