Skip to content

Commit

Permalink
Merge branch 'release/1.1.9'
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrimault committed May 24, 2021
2 parents fd8aab7 + 9bd0273 commit 75361d0
Show file tree
Hide file tree
Showing 18 changed files with 359 additions and 94 deletions.
2 changes: 1 addition & 1 deletion commons/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

version = "0.8.2"
version = "0.8.3"

android {
compileSdkVersion 29
Expand Down
14 changes: 14 additions & 0 deletions commons/src/main/java/fr/geonature/commons/data/AppSync.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import java.util.Date
data class AppSync(
var packageId: String,
var lastSync: Date? = null,
var lastSyncEssential: Date? = null,
var inputsToSynchronize: Int = 0
) : Parcelable {

private constructor(source: Parcel) : this(
source.readString()!!,
source.readSerializable() as Date,
source.readSerializable() as Date,
source.readInt()
)

Expand All @@ -36,6 +38,7 @@ data class AppSync(
dest?.also {
it.writeString(packageId)
it.writeSerializable(lastSync)
it.writeSerializable(lastSyncEssential)
it.writeInt(inputsToSynchronize)
}
}
Expand All @@ -47,6 +50,7 @@ data class AppSync(
const val TABLE_NAME = "app_sync"
const val COLUMN_ID = "package_id"
const val COLUMN_LAST_SYNC = "last_sync"
const val COLUMN_LAST_SYNC_ESSENTIAL = "last_sync_essential"
const val COLUMN_INPUTS_TO_SYNCHRONIZE = "inputs_to_synchronize"

/**
Expand All @@ -62,6 +66,10 @@ data class AppSync(
COLUMN_LAST_SYNC,
tableAlias
),
column(
COLUMN_LAST_SYNC_ESSENTIAL,
tableAlias
),
column(
COLUMN_INPUTS_TO_SYNCHRONIZE,
tableAlias
Expand Down Expand Up @@ -113,6 +121,12 @@ data class AppSync(
tableAlias
)
),
cursor.get(
getColumnAlias(
COLUMN_LAST_SYNC_ESSENTIAL,
tableAlias
)
),
requireNotNull(
cursor.get(
getColumnAlias(
Expand Down
35 changes: 33 additions & 2 deletions commons/src/test/java/fr/geonature/commons/data/AppSyncTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.mockito.Mockito.`when`
import org.mockito.Mockito.mock
import org.robolectric.RobolectricTestRunner
import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.Date

/**
Expand All @@ -29,11 +30,27 @@ class AppSyncTest {
assertEquals(
AppSync(
"fr.geonature.sync",
Date.from(
now
.toInstant()
.minus(
1,
ChronoUnit.HOURS
)
),
now,
3
),
AppSync(
"fr.geonature.sync",
Date.from(
now
.toInstant()
.minus(
1,
ChronoUnit.HOURS
)
),
now,
3
)
Expand All @@ -51,8 +68,9 @@ class AppSyncTest {
}

`when`(cursor.getString(0)).thenReturn("fr.geonature.sync")
`when`(cursor.getLong(1)).thenReturn(1477642500000)
`when`(cursor.getInt(2)).thenReturn(3)
`when`(cursor.getLong(1)).thenReturn(1477638900000)
`when`(cursor.getLong(2)).thenReturn(1477642500000)
`when`(cursor.getInt(3)).thenReturn(3)

// when getting AppSync instance from Cursor
val appSync = AppSync.fromCursor(cursor)
Expand All @@ -62,6 +80,7 @@ class AppSyncTest {
assertEquals(
AppSync(
"fr.geonature.sync",
Date.from(Instant.parse("2016-10-28T07:15:00Z")),
Date.from(Instant.parse("2016-10-28T08:15:00Z")),
3
),
Expand All @@ -74,6 +93,14 @@ class AppSyncTest {
// given AppSync
val appSync = AppSync(
"fr.geonature.sync",
Date.from(
Instant
.now()
.minus(
1,
ChronoUnit.HOURS
)
),
Date.from(Instant.now()),
3
)
Expand Down Expand Up @@ -107,6 +134,10 @@ class AppSyncTest {
"${AppSync.TABLE_NAME}.\"${AppSync.COLUMN_LAST_SYNC}\"",
"${AppSync.TABLE_NAME}_${AppSync.COLUMN_LAST_SYNC}"
),
Pair(
"${AppSync.TABLE_NAME}.\"${AppSync.COLUMN_LAST_SYNC_ESSENTIAL}\"",
"${AppSync.TABLE_NAME}_${AppSync.COLUMN_LAST_SYNC_ESSENTIAL}"
),
Pair(
"${AppSync.TABLE_NAME}.\"${AppSync.COLUMN_INPUTS_TO_SYNCHRONIZE}\"",
"${AppSync.TABLE_NAME}_${AppSync.COLUMN_INPUTS_TO_SYNCHRONIZE}"
Expand Down
4 changes: 2 additions & 2 deletions commons/version.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#Sun Mar 28 16:42:31 CEST 2021
VERSION_CODE=2820
#Sun May 23 16:23:47 CEST 2021
VERSION_CODE=2855
2 changes: 1 addition & 1 deletion sync/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: "kotlin-kapt"

version = "1.1.8"
version = "1.1.9"

android {
compileSdkVersion 29
Expand Down
19 changes: 19 additions & 0 deletions sync/src/main/java/fr/geonature/sync/MainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import fr.geonature.mountpoint.util.MountPointUtils.getExternalStorage
import fr.geonature.mountpoint.util.MountPointUtils.getInternalStorage
import fr.geonature.sync.sync.worker.CheckAuthLoginWorker
import fr.geonature.sync.sync.worker.CheckInputsToSynchronizeWorker
import java.util.concurrent.TimeUnit

Expand All @@ -36,9 +37,27 @@ class MainApplication : Application() {
configureCheckInputsToSynchronizeChannel(notificationManager)
configureSynchronizeDataChannel(notificationManager)

checkAuthLogin()
checkInputsToSynchronize()
}

private fun checkAuthLogin() {
val workManager: WorkManager = WorkManager.getInstance(this)

val request = PeriodicWorkRequestBuilder<CheckAuthLoginWorker>(
1,
TimeUnit.HOURS
)
.addTag(CheckAuthLoginWorker.CHECK_AUTH_LOGIN_WORKER_TAG)
.build()

workManager.enqueueUniquePeriodicWork(
CheckAuthLoginWorker.CHECK_AUTH_LOGIN_WORKER,
ExistingPeriodicWorkPolicy.REPLACE,
request
)
}

private fun checkInputsToSynchronize() {
val workManager: WorkManager = WorkManager.getInstance(this)

Expand Down
37 changes: 21 additions & 16 deletions sync/src/main/java/fr/geonature/sync/auth/AuthLoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio

private val authManager: AuthManager = AuthManager.getInstance(application)
private val geoNatureAPIClient: GeoNatureAPIClient? = GeoNatureAPIClient.instance(application)
private val connectivityManager =
application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
private val connectivityManager = application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

private val _loginFormState = MutableLiveData<LoginFormState>()
val loginFormState: LiveData<LoginFormState> = _loginFormState
Expand All @@ -52,6 +51,16 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
}
}

fun checkAuthLogin(): LiveData<AuthLogin?> {
val authLoginLiveData = MutableLiveData<AuthLogin?>()

viewModelScope.launch {
authLoginLiveData.postValue(authManager.getAuthLogin())
}

return authLoginLiveData
}

fun login(
username: String,
password: String,
Expand Down Expand Up @@ -95,13 +104,13 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
return@launch
}

authManager.setAuthLogin(authLogin)
authManager
.setAuthLogin(authLogin)
.also {
_loginResult.value = LoginResult(success = authLogin)
}
} catch (e: Exception) {
_loginResult.value =
LoginResult(error = if (connectivityManager.allNetworks.isEmpty()) R.string.snackbar_network_lost else R.string.login_failed)
_loginResult.value = LoginResult(error = if (connectivityManager.allNetworks.isEmpty()) R.string.snackbar_network_lost else R.string.login_failed)
}
}
}
Expand All @@ -111,14 +120,12 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
password: String
) {
if (!isUserNameValid(username)) {
_loginFormState.value =
LoginFormState(usernameError = R.string.login_form_username_invalid)
_loginFormState.value = LoginFormState(usernameError = R.string.login_form_username_invalid)
return
}

if (!isPasswordValid(password)) {
_loginFormState.value =
LoginFormState(passwordError = R.string.login_form_password_invalid)
_loginFormState.value = LoginFormState(passwordError = R.string.login_form_password_invalid)
return
}

Expand Down Expand Up @@ -153,7 +160,8 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
val type = object : TypeToken<AuthLoginError>() {}.type

return Gson().fromJson(
response.errorBody()!!
response
.errorBody()!!
.charStream(),
type
)
Expand All @@ -165,10 +173,8 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
* @author [S. Grimault](mailto:[email protected])
*/
data class LoginFormState(
@StringRes
val usernameError: Int? = null,
@StringRes
val passwordError: Int? = null,
@StringRes val usernameError: Int? = null,
@StringRes val passwordError: Int? = null,
val isValid: Boolean = false
)

Expand All @@ -179,8 +185,7 @@ class AuthLoginViewModel(application: Application) : AndroidViewModel(applicatio
*/
data class LoginResult(
val success: AuthLogin? = null,
@StringRes
val error: Int? = null
@StringRes val error: Int? = null
) {

fun hasError(): Boolean {
Expand Down
51 changes: 36 additions & 15 deletions sync/src/main/java/fr/geonature/sync/data/dao/AppSyncDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ import java.util.Date
*/
class AppSyncDao(private val context: Context) {

private val sharedPreferences: SharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context)
private val sharedPreferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)

fun findByPackageId(packageId: String?): Cursor {
val cursor = MatrixCursor(AppSync.defaultProjection().map { it.second }.toTypedArray())
val cursor = MatrixCursor(AppSync
.defaultProjection()
.map { it.second }
.toTypedArray())

if (packageId.isNullOrBlank()) return cursor

val values = arrayOf(
packageId,
dateToTimestamp(getLastSynchronizedDate()),
dateToTimestamp(getLastEssentialSynchronizedDate()),
countInputsToSynchronize(packageId)
)

Expand All @@ -38,35 +41,53 @@ class AppSyncDao(private val context: Context) {
return cursor
}

fun updateLastSynchronizedDate(): Date {
fun updateLastSynchronizedDate(complete: Boolean = true): Date {
val now = Date()

this.sharedPreferences.edit()
this.sharedPreferences
.edit()
.putLong(
"sync.${AppSync.COLUMN_LAST_SYNC}",
dateToTimestamp(now) ?: -1L
buildLastSynchronizedDatePreferenceKey(complete),
dateToTimestamp(now)
?: -1L
)
.apply()

return now
}

fun getLastSynchronizedDate(): Date? {
return this.sharedPreferences.getLong(
"sync.${AppSync.COLUMN_LAST_SYNC}",
-1L
)
return this.sharedPreferences
.getLong(
buildLastSynchronizedDatePreferenceKey(),
-1L
)
.takeUnless { it == -1L }
.run { fromTimestamp(this) }
}

fun getLastEssentialSynchronizedDate(): Date? {
return this.sharedPreferences
.getLong(
buildLastSynchronizedDatePreferenceKey(false),
-1L
)
.takeUnless { it == -1L }
.run { fromTimestamp(this) }
}

private fun countInputsToSynchronize(packageId: String): Number {
return FileUtils.getInputsFolder(
context,
packageId
)
return FileUtils
.getInputsFolder(
context,
packageId
)
.walkTopDown()
.filter { it.isFile && it.extension == "json" && it.canRead() }
.count()
}

private fun buildLastSynchronizedDatePreferenceKey(complete: Boolean = true): String {
return "sync.${if (complete) AppSync.COLUMN_LAST_SYNC else AppSync.COLUMN_LAST_SYNC_ESSENTIAL}"
}
}
Loading

0 comments on commit 75361d0

Please sign in to comment.