diff --git a/commons/build.gradle b/commons/build.gradle index d14c6ff1..fdb016ac 100644 --- a/commons/build.gradle +++ b/commons/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' -version = "0.7.5" +version = "0.7.6" android { compileSdkVersion 29 diff --git a/commons/src/main/java/fr/geonature/commons/input/InputManager.kt b/commons/src/main/java/fr/geonature/commons/input/InputManager.kt index 6bbd5542..1cf5065a 100644 --- a/commons/src/main/java/fr/geonature/commons/input/InputManager.kt +++ b/commons/src/main/java/fr/geonature/commons/input/InputManager.kt @@ -3,6 +3,7 @@ package fr.geonature.commons.input import android.annotation.SuppressLint import android.app.Application import android.content.SharedPreferences +import android.util.Log import androidx.lifecycle.MutableLiveData import androidx.preference.PreferenceManager import fr.geonature.commons.input.io.InputJsonReader @@ -95,23 +96,24 @@ class InputManager private constructor( * @return `true` if the given [AbstractInput] has been successfully saved, `false` otherwise */ @SuppressLint("ApplySharedPref") - suspend fun saveInput(input: I): Boolean = withContext(IO) { - val inputAsJson = inputJsonWriter.write(input) - - if (inputAsJson.isNullOrBlank()) return@withContext false - - preferenceManager.edit() - .putString( - buildInputPreferenceKey(input.id), - inputAsJson - ) - .putLong( - KEY_PREFERENCE_CURRENT_INPUT, - input.id - ) - .commit() + suspend fun saveInput(input: I): Boolean { + val saved = withContext(IO) { + val inputAsJson = inputJsonWriter.write(input) + if (inputAsJson.isNullOrBlank()) return@withContext false + + preferenceManager.edit() + .putString( + buildInputPreferenceKey(input.id), + inputAsJson + ) + .putLong( + KEY_PREFERENCE_CURRENT_INPUT, + input.id + ) + .commit() + } - preferenceManager.contains(buildInputPreferenceKey(input.id)) + return saved && preferenceManager.contains(buildInputPreferenceKey(input.id)) .also { readInputs() } } @@ -123,24 +125,32 @@ class InputManager private constructor( * @return `true` if the given [AbstractInput] has been successfully deleted, `false` otherwise */ @SuppressLint("ApplySharedPref") - suspend fun deleteInput(id: Long): Boolean = withContext(IO) { - preferenceManager.edit() - .remove(buildInputPreferenceKey(id)) - .also { - if (preferenceManager.getLong( - KEY_PREFERENCE_CURRENT_INPUT, - 0 - ) == id - ) { - it.remove(KEY_PREFERENCE_CURRENT_INPUT) + suspend fun deleteInput(id: Long): Boolean { + val deleted = withContext(IO) { + preferenceManager.edit() + .remove(buildInputPreferenceKey(id)) + .also { + if (preferenceManager.getLong( + KEY_PREFERENCE_CURRENT_INPUT, + 0 + ) == id + ) { + it.remove(KEY_PREFERENCE_CURRENT_INPUT) + } } - } - .commit() - - !preferenceManager.contains(buildInputPreferenceKey(id)).also { - readInputs() - input.postValue(null) + .commit() } + + Log.i( + TAG, + "input '$id' deleted: $deleted" + ) + + return deleted && !preferenceManager.contains(buildInputPreferenceKey(id)) + .also { + readInputs() + input.postValue(null) + } } /** @@ -150,10 +160,10 @@ class InputManager private constructor( * * @return `true` if the given [AbstractInput] has been successfully exported, `false` otherwise */ - suspend fun exportInput(id: Long): Boolean = withContext(IO) { - val inputToExport = readInput(id) ?: return@withContext false + suspend fun exportInput(id: Long): Boolean { + val inputToExport = readInput(id) ?: return false - return@withContext exportInput(inputToExport) + return exportInput(inputToExport) } /** @@ -163,14 +173,27 @@ class InputManager private constructor( * * @return `true` if the given [AbstractInput] has been successfully exported, `false` otherwise */ - suspend fun exportInput(input: I): Boolean = withContext(IO) { - val inputExportFile = getInputExportFile(input) - inputJsonWriter.write( - FileWriter(inputExportFile), - input + suspend fun exportInput(input: I): Boolean { + val inputExportFile = withContext(IO) { + val inputExportFile = getInputExportFile(input) + inputJsonWriter.write( + FileWriter(inputExportFile), + input + ) + + return@withContext inputExportFile + } + + Log.i( + TAG, + "export input '${input.id}' to JSON file '${inputExportFile.absolutePath}'" + ) + Log.d( + TAG, + "'${inputExportFile.absolutePath}' exists? ${inputExportFile.exists()}" ) - return@withContext if (inputExportFile.exists()) { + return if (inputExportFile.exists()) { deleteInput(input.id) } else { false @@ -193,6 +216,8 @@ class InputManager private constructor( } companion object { + private val TAG = InputManager::class.java.name + private const val KEY_PREFERENCE_INPUT = "key_preference_input" private const val KEY_PREFERENCE_CURRENT_INPUT = "key_preference_current_input" diff --git a/commons/version.properties b/commons/version.properties index 432237e1..12744b52 100644 --- a/commons/version.properties +++ b/commons/version.properties @@ -1,2 +1,2 @@ -#Sat Jul 18 17:30:07 CEST 2020 -VERSION_CODE=2540 +#Sat Oct 10 14:42:14 CEST 2020 +VERSION_CODE=2560 diff --git a/sync/build.gradle b/sync/build.gradle index c570505f..095da70b 100644 --- a/sync/build.gradle +++ b/sync/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: "kotlin-kapt" -version = "1.1.1" +version = "1.1.2" android { compileSdkVersion 29 diff --git a/sync/src/main/java/fr/geonature/sync/data/dao/AppSyncDao.kt b/sync/src/main/java/fr/geonature/sync/data/dao/AppSyncDao.kt index f1a04a53..5197a497 100644 --- a/sync/src/main/java/fr/geonature/sync/data/dao/AppSyncDao.kt +++ b/sync/src/main/java/fr/geonature/sync/data/dao/AppSyncDao.kt @@ -66,7 +66,7 @@ class AppSyncDao(private val context: Context) { packageId ) .walkTopDown() - .filter { it.extension == "json" } + .filter { it.isFile && it.extension == "json" && it.canRead() } .count() } } diff --git a/sync/src/main/java/fr/geonature/sync/sync/worker/DownloadPackageWorker.kt b/sync/src/main/java/fr/geonature/sync/sync/worker/DownloadPackageWorker.kt index e21cfa5a..5c9d78b2 100644 --- a/sync/src/main/java/fr/geonature/sync/sync/worker/DownloadPackageWorker.kt +++ b/sync/src/main/java/fr/geonature/sync/sync/worker/DownloadPackageWorker.kt @@ -9,8 +9,6 @@ import androidx.work.workDataOf import fr.geonature.sync.api.GeoNatureAPIClient import fr.geonature.sync.sync.PackageInfo import fr.geonature.sync.sync.PackageInfoManager -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import okhttp3.ResponseBody import okhttp3.internal.Util import okio.Buffer @@ -33,20 +31,20 @@ class DownloadPackageWorker( private val packageInfoManager = PackageInfoManager.getInstance(applicationContext) - override suspend fun doWork(): Result = withContext(Dispatchers.IO) { + override suspend fun doWork(): Result { val packageName = inputData.getString(KEY_PACKAGE_NAME) if (packageName.isNullOrBlank()) { - return@withContext Result.failure() + return Result.failure() } val packageInfoToUpdate = packageInfoManager.getPackageInfo(packageName) - ?: return@withContext Result.failure() - val apkUrl = packageInfoToUpdate.apkUrl ?: return@withContext Result.failure() + ?: return Result.failure() + val apkUrl = packageInfoToUpdate.apkUrl ?: return Result.failure() val geoNatureAPIClient = GeoNatureAPIClient.instance(applicationContext) - ?: return@withContext Result.failure() + ?: return Result.failure() Log.i( TAG, @@ -55,12 +53,12 @@ class DownloadPackageWorker( setProgress(workData(packageInfoToUpdate.packageName)) - try { + return try { val response = geoNatureAPIClient.downloadPackage(apkUrl) .awaitResponse() if (!response.isSuccessful) { - return@withContext Result.failure( + return Result.failure( workData( packageInfoToUpdate.packageName, 100 @@ -68,7 +66,7 @@ class DownloadPackageWorker( ) } - val responseBody = response.body() ?: return@withContext Result.failure( + val responseBody = response.body() ?: return Result.failure( workData( packageInfoToUpdate.packageName, 100 diff --git a/sync/src/main/java/fr/geonature/sync/sync/worker/InputsSyncWorker.kt b/sync/src/main/java/fr/geonature/sync/sync/worker/InputsSyncWorker.kt index 6643fed6..8030697c 100644 --- a/sync/src/main/java/fr/geonature/sync/sync/worker/InputsSyncWorker.kt +++ b/sync/src/main/java/fr/geonature/sync/sync/worker/InputsSyncWorker.kt @@ -32,18 +32,18 @@ class InputsSyncWorker( private val packageInfoManager = PackageInfoManager.getInstance(applicationContext) - override suspend fun doWork(): Result = withContext(Dispatchers.IO) { + override suspend fun doWork(): Result { val packageName = inputData.getString(KEY_PACKAGE_NAME) if (packageName.isNullOrBlank()) { - return@withContext Result.failure() + return Result.failure() } val packageInfo = - packageInfoManager.getPackageInfo(packageName) ?: return@withContext Result.failure() + packageInfoManager.getPackageInfo(packageName) ?: return Result.failure() val geoNatureAPIClient = GeoNatureAPIClient.instance(applicationContext) - ?: return@withContext Result.failure() + ?: return Result.failure() Log.i( TAG, @@ -76,7 +76,7 @@ class InputsSyncWorker( "No inputs to synchronize for '$packageName'" ) - return@withContext Result.success() + return Result.success() } setProgress( @@ -141,7 +141,7 @@ class InputsSyncWorker( "inputs synchronization ${if (inputsSynchronized.size == inputsToSynchronize.size) "successfully finished" else "finished with errors"} for '$packageName'" ) - if (inputsSynchronized.size == inputsToSynchronize.size) { + return if (inputsSynchronized.size == inputsToSynchronize.size) { Result.success( workData( packageInfo.packageName, @@ -160,15 +160,19 @@ class InputsSyncWorker( } } - private suspend fun deleteSynchronizedInput(syncInput: SyncInput): Boolean = - withContext(Dispatchers.IO) { + private suspend fun deleteSynchronizedInput(syncInput: SyncInput): Boolean { + val deleted = withContext(Dispatchers.IO) { File(syncInput.filePath).takeIf { it.exists() && it.isFile && it.parentFile?.canWrite() ?: false } - ?.delete() - ?.also { - packageInfoManager.getInputsToSynchronize(syncInput.packageInfo) - } ?: false + ?.delete() ?: false } + if (deleted) { + packageInfoManager.getInputsToSynchronize(syncInput.packageInfo) + } + + return deleted + } + private fun workData(packageName: String, state: WorkInfo.State, inputs: Int = 0): Data { return workDataOf( KEY_PACKAGE_NAME to packageName, diff --git a/sync/version.properties b/sync/version.properties index 4a42983a..15a0007c 100644 --- a/sync/version.properties +++ b/sync/version.properties @@ -1,2 +1,2 @@ -#Sun Oct 04 13:36:43 CEST 2020 -VERSION_CODE=2475 +#Mon Oct 26 21:09:56 CET 2020 +VERSION_CODE=2480