mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2024-11-24 19:04:38 -06:00
[APIv2] Simplify endpoint choosing. Optimize imports.
This commit is contained in:
parent
b35df5ef11
commit
bdc0ceb11d
@ -0,0 +1,80 @@
|
||||
package pl.szczodrzynski.edziennik.api.v2
|
||||
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Feature
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_NEVER
|
||||
|
||||
fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featureIds: List<Int>, viewId: Int?) {
|
||||
val data = this
|
||||
|
||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||
|
||||
for (loginMethod in loginMethods) {
|
||||
if (loginMethod.isPossible(profile, loginStore))
|
||||
possibleLoginMethods += loginMethod.loginMethodId
|
||||
}
|
||||
|
||||
//var highestLoginMethod = 0
|
||||
var endpointList = mutableListOf<Feature>()
|
||||
val requiredLoginMethods = mutableListOf<Int>()
|
||||
|
||||
data.targetEndpointIds.clear()
|
||||
data.targetLoginMethodIds.clear()
|
||||
|
||||
// get all endpoints for every feature, only if possible to login and possible/necessary to sync
|
||||
for (featureId in featureIds) {
|
||||
features.filter {
|
||||
it.featureId == featureId // feature ID matches
|
||||
&& possibleLoginMethods.containsAll(it.requiredLoginMethods) // is possible to login
|
||||
&& it.shouldSync?.invoke(data) ?: true // is necessary/possible to sync
|
||||
}.let {
|
||||
endpointList.addAll(it)
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Feature::featureId, Feature::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods, filtering using timers
|
||||
.onEach { feature ->
|
||||
feature.endpointIds.forEach { endpoint ->
|
||||
(data.endpointTimers
|
||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id ?: -1, endpoint.first))
|
||||
.let { timer ->
|
||||
if (timer.nextSync == SYNC_ALWAYS ||
|
||||
(viewId != null && timer.viewId == viewId) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
for (loginMethodId in requiredLoginMethods) {
|
||||
var requiredLoginMethod: Int? = loginMethodId
|
||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||
loginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||
if (requiredLoginMethod != null)
|
||||
data.targetLoginMethodIds.add(requiredLoginMethod!!)
|
||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort and distinct every login method and endpoint
|
||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||
data.targetLoginMethodIds.sort()
|
||||
|
||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||
data.targetEndpointIds.sort()
|
||||
}
|
@ -7,18 +7,16 @@ package pl.szczodrzynski.edziennik.api.v2.librus
|
||||
import android.util.Log
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
|
||||
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_NOT_NEEDED
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusData
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.login.LibrusLogin
|
||||
import pl.szczodrzynski.edziennik.api.v2.librusLoginMethods
|
||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.MobidziennikFeatures
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Feature
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.*
|
||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||
companion object {
|
||||
@ -27,13 +25,12 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataLibrus
|
||||
private var cancelled = false
|
||||
|
||||
init {
|
||||
data = DataLibrus(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Librus.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
data.satisfyLoginMethods()
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
@ -50,77 +47,9 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
__/ |
|
||||
|__*/
|
||||
override fun sync(featureIds: List<Int>, viewId: Int?) {
|
||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||
|
||||
for (loginMethod in librusLoginMethods) {
|
||||
if (loginMethod.isPossible(profile, loginStore))
|
||||
possibleLoginMethods += loginMethod.loginMethodId
|
||||
}
|
||||
|
||||
//var highestLoginMethod = 0
|
||||
var endpointList = mutableListOf<Feature>()
|
||||
val requiredLoginMethods = mutableListOf<Int>()
|
||||
|
||||
data.targetEndpointIds.clear()
|
||||
data.targetLoginMethodIds.clear()
|
||||
|
||||
// get all endpoints for every feature, only if possible to login and possible/necessary to sync
|
||||
for (featureId in featureIds) {
|
||||
LibrusFeatures.filter {
|
||||
it.featureId == featureId // feature ID matches
|
||||
&& possibleLoginMethods.containsAll(it.requiredLoginMethods) // is possible to login
|
||||
&& it.shouldSync?.invoke(data) ?: true // is necessary/possible to sync
|
||||
}.let {
|
||||
endpointList.addAll(it)
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Feature::featureId, Feature::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods, filtering using timers
|
||||
.onEach { feature ->
|
||||
feature.endpointIds.forEach { endpoint ->
|
||||
(data.endpointTimers
|
||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id ?: -1, endpoint.first))
|
||||
.let { timer ->
|
||||
if (timer.nextSync == SYNC_ALWAYS ||
|
||||
(viewId != null && timer.viewId == viewId) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
for (loginMethodId in requiredLoginMethods) {
|
||||
var requiredLoginMethod: Int? = loginMethodId
|
||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||
librusLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||
if (requiredLoginMethod != null)
|
||||
data.targetLoginMethodIds.add(requiredLoginMethod!!)
|
||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort and distinct every login method and endpoint
|
||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||
data.targetLoginMethodIds.sort()
|
||||
|
||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||
data.targetEndpointIds.sort()
|
||||
|
||||
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId)
|
||||
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
|
||||
LibrusLogin(data) {
|
||||
LibrusData(data) {
|
||||
completed()
|
||||
@ -137,6 +66,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
Utils.d(TAG, "Cancelled")
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
|
@ -6,17 +6,14 @@ package pl.szczodrzynski.edziennik.api.v2.mobidziennik
|
||||
|
||||
import android.util.Log
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.*
|
||||
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.LibrusFeatures
|
||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikData
|
||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.login.MobidziennikLogin
|
||||
import pl.szczodrzynski.edziennik.api.v2.mobidziennikLoginMethods
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Feature
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_NEVER
|
||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
@ -28,13 +25,12 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataMobidziennik
|
||||
private var cancelled = false
|
||||
|
||||
init {
|
||||
data = DataMobidziennik(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Mobidziennik.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
data.satisfyLoginMethods()
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
@ -51,77 +47,9 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
||||
__/ |
|
||||
|__*/
|
||||
override fun sync(featureIds: List<Int>, viewId: Int?) {
|
||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||
|
||||
for (loginMethod in mobidziennikLoginMethods) {
|
||||
if (loginMethod.isPossible(profile, loginStore))
|
||||
possibleLoginMethods += loginMethod.loginMethodId
|
||||
}
|
||||
|
||||
//var highestLoginMethod = 0
|
||||
var endpointList = mutableListOf<Feature>()
|
||||
val requiredLoginMethods = mutableListOf<Int>()
|
||||
|
||||
data.targetEndpointIds.clear()
|
||||
data.targetLoginMethodIds.clear()
|
||||
|
||||
// get all endpoints for every feature, only if possible to login and possible/necessary to sync
|
||||
for (featureId in featureIds) {
|
||||
MobidziennikFeatures.filter {
|
||||
it.featureId == featureId // feature ID matches
|
||||
&& possibleLoginMethods.containsAll(it.requiredLoginMethods) // is possible to login
|
||||
&& it.shouldSync?.invoke(data) ?: true // is necessary/possible to sync
|
||||
}.let {
|
||||
endpointList.addAll(it)
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Feature::featureId, Feature::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods, filtering using timers
|
||||
.onEach { feature ->
|
||||
feature.endpointIds.forEach { endpoint ->
|
||||
(data.endpointTimers
|
||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id ?: -1, endpoint.first))
|
||||
.let { timer ->
|
||||
if (timer.nextSync == SYNC_ALWAYS ||
|
||||
(viewId != null && timer.viewId == viewId) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
for (loginMethodId in requiredLoginMethods) {
|
||||
var requiredLoginMethod: Int? = loginMethodId
|
||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||
mobidziennikLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||
if (requiredLoginMethod != null)
|
||||
data.targetLoginMethodIds.add(requiredLoginMethod!!)
|
||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort and distinct every login method and endpoint
|
||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||
data.targetLoginMethodIds.sort()
|
||||
|
||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||
data.targetEndpointIds.sort()
|
||||
|
||||
data.prepare(mobidziennikLoginMethods, MobidziennikFeatures, featureIds, viewId)
|
||||
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
|
||||
MobidziennikLogin(data) {
|
||||
MobidziennikData(data) {
|
||||
completed()
|
||||
@ -139,7 +67,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
|
||||
|
||||
override fun cancel() {
|
||||
Utils.d(TAG, "Cancelled")
|
||||
cancelled = true
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||
|
@ -2,7 +2,6 @@ package pl.szczodrzynski.edziennik.api.v2.models
|
||||
|
||||
import android.util.LongSparseArray
|
||||
import android.util.SparseArray
|
||||
import androidx.core.util.isNotEmpty
|
||||
import com.google.gson.JsonObject
|
||||
import im.wangchao.mhttp.Response
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
@ -84,18 +83,6 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
*/
|
||||
var endpointArgs = mutableMapOf<Int, JsonObject>()
|
||||
|
||||
/**
|
||||
* A list of per-endpoint next sync time descriptors.
|
||||
*
|
||||
* [EndpointTimer.nextSync] may be:
|
||||
* - [pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_NEVER] to never sync the endpoint (pretty useless)
|
||||
* - [pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS] to sync the endpoint during every sync
|
||||
* - [pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_IF_EXPLICIT] to sync the endpoint only if the matching
|
||||
* feature ID is in the input set
|
||||
* - [pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_IF_EXPLICIT_OR_ALL] to sync if the matching feature ID
|
||||
* is in the input set OR the sync covers all feature IDs
|
||||
* - a Unix-epoch timestamp (in millis) to sync the endpoint if [System.currentTimeMillis] is greater or equal to this value
|
||||
*/
|
||||
var endpointTimers = mutableListOf<EndpointTimer>()
|
||||
|
||||
val teacherList = LongSparseArray<Teacher>()
|
||||
@ -148,9 +135,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
val db by lazy { app.db }
|
||||
|
||||
init {
|
||||
|
||||
clear()
|
||||
|
||||
if (profile != null) {
|
||||
endpointTimers = db.endpointTimerDao().getAllNow(profile.id).toMutableList()
|
||||
db.teacherDao().getAllNow(profileId).toSparseArray(teacherList) { it.id }
|
||||
@ -159,11 +144,6 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
db.lessonRangeDao().getAllNow(profileId).toSparseArray(lessonRanges) { it.lessonNumber }
|
||||
db.gradeCategoryDao().getAllNow(profileId).toSparseArray(gradeCategories) { it.categoryId }
|
||||
}
|
||||
|
||||
/*val teacher = teachers.byNameFirstLast("Jan Kowalski") ?: Teacher(1, 1, "", "").let {
|
||||
teachers.add(it)
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
|
@ -7,19 +7,13 @@ package pl.szczodrzynski.edziennik.api.v2.template
|
||||
import android.util.Log
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
|
||||
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_NOT_NEEDED
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.LibrusFeatures
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Feature
|
||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||
import pl.szczodrzynski.edziennik.api.v2.template.data.TemplateData
|
||||
import pl.szczodrzynski.edziennik.api.v2.template.login.TemplateLogin
|
||||
import pl.szczodrzynski.edziennik.api.v2.templateLoginMethods
|
||||
import pl.szczodrzynski.edziennik.api.v2.vulcan.VulcanFeatures
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_NEVER
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
@ -31,13 +25,12 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataTemplate
|
||||
private var cancelled = false
|
||||
|
||||
init {
|
||||
data = DataTemplate(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Template.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
data.satisfyLoginMethods()
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
@ -54,77 +47,9 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
||||
__/ |
|
||||
|__*/
|
||||
override fun sync(featureIds: List<Int>, viewId: Int?) {
|
||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||
|
||||
for (loginMethod in templateLoginMethods) {
|
||||
if (loginMethod.isPossible(profile, loginStore))
|
||||
possibleLoginMethods += loginMethod.loginMethodId
|
||||
}
|
||||
|
||||
//var highestLoginMethod = 0
|
||||
var endpointList = mutableListOf<Feature>()
|
||||
val requiredLoginMethods = mutableListOf<Int>()
|
||||
|
||||
data.targetEndpointIds.clear()
|
||||
data.targetLoginMethodIds.clear()
|
||||
|
||||
// get all endpoints for every feature, only if possible to login and possible/necessary to sync
|
||||
for (featureId in featureIds) {
|
||||
VulcanFeatures.filter {
|
||||
it.featureId == featureId // feature ID matches
|
||||
&& possibleLoginMethods.containsAll(it.requiredLoginMethods) // is possible to login
|
||||
&& it.shouldSync?.invoke(data) ?: true // is necessary/possible to sync
|
||||
}.let {
|
||||
endpointList.addAll(it)
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Feature::featureId, Feature::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods, filtering using timers
|
||||
.onEach { feature ->
|
||||
feature.endpointIds.forEach { endpoint ->
|
||||
(data.endpointTimers
|
||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id ?: -1, endpoint.first))
|
||||
.let { timer ->
|
||||
if (timer.nextSync == SYNC_ALWAYS ||
|
||||
(viewId != null && timer.viewId == viewId) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
for (loginMethodId in requiredLoginMethods) {
|
||||
var requiredLoginMethod: Int? = loginMethodId
|
||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||
templateLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||
if (requiredLoginMethod != null)
|
||||
data.targetLoginMethodIds.add(requiredLoginMethod!!)
|
||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort and distinct every login method and endpoint
|
||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||
data.targetLoginMethodIds.sort()
|
||||
|
||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||
data.targetEndpointIds.sort()
|
||||
|
||||
data.prepare(templateLoginMethods, TemplateFeatures, featureIds, viewId)
|
||||
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
|
||||
TemplateLogin(data) {
|
||||
TemplateData(data) {
|
||||
completed()
|
||||
@ -142,7 +67,7 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
||||
|
||||
override fun cancel() {
|
||||
Utils.d(TAG, "Cancelled")
|
||||
cancelled = true
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||
|
@ -7,18 +7,13 @@ package pl.szczodrzynski.edziennik.api.v2.vulcan
|
||||
import android.util.Log
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
|
||||
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_NOT_NEEDED
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.LibrusFeatures
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Feature
|
||||
import pl.szczodrzynski.edziennik.api.v2.prepare
|
||||
import pl.szczodrzynski.edziennik.api.v2.vulcan.data.VulcanData
|
||||
import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLogin
|
||||
import pl.szczodrzynski.edziennik.api.v2.vulcanLoginMethods
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_NEVER
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
@ -30,13 +25,12 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataVulcan
|
||||
private var cancelled = false
|
||||
|
||||
init {
|
||||
data = DataVulcan(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Vulcan.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
data.satisfyLoginMethods()
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
@ -53,77 +47,9 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
__/ |
|
||||
|__*/
|
||||
override fun sync(featureIds: List<Int>, viewId: Int?) {
|
||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||
|
||||
for (loginMethod in vulcanLoginMethods) {
|
||||
if (loginMethod.isPossible(profile, loginStore))
|
||||
possibleLoginMethods += loginMethod.loginMethodId
|
||||
}
|
||||
|
||||
//var highestLoginMethod = 0
|
||||
var endpointList = mutableListOf<Feature>()
|
||||
val requiredLoginMethods = mutableListOf<Int>()
|
||||
|
||||
data.targetEndpointIds.clear()
|
||||
data.targetLoginMethodIds.clear()
|
||||
|
||||
// get all endpoints for every feature, only if possible to login and possible/necessary to sync
|
||||
for (featureId in featureIds) {
|
||||
VulcanFeatures.filter {
|
||||
it.featureId == featureId // feature ID matches
|
||||
&& possibleLoginMethods.containsAll(it.requiredLoginMethods) // is possible to login
|
||||
&& it.shouldSync?.invoke(data) ?: true // is necessary/possible to sync
|
||||
}.let {
|
||||
endpointList.addAll(it)
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Feature::featureId, Feature::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods, filtering using timers
|
||||
.onEach { feature ->
|
||||
feature.endpointIds.forEach { endpoint ->
|
||||
(data.endpointTimers
|
||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id ?: -1, endpoint.first))
|
||||
.let { timer ->
|
||||
if (timer.nextSync == SYNC_ALWAYS ||
|
||||
(viewId != null && timer.viewId == viewId) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
for (loginMethodId in requiredLoginMethods) {
|
||||
var requiredLoginMethod: Int? = loginMethodId
|
||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||
vulcanLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||
if (requiredLoginMethod != null)
|
||||
data.targetLoginMethodIds.add(requiredLoginMethod!!)
|
||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort and distinct every login method and endpoint
|
||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||
data.targetLoginMethodIds.sort()
|
||||
|
||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||
data.targetEndpointIds.sort()
|
||||
|
||||
data.prepare(vulcanLoginMethods, VulcanFeatures, featureIds, viewId)
|
||||
Log.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
Log.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
|
||||
VulcanLogin(data) {
|
||||
VulcanData(data) {
|
||||
completed()
|
||||
@ -141,7 +67,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
|
||||
override fun cancel() {
|
||||
Utils.d(TAG, "Cancelled")
|
||||
cancelled = true
|
||||
data.cancel()
|
||||
}
|
||||
|
||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||
|
Loading…
Reference in New Issue
Block a user