[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] 02/03: [wallet] Proper DB import/export functional
From: |
gnunet |
Subject: |
[taler-taler-android] 02/03: [wallet] Proper DB import/export functionality |
Date: |
Tue, 28 Nov 2023 18:33:01 +0100 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a commit to branch master
in repository taler-android.
commit ba51b5e541d888cafdbf479a7e03a116af7050c5
Author: Iván Ávalos <avalos@disroot.org>
AuthorDate: Tue Nov 14 14:13:51 2023 -0600
[wallet] Proper DB import/export functionality
---
.../main/java/net/taler/wallet/MainViewModel.kt | 2 +-
.../net/taler/wallet/backend/WalletBackendApi.kt | 23 ++++++
.../net/taler/wallet/settings/SettingsFragment.kt | 17 +++-
.../net/taler/wallet/settings/SettingsManager.kt | 91 ++++++++++++++++++----
wallet/src/main/res/drawable/ic_archive.xml | 21 +++++
wallet/src/main/res/values/strings.xml | 6 +-
wallet/src/main/res/xml/settings_main.xml | 8 ++
7 files changed, 150 insertions(+), 18 deletions(-)
diff --git a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
index 15fe7e4..4614474 100644
--- a/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
+++ b/wallet/src/main/java/net/taler/wallet/MainViewModel.kt
@@ -83,7 +83,7 @@ class MainViewModel(
val refundManager = RefundManager(api, viewModelScope)
val exchangeManager: ExchangeManager = ExchangeManager(api, viewModelScope)
val peerManager: PeerManager = PeerManager(api, exchangeManager,
viewModelScope)
- val settingsManager: SettingsManager =
SettingsManager(app.applicationContext, viewModelScope)
+ val settingsManager: SettingsManager =
SettingsManager(app.applicationContext, api, viewModelScope)
val accountManager: AccountManager = AccountManager(api, viewModelScope)
val depositManager: DepositManager = DepositManager(api, viewModelScope)
diff --git a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
index bf6f371..ea58dd7 100644
--- a/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
+++ b/wallet/src/main/java/net/taler/wallet/backend/WalletBackendApi.kt
@@ -23,6 +23,7 @@ import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.KSerializer
+import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.decodeFromJsonElement
import net.taler.wallet.backend.TalerErrorCode.NONE
import org.json.JSONObject
@@ -86,4 +87,26 @@ class WalletBackendApi(
WalletResponse.Error(info)
}
}
+
+ // Returns raw JSON response instead of serialized object
+ suspend inline fun rawRequest(
+ operation: String,
+ noinline args: (JSONObject.() -> JSONObject)? = null,
+ ): WalletResponse<JsonObject> = withContext(Dispatchers.Default) {
+ val json = BackendManager.json
+ try {
+ when (val response = sendRequest(operation,
args?.invoke(JSONObject()))) {
+ is ApiResponse.Response -> {
+ WalletResponse.Success(response.result)
+ }
+ is ApiResponse.Error -> {
+ val error: TalerErrorInfo =
json.decodeFromJsonElement(response.error)
+ WalletResponse.Error(error)
+ }
+ }
+ } catch (e: Exception) {
+ val info = TalerErrorInfo(NONE, "", e.toString())
+ WalletResponse.Error(info)
+ }
+ }
}
diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
index f5826c9..54d6dc0 100644
--- a/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsFragment.kt
@@ -18,6 +18,7 @@ package net.taler.wallet.settings
import android.os.Bundle
import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts.OpenDocument
import androidx.activity.result.contract.ActivityResultContracts.CreateDocument
import androidx.fragment.app.activityViewModels
import androidx.preference.Preference
@@ -47,6 +48,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private lateinit var prefWithdrawTest: Preference
private lateinit var prefLogcat: Preference
private lateinit var prefExportDb: Preference
+ private lateinit var prefImportDb: Preference
private lateinit var prefVersionApp: Preference
private lateinit var prefVersionCore: Preference
private lateinit var prefVersionExchange: Preference
@@ -58,6 +60,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
prefWithdrawTest,
prefLogcat,
prefExportDb,
+ prefImportDb,
prefVersionApp,
prefVersionCore,
prefVersionExchange,
@@ -71,9 +74,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
settingsManager.exportLogcat(uri)
}
private val dbExportLauncher =
- registerForActivityResult(CreateDocument("application/x-sqlite3")) {
uri ->
+ registerForActivityResult(CreateDocument("application/json")) { uri ->
settingsManager.exportDb(uri)
}
+ private val dbImportLauncher =
+ registerForActivityResult(OpenDocument()) { uri ->
+ settingsManager.importDb(uri)
+ }
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey:
String?) {
setPreferencesFromResource(R.xml.settings_main, rootKey)
@@ -81,6 +88,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
prefWithdrawTest = findPreference("pref_testkudos")!!
prefLogcat = findPreference("pref_logcat")!!
prefExportDb = findPreference("pref_export_db")!!
+ prefImportDb = findPreference("pref_import_db")!!
prefVersionApp = findPreference("pref_version_app")!!
prefVersionCore = findPreference("pref_version_core")!!
prefVersionExchange =
findPreference("pref_version_protocol_exchange")!!
@@ -127,10 +135,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
true
}
prefExportDb.setOnPreferenceClickListener {
-
dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.sql")
+
dbExportLauncher.launch("taler-wallet-db-${currentTimeMillis()}.json")
+ true
+ }
+ prefImportDb.setOnPreferenceClickListener {
+ dbImportLauncher.launch(arrayOf("application/json"))
true
}
-
prefTest.setOnPreferenceClickListener {
model.runIntegrationTest()
true
diff --git a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
index 349c7b1..0b4cbe9 100644
--- a/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
+++ b/wallet/src/main/java/net/taler/wallet/settings/SettingsManager.kt
@@ -25,14 +25,19 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
import net.taler.wallet.R
-import net.taler.wallet.backend.WALLET_DB
+import net.taler.wallet.backend.WalletBackendApi
+import net.taler.wallet.backend.WalletResponse.Error
+import net.taler.wallet.backend.WalletResponse.Success
+import org.json.JSONObject
class SettingsManager(
private val context: Context,
+ private val api: WalletBackendApi,
private val scope: CoroutineScope,
) {
-
fun exportLogcat(uri: Uri?) {
if (uri == null) {
onLogExportError()
@@ -65,20 +70,76 @@ class SettingsManager(
onDbExportError()
return
}
+
scope.launch(Dispatchers.IO) {
- try {
- context.contentResolver.openOutputStream(uri, "wt")?.use {
outputStream ->
- context.openFileInput(WALLET_DB).use { inputStream ->
- inputStream.copyTo(outputStream)
+ when (val response = api.rawRequest("exportDb")) {
+ is Success -> {
+ try {
+ context.contentResolver.openOutputStream(uri,
"wt")?.use { outputStream ->
+ val data = Json.encodeToString(response.result)
+ val writer = outputStream.bufferedWriter()
+ writer.write(data)
+ writer.close()
+ }
+ } catch(e: Exception) {
+ Log.e(SettingsManager::class.simpleName, "Error
exporting db: ", e)
+ withContext(Dispatchers.Main) {
+ onDbExportError()
+ }
+ return@launch
}
- } ?: onDbExportError()
- } catch (e: Exception) {
- Log.e(SettingsManager::class.simpleName, "Error exporting db:
", e)
- onDbExportError()
- return@launch
+
+ withContext(Dispatchers.Main) {
+ Toast.makeText(context,
R.string.settings_db_export_success, LENGTH_LONG).show()
+ }
+ }
+ is Error -> {
+ Log.e(SettingsManager::class.simpleName, "Error exporting
db: ${response.error}")
+ withContext(Dispatchers.Main) {
+ onDbExportError()
+ }
+ return@launch
+ }
}
- withContext(Dispatchers.Main) {
- Toast.makeText(context, R.string.settings_db_export_success,
LENGTH_LONG).show()
+ }
+ }
+
+ fun importDb(uri: Uri?) {
+ if (uri == null) {
+ onDbImportError()
+ return
+ }
+
+ scope.launch(Dispatchers.IO) {
+ context.contentResolver.openInputStream(uri)?.use { inputStream ->
+ try {
+ val reader = inputStream.bufferedReader()
+ val strData = reader.readText()
+ reader.close()
+ val jsonData = JSONObject(strData)
+ when (val response = api.rawRequest("importDb") {
+ put("dump", jsonData)
+ }) {
+ is Success -> {
+ withContext(Dispatchers.Main) {
+ Toast.makeText(context,
R.string.settings_db_import_success, LENGTH_LONG).show()
+ }
+ }
+ is Error -> {
+ Log.e(SettingsManager::class.simpleName, "Error
importing db: ${response.error}")
+ withContext(Dispatchers.Main) {
+ onDbImportError()
+ }
+ return@launch
+ }
+ }
+ } catch (e: Exception) {
+ Log.e(SettingsManager::class.simpleName, "Error importing
db: ", e)
+ withContext(Dispatchers.Main) {
+ onDbImportError()
+ }
+ return@launch
+ }
}
}
}
@@ -87,4 +148,8 @@ class SettingsManager(
Toast.makeText(context, R.string.settings_db_export_error,
LENGTH_LONG).show()
}
+ private fun onDbImportError() {
+ Toast.makeText(context, R.string.settings_db_import_error,
LENGTH_LONG).show()
+ }
+
}
diff --git a/wallet/src/main/res/drawable/ic_archive.xml
b/wallet/src/main/res/drawable/ic_archive.xml
new file mode 100644
index 0000000..58a032c
--- /dev/null
+++ b/wallet/src/main/res/drawable/ic_archive.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ This file is part of GNU Taler
+ ~ (C) 2023 Taler Systems S.A.
+ ~
+ ~ GNU Taler is free software; you can redistribute it and/or modify it under
the
+ ~ terms of the GNU General Public License as published by the Free Software
+ ~ Foundation; either version 3, or (at your option) any later version.
+ ~
+ ~ GNU Taler is distributed in the hope that it will be useful, but WITHOUT
ANY
+ ~ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR
+ ~ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ ~
+ ~ You should have received a copy of the GNU General Public License along
with
+ ~ GNU Taler; see the file COPYING. If not, see
<http://www.gnu.org/licenses/>
+ -->
+
+<vector android:height="24dp" android:tint="?attr/colorControlNormal"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp"
xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/white"
android:pathData="M20.54,5.23l-1.39,-1.68C18.88,3.21 18.47,3 18,3H6c-0.47,0
-0.88,0.21 -1.16,0.55L3.46,5.23C3.17,5.57 3,6.02 3,6.5V19c0,1.1 0.9,2
2,2h14c1.1,0 2,-0.9 2,-2V6.5c0,-0.48 -0.17,-0.93
-0.46,-1.27zM12,17.5L6.5,12H10v-2h4v2h3.5L12,17.5zM5.12,5l0.81,-1h12l0.94,1H5.12z"/>
+</vector>
diff --git a/wallet/src/main/res/values/strings.xml
b/wallet/src/main/res/values/strings.xml
index 3b05ae9..2533820 100644
--- a/wallet/src/main/res/values/strings.xml
+++ b/wallet/src/main/res/values/strings.xml
@@ -257,10 +257,14 @@ GNU Taler is immune against many types of fraud, such as
phishing of credit card
<string name="settings_logcat_summary">Save internal log</string>
<string name="settings_logcat_error">Error exporting log</string>
<string name="settings_logcat_success">Log exported to file</string>
- <string name="settings_db_export">Database</string>
+ <string name="settings_db_export">Export database</string>
<string name="settings_db_export_summary">Save internal database</string>
+ <string name="settings_db_import">Import database</string>
+ <string name="settings_db_import_summary">Restore database from
file</string>
<string name="settings_db_export_error">Error exporting database</string>
+ <string name="settings_db_import_error">Error importing database</string>
<string name="settings_db_export_success">Database exported to
file</string>
+ <string name="settings_db_import_success">Database imported from
file</string>
<string name="settings_version_app">App Version</string>
<string name="settings_version_core">Wallet Core Version</string>
<string name="settings_version_protocol_exchange">Supported Exchange
Versions</string>
diff --git a/wallet/src/main/res/xml/settings_main.xml
b/wallet/src/main/res/xml/settings_main.xml
index 3a6d991..739e119 100644
--- a/wallet/src/main/res/xml/settings_main.xml
+++ b/wallet/src/main/res/xml/settings_main.xml
@@ -55,6 +55,14 @@
app:title="@string/settings_db_export"
tools:isPreferenceVisible="true" />
+ <Preference
+ app:icon="@drawable/ic_archive"
+ app:isPreferenceVisible="false"
+ app:key="pref_import_db"
+ app:summary="@string/settings_db_import_summary"
+ app:title="@string/settings_db_import"
+ tools:isPreferenceVisible="true" />
+
<Preference
app:icon="@drawable/ic_account_balance_wallet"
app:isPreferenceVisible="false"
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.