forked from github/szkolny
[API/Szkolny] Fix user/device registration after API errors. (#111)
This commit is contained in:
parent
e02246f97d
commit
8745d7d526
@ -28,6 +28,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||||
|
import pl.szczodrzynski.edziennik.ext.keys
|
||||||
import pl.szczodrzynski.edziennik.ext.md5
|
import pl.szczodrzynski.edziennik.ext.md5
|
||||||
import pl.szczodrzynski.edziennik.ext.toApiError
|
import pl.szczodrzynski.edziennik.ext.toApiError
|
||||||
import pl.szczodrzynski.edziennik.ext.toErrorCode
|
import pl.szczodrzynski.edziennik.ext.toErrorCode
|
||||||
@ -126,7 +127,10 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
* or null if it's a HTTP call error.
|
* or null if it's a HTTP call error.
|
||||||
*/
|
*/
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
private inline fun <reified T> parseResponse(response: Response<ApiResponse<T>>): T {
|
private inline fun <reified T> parseResponse(
|
||||||
|
response: Response<ApiResponse<T>>,
|
||||||
|
updateDeviceHash: Boolean = false,
|
||||||
|
): T {
|
||||||
app.config.update = response.body()?.update?.let { update ->
|
app.config.update = response.body()?.update?.let { update ->
|
||||||
if (update.versionCode > BuildConfig.VERSION_CODE) {
|
if (update.versionCode > BuildConfig.VERSION_CODE) {
|
||||||
if (update.updateMandatory
|
if (update.updateMandatory
|
||||||
@ -144,6 +148,14 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (response.isSuccessful && response.body()?.success == true) {
|
if (response.isSuccessful && response.body()?.success == true) {
|
||||||
|
// update the device's hash on success
|
||||||
|
if (updateDeviceHash) {
|
||||||
|
val hash = getDevice()?.toString()?.md5()
|
||||||
|
if (hash != null) {
|
||||||
|
app.config.hash = hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Unit is T) {
|
if (Unit is T) {
|
||||||
return Unit
|
return Unit
|
||||||
}
|
}
|
||||||
@ -168,7 +180,6 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
throw SzkolnyApiException(body?.errors?.firstOrNull())
|
throw SzkolnyApiException(body?.errors?.firstOrNull())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
|
||||||
private fun getDevice() = run {
|
private fun getDevice() = run {
|
||||||
val config = app.config
|
val config = app.config
|
||||||
val device = Device(
|
val device = Device(
|
||||||
@ -181,51 +192,50 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
appVersionCode = BuildConfig.VERSION_CODE,
|
appVersionCode = BuildConfig.VERSION_CODE,
|
||||||
syncInterval = app.config.sync.interval
|
syncInterval = app.config.sync.interval
|
||||||
)
|
)
|
||||||
device.toString().md5().let {
|
val hash = device.toString().md5()
|
||||||
if (it == config.hash)
|
if (hash == config.hash)
|
||||||
null
|
return@run null
|
||||||
else {
|
return@run device
|
||||||
config.hash = it
|
|
||||||
device
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getEvents(profiles: List<Profile>, notifications: List<Notification>, blacklistedIds: List<Long>, lastSyncTime: Long): List<EventFull> {
|
fun getEvents(profiles: List<Profile>, notifications: List<Notification>, blacklistedIds: List<Long>, lastSyncTime: Long): List<EventFull> {
|
||||||
val teams = app.db.teamDao().allNow
|
val teams = app.db.teamDao().allNow
|
||||||
|
|
||||||
|
val users = profiles.mapNotNull { profile ->
|
||||||
|
val config = app.config.getFor(profile.id)
|
||||||
|
val user = ServerSyncRequest.User(
|
||||||
|
profile.userCode,
|
||||||
|
profile.studentNameLong,
|
||||||
|
profile.studentNameShort,
|
||||||
|
profile.loginStoreType,
|
||||||
|
teams.filter { it.profileId == profile.id }.map { it.code }
|
||||||
|
)
|
||||||
|
val hash = user.toString().md5()
|
||||||
|
if (hash == config.hash)
|
||||||
|
return@mapNotNull null
|
||||||
|
return@mapNotNull user to config
|
||||||
|
}
|
||||||
|
|
||||||
val response = api.serverSync(ServerSyncRequest(
|
val response = api.serverSync(ServerSyncRequest(
|
||||||
deviceId = app.deviceId,
|
deviceId = app.deviceId,
|
||||||
device = getDevice(),
|
device = getDevice(),
|
||||||
userCodes = profiles.map { it.userCode },
|
userCodes = profiles.map { it.userCode },
|
||||||
users = profiles.mapNotNull { profile ->
|
users = users.keys(),
|
||||||
val config = app.config.getFor(profile.id)
|
|
||||||
val user = ServerSyncRequest.User(
|
|
||||||
profile.userCode,
|
|
||||||
profile.studentNameLong,
|
|
||||||
profile.studentNameShort,
|
|
||||||
profile.loginStoreType,
|
|
||||||
teams.filter { it.profileId == profile.id }.map { it.code }
|
|
||||||
)
|
|
||||||
user.toString().md5().let {
|
|
||||||
if (it == config.hash)
|
|
||||||
null
|
|
||||||
else {
|
|
||||||
config.hash = it
|
|
||||||
user
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
lastSync = lastSyncTime,
|
lastSync = lastSyncTime,
|
||||||
notifications = notifications.map { ServerSyncRequest.Notification(it.profileName ?: "", it.type, it.text) }
|
notifications = notifications.map { ServerSyncRequest.Notification(it.profileName ?: "", it.type, it.text) }
|
||||||
)).execute()
|
)).execute()
|
||||||
val (events, hasBrowsers) = parseResponse(response)
|
val (events, hasBrowsers) = parseResponse(response, updateDeviceHash = true)
|
||||||
|
|
||||||
hasBrowsers?.let {
|
hasBrowsers?.let {
|
||||||
app.config.sync.webPushEnabled = it
|
app.config.sync.webPushEnabled = it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update users' hashes on success
|
||||||
|
users.forEach { (user, config) ->
|
||||||
|
config.hash = user.toString().md5()
|
||||||
|
}
|
||||||
|
|
||||||
val eventList = mutableListOf<EventFull>()
|
val eventList = mutableListOf<EventFull>()
|
||||||
|
|
||||||
events.forEach { event ->
|
events.forEach { event ->
|
||||||
@ -270,7 +280,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
shareTeamCode = team.code,
|
shareTeamCode = team.code,
|
||||||
event = event
|
event = event
|
||||||
)).execute()
|
)).execute()
|
||||||
parseResponse(response)
|
parseResponse(response, updateDeviceHash = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -284,7 +294,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
unshareTeamCode = team.code,
|
unshareTeamCode = team.code,
|
||||||
eventId = event.id
|
eventId = event.id
|
||||||
)).execute()
|
)).execute()
|
||||||
parseResponse(response)
|
parseResponse(response, updateDeviceHash = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*fun eventEditRequest(requesterName: String, event: Event): ApiResponse<Nothing>? {
|
/*fun eventEditRequest(requesterName: String, event: Event): ApiResponse<Nothing>? {
|
||||||
@ -301,7 +311,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
pairToken = pairToken
|
pairToken = pairToken
|
||||||
)).execute()
|
)).execute()
|
||||||
|
|
||||||
return parseResponse(response).browsers
|
return parseResponse(response, updateDeviceHash = true).browsers
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -312,7 +322,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
action = "listBrowsers"
|
action = "listBrowsers"
|
||||||
)).execute()
|
)).execute()
|
||||||
|
|
||||||
return parseResponse(response).browsers
|
return parseResponse(response, updateDeviceHash = true).browsers
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -324,7 +334,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
browserId = browserId
|
browserId = browserId
|
||||||
)).execute()
|
)).execute()
|
||||||
|
|
||||||
return parseResponse(response).browsers
|
return parseResponse(response, updateDeviceHash = true).browsers
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -335,7 +345,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
appVersion = BuildConfig.VERSION_NAME,
|
appVersion = BuildConfig.VERSION_NAME,
|
||||||
errors = errors
|
errors = errors
|
||||||
)).execute()
|
)).execute()
|
||||||
parseResponse(response)
|
parseResponse(response, updateDeviceHash = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -345,7 +355,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
device = getDevice(),
|
device = getDevice(),
|
||||||
userCode = userCode
|
userCode = userCode
|
||||||
)).execute()
|
)).execute()
|
||||||
parseResponse(response)
|
parseResponse(response, updateDeviceHash = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
@ -364,7 +374,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
text = text
|
text = text
|
||||||
)).execute()
|
)).execute()
|
||||||
|
|
||||||
return parseResponse(response).message
|
return parseResponse(response, updateDeviceHash = true).message
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
|
@ -59,20 +59,8 @@ fun SparseIntArray.values(): List<Int> {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <K, V> List<Pair<K, V>>.keys(): List<K> {
|
fun <K, V> List<Pair<K, V>>.keys() = map { it.first }
|
||||||
val result = mutableListOf<K>()
|
fun <K, V> List<Pair<K, V>>.values() = map { it.second }
|
||||||
forEach { pair ->
|
|
||||||
result += pair.first
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
fun <K, V> List<Pair<K, V>>.values(): List<V> {
|
|
||||||
val result = mutableListOf<V>()
|
|
||||||
forEach { pair ->
|
|
||||||
result += pair.second
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> List<T>.toSparseArray(destination: SparseArray<T>, key: (T) -> Int) {
|
fun <T> List<T>.toSparseArray(destination: SparseArray<T>, key: (T) -> Int) {
|
||||||
forEach {
|
forEach {
|
||||||
|
Loading…
Reference in New Issue
Block a user