forked from github/szkolny
[APIv2] Implement endpoint timers. Fix compilation issues after merge.
This commit is contained in:
parent
870a429f3d
commit
c8c933fb20
5
.idea/misc.xml
generated
5
.idea/misc.xml
generated
@ -5,6 +5,11 @@
|
||||
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
|
||||
</configurations>
|
||||
</component>
|
||||
<component name="EntryPointsManager">
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="org.greenrobot.eventbus.Subscribe" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
<option name="myDefaultNullable" value="org.jetbrains.annotations.Nullable" />
|
||||
<option name="myDefaultNotNull" value="androidx.annotation.RecentlyNonNull" />
|
||||
|
@ -129,3 +129,10 @@ fun Response?.getUnixDate(): Long {
|
||||
val format = SimpleDateFormat(pattern, Locale.ENGLISH)
|
||||
return format.parse(rfcDate).time / 1000
|
||||
}
|
||||
|
||||
const val MINUTE = 60L
|
||||
const val HOUR = 60L*MINUTE
|
||||
const val DAY = 24L*HOUR
|
||||
const val WEEK = 7L*DAY
|
||||
const val MONTH = 30L*DAY
|
||||
const val YEAR = 365L*DAY
|
@ -52,89 +52,93 @@ val endpoints = listOf(
|
||||
|
||||
// LIBRUS: API
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TIMETABLE, listOf(
|
||||
ENDPOINT_LIBRUS_API_TIMETABLES,
|
||||
ENDPOINT_LIBRUS_API_SUBSTITUTIONS
|
||||
ENDPOINT_LIBRUS_API_TIMETABLES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_SUBSTITUTIONS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_AGENDA, listOf(
|
||||
ENDPOINT_LIBRUS_API_EVENTS,
|
||||
ENDPOINT_LIBRUS_API_EVENT_TYPES,
|
||||
ENDPOINT_LIBRUS_API_PT_MEETINGS,
|
||||
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS,
|
||||
ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS,
|
||||
ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS
|
||||
ENDPOINT_LIBRUS_API_EVENTS to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_EVENT_TYPES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_PT_MEETINGS to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf(
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GC,
|
||||
ENDPOINT_LIBRUS_API_POINT_GC,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC,
|
||||
ENDPOINT_LIBRUS_API_TEXT_GC,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC,
|
||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GC,
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GRADES,
|
||||
ENDPOINT_LIBRUS_API_POINT_GRADES,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES,
|
||||
ENDPOINT_LIBRUS_API_TEXT_GRADES,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES,
|
||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_POINT_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_TEXT_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_POINT_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_TEXT_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf(
|
||||
ENDPOINT_LIBRUS_API_HOMEWORK
|
||||
ENDPOINT_LIBRUS_API_HOMEWORK to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_NOTICES, listOf(
|
||||
ENDPOINT_LIBRUS_API_NOTICES
|
||||
ENDPOINT_LIBRUS_API_NOTICES to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ATTENDANCES, listOf(
|
||||
ENDPOINT_LIBRUS_API_ATTENDANCE,
|
||||
ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES
|
||||
ENDPOINT_LIBRUS_API_ATTENDANCE to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ANNOUNCEMENTS, listOf(
|
||||
ENDPOINT_LIBRUS_API_ANNOUNCEMENTS
|
||||
ENDPOINT_LIBRUS_API_ANNOUNCEMENTS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf(
|
||||
ENDPOINT_LIBRUS_API_ME
|
||||
ENDPOINT_LIBRUS_API_ME to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SCHOOL_INFO, listOf(
|
||||
ENDPOINT_LIBRUS_API_SCHOOLS,
|
||||
ENDPOINT_LIBRUS_API_UNITS
|
||||
ENDPOINT_LIBRUS_API_SCHOOLS to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_UNITS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASS_INFO, listOf(
|
||||
ENDPOINT_LIBRUS_API_CLASSES
|
||||
ENDPOINT_LIBRUS_API_CLASSES to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEAM_INFO, listOf(
|
||||
ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES
|
||||
ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_LUCKY_NUMBER, listOf(
|
||||
ENDPOINT_LIBRUS_API_LUCKY_NUMBER
|
||||
ENDPOINT_LIBRUS_API_LUCKY_NUMBER to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEACHERS, listOf(
|
||||
ENDPOINT_LIBRUS_API_USERS
|
||||
ENDPOINT_LIBRUS_API_USERS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SUBJECTS, listOf(
|
||||
ENDPOINT_LIBRUS_API_SUBJECTS
|
||||
ENDPOINT_LIBRUS_API_SUBJECTS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASSROOMS, listOf(
|
||||
ENDPOINT_LIBRUS_API_CLASSROOMS
|
||||
ENDPOINT_LIBRUS_API_CLASSROOMS to LOGIN_METHOD_LIBRUS_API
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API)),
|
||||
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf(
|
||||
ENDPOINT_LIBRUS_SYNERGIA_INFO
|
||||
ENDPOINT_LIBRUS_SYNERGIA_INFO to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_NUMBER, listOf(
|
||||
ENDPOINT_LIBRUS_SYNERGIA_INFO
|
||||
ENDPOINT_LIBRUS_SYNERGIA_INFO to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)),
|
||||
/*Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf(
|
||||
ENDPOINT_LIBRUS_SYNERGIA_GRADES
|
||||
ENDPOINT_LIBRUS_SYNERGIA_GRADES to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)),*/
|
||||
|
||||
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf(
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GC,
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GRADES,
|
||||
ENDPOINT_LIBRUS_SYNERGIA_GRADES
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GC to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_API_NORMAL_GRADES to LOGIN_METHOD_LIBRUS_API,
|
||||
ENDPOINT_LIBRUS_SYNERGIA_GRADES to LOGIN_METHOD_LIBRUS_SYNERGIA
|
||||
), listOf(LOGIN_METHOD_LIBRUS_API, LOGIN_METHOD_LIBRUS_SYNERGIA)),
|
||||
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_INBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_RECEIVED), listOf(LOGIN_METHOD_LIBRUS_MESSAGES)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_OUTBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_SENT), listOf(LOGIN_METHOD_LIBRUS_MESSAGES))
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_INBOX, listOf(
|
||||
ENDPOINT_LIBRUS_MESSAGES_RECEIVED to LOGIN_METHOD_LIBRUS_MESSAGES
|
||||
), listOf(LOGIN_METHOD_LIBRUS_MESSAGES)),
|
||||
Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_OUTBOX, listOf(
|
||||
ENDPOINT_LIBRUS_MESSAGES_SENT to LOGIN_METHOD_LIBRUS_MESSAGES
|
||||
), listOf(LOGIN_METHOD_LIBRUS_MESSAGES))
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -15,6 +15,7 @@ import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.api.v2.librusLoginMethods
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Endpoint
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.*
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
@ -65,12 +66,6 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
|
||||
// get all endpoints for every feature, only if possible to login
|
||||
for (featureId in featureIds) {
|
||||
/*endpoints.filter { it.featureId == featureId }.forEach { endpoint ->
|
||||
if (possibleLoginMethods.containsAll(endpoint.requiredLoginMethods)) {
|
||||
endpointList.add(endpoint)
|
||||
//highestLoginMethod = max(highestLoginMethod, endpoint.requiredLoginMethods.max() ?: 0)
|
||||
}
|
||||
}*/
|
||||
endpoints.filter {
|
||||
it.featureId == featureId && possibleLoginMethods.containsAll(it.requiredLoginMethods)
|
||||
}
|
||||
@ -79,16 +74,30 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
||||
}
|
||||
}
|
||||
|
||||
val timestamp = System.currentTimeMillis()
|
||||
val viewId = 0
|
||||
|
||||
endpointList = endpointList
|
||||
// sort the endpoint list by feature ID and priority
|
||||
.sortedWith(compareBy(Endpoint::featureId, Endpoint::priority))
|
||||
// select only the most important endpoint for each feature
|
||||
.distinctBy { it.featureId }
|
||||
.toMutableList()
|
||||
// add all endpoint IDs and required login methods
|
||||
.onEach { endpoint ->
|
||||
data.targetEndpointIds.addAll(endpoint.endpointIds)
|
||||
requiredLoginMethods.addAll(endpoint.requiredLoginMethods)
|
||||
// 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 ||
|
||||
(timer.nextSync == SYNC_IF_EXPLICIT && timer.viewId == viewId) ||
|
||||
(timer.nextSync == SYNC_IF_EXPLICIT_OR_ALL && viewId == null) ||
|
||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
||||
data.targetEndpointIds.add(endpoint.first)
|
||||
requiredLoginMethods.add(endpoint.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check every login method for any dependencies
|
||||
|
@ -7,7 +7,7 @@ package pl.szczodrzynski.edziennik.api.v2.librus
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.api.v2.ENDPOINT_LIBRUS_API_ME
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApiMe
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.api.LibrusApiMe
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class LibrusEndpoints(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||
|
@ -25,6 +25,7 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
||||
fun isMessagesLoginValid() = messagesSessionIdExpiryTime-30 > currentTimeUnix() && messagesSessionId.isNotNullNorEmpty()
|
||||
|
||||
override fun satisfyLoginMethods() {
|
||||
loginMethods.clear()
|
||||
if (isPortalLoginValid())
|
||||
loginMethods += LOGIN_METHOD_LIBRUS_PORTAL
|
||||
if (isApiLoginValid())
|
||||
|
@ -1,4 +1,4 @@
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data.api
|
||||
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
@ -1,10 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-9-21.
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-10-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data.api
|
||||
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.api.v2.ENDPOINT_LIBRUS_API_ME
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApi
|
||||
|
||||
class LibrusApiMe(override val data: DataLibrus,
|
||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
||||
@ -29,6 +32,7 @@ class LibrusApiMe(override val data: DataLibrus,
|
||||
data.profile?.studentNameLong =
|
||||
buildFullName(user?.getString("FirstName"), user?.getString("LastName"))
|
||||
|
||||
data.setSyncNext(ENDPOINT_LIBRUS_API_ME, 2*DAY)
|
||||
onSuccess()
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data
|
||||
package pl.szczodrzynski.edziennik.api.v2.librus.data.synergia
|
||||
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.api.v2.interfaces.EndpointCallback
|
||||
import pl.szczodrzynski.edziennik.data.api.AppError.*
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.announcements.Announcement
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.attendance.Attendance
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.events.EventType
|
||||
@ -72,21 +73,49 @@ 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>()
|
||||
val subjectList = LongSparseArray<Subject>()
|
||||
val teamList = mutableListOf<Team>()
|
||||
|
||||
var lessonsToRemove: DataRemoveModel? = null
|
||||
val lessonList = mutableListOf<Lesson>()
|
||||
val lessonChangeList = mutableListOf<LessonChange>()
|
||||
|
||||
var gradesToRemove: DataRemoveModel? = null
|
||||
val gradeCategoryList = mutableListOf<GradeCategory>()
|
||||
val gradeList = mutableListOf<Grade>()
|
||||
|
||||
var eventsToRemove: DataRemoveModel? = null
|
||||
val eventList = mutableListOf<Event>()
|
||||
val eventTypeList = mutableListOf<EventType>()
|
||||
|
||||
var noticesToRemove: DataRemoveModel? = null
|
||||
val noticeList = mutableListOf<Notice>()
|
||||
|
||||
var attendanceToRemove: DataRemoveModel? = null
|
||||
val attendanceList = mutableListOf<Attendance>()
|
||||
|
||||
var announcementsToRemove: DataRemoveModel? = null
|
||||
val announcementList = mutableListOf<Announcement>()
|
||||
|
||||
val messageList = mutableListOf<Message>()
|
||||
val messageRecipientList = mutableListOf<MessageRecipient>()
|
||||
val messageRecipientIgnoreList = mutableListOf<MessageRecipient>()
|
||||
|
||||
val metadataList = mutableListOf<Metadata>()
|
||||
val messageMetadataList = mutableListOf<Metadata>()
|
||||
|
||||
@ -97,6 +126,9 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
clear()
|
||||
|
||||
if (profile != null) {
|
||||
db.endpointTimerDao().getAllNow(profile.id).forEach { endpointTimer ->
|
||||
endpointTimers.add(endpointTimer)
|
||||
}
|
||||
db.teacherDao().getAllNow(profile.id).forEach { teacher ->
|
||||
teacherList.put(teacher.id, teacher)
|
||||
}
|
||||
@ -114,6 +146,8 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
fun clear() {
|
||||
loginMethods.clear()
|
||||
|
||||
endpointTimers.clear()
|
||||
|
||||
teacherList.clear()
|
||||
subjectList.clear()
|
||||
teamList.clear()
|
||||
@ -139,6 +173,8 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
db.profileDao().add(profile)
|
||||
db.loginStoreDao().add(loginStore)
|
||||
|
||||
db.endpointTimerDao().addAll(endpointTimers)
|
||||
|
||||
if (teacherList.isNotEmpty()) {
|
||||
val tempList: ArrayList<Teacher> = ArrayList()
|
||||
teacherList.forEach { _, teacher ->
|
||||
@ -193,6 +229,21 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
|
||||
db.metadataDao().setSeen(messageMetadataList)
|
||||
}
|
||||
|
||||
fun setSyncNext(endpointId: Int, syncIn: Long, viewId: Int? = null, syncIfAll: Boolean = false) {
|
||||
EndpointTimer(profile?.id ?: -1, endpointId).apply {
|
||||
syncedNow()
|
||||
if (syncIn < 10) {
|
||||
nextSync = syncIn
|
||||
}
|
||||
else {
|
||||
syncIn(syncIn)
|
||||
if (viewId != null)
|
||||
syncWhenView(viewId, syncIfAll)
|
||||
}
|
||||
endpointTimers.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun error(tag: String, errorCode: Int, response: Response? = null, throwable: Throwable? = null, apiResponse: JsonObject? = null) {
|
||||
var code = when (throwable) {
|
||||
is UnknownHostException, is SSLException, is InterruptedIOException -> CODE_NO_INTERNET
|
||||
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-10-2.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.api.v2.models
|
||||
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
class DataRemoveModel {
|
||||
var removeSemester: Int? = null
|
||||
var removeDateFrom: Date? = null
|
||||
var removeDateTo: Date? = null
|
||||
|
||||
constructor(semester: Int) {
|
||||
this.removeSemester = semester
|
||||
}
|
||||
|
||||
constructor(dateFrom: Date?, dateTo: Date) {
|
||||
this.removeDateFrom = dateFrom
|
||||
this.removeDateTo = dateTo
|
||||
}
|
||||
|
||||
constructor(dateFrom: Date) {
|
||||
this.removeDateFrom = dateFrom
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ package pl.szczodrzynski.edziennik.api.v2.models
|
||||
data class Endpoint(
|
||||
val loginType: Int,
|
||||
val featureId: Int,
|
||||
val endpointIds: List<Int>,
|
||||
val endpointIds: List<Pair<Int, Int>>,
|
||||
val requiredLoginMethods: List<Int>
|
||||
) {
|
||||
val priority
|
||||
|
@ -10,6 +10,8 @@ import androidx.room.migration.Migration;
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.announcements.Announcement;
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.announcements.AnnouncementDao;
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimer;
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.api.EndpointTimerDao;
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.attendance.Attendance;
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.attendance.AttendanceDao;
|
||||
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate;
|
||||
@ -81,7 +83,8 @@ import android.content.Context;
|
||||
Message.class,
|
||||
MessageRecipient.class,
|
||||
DebugLog.class,
|
||||
Metadata.class}, version = 54)
|
||||
EndpointTimer.class,
|
||||
Metadata.class}, version = 55)
|
||||
@TypeConverters({
|
||||
ConverterTime.class,
|
||||
ConverterDate.class,
|
||||
@ -111,6 +114,7 @@ public abstract class AppDb extends RoomDatabase {
|
||||
public abstract MessageDao messageDao();
|
||||
public abstract MessageRecipientDao messageRecipientDao();
|
||||
public abstract DebugLogDao debugLogDao();
|
||||
public abstract EndpointTimerDao endpointTimerDao();
|
||||
public abstract MetadataDao metadataDao();
|
||||
|
||||
private static volatile AppDb INSTANCE;
|
||||
@ -558,6 +562,19 @@ public abstract class AppDb extends RoomDatabase {
|
||||
database.execSQL("ALTER TABLE teacherAbsence ADD teacherAbsenceTimeTo TEXT DEFAULT NULL");
|
||||
}
|
||||
};
|
||||
private static final Migration MIGRATION_54_55 = new Migration(54, 55) {
|
||||
@Override
|
||||
public void migrate(@NonNull SupportSQLiteDatabase database) {
|
||||
database.execSQL("CREATE TABLE IF NOT EXISTS endpointTimers (" +
|
||||
"profileId INTEGER NOT NULL," +
|
||||
"endpointId INTEGER NOT NULL," +
|
||||
"endpointLastSync INTEGER DEFAULT NULL," +
|
||||
"endpointNextSync INTEGER NOT NULL DEFAULT 1," +
|
||||
"endpointViewId INTEGER DEFAULT NULL," +
|
||||
"PRIMARY KEY(profileId, endpointId)" +
|
||||
")");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static AppDb getDatabase(final Context context) {
|
||||
@ -609,7 +626,8 @@ public abstract class AppDb extends RoomDatabase {
|
||||
MIGRATION_50_51,
|
||||
MIGRATION_51_52,
|
||||
MIGRATION_52_53,
|
||||
MIGRATION_53_54
|
||||
MIGRATION_53_54,
|
||||
MIGRATION_54_55
|
||||
)
|
||||
.allowMainThreadQueries()
|
||||
//.fallbackToDestructiveMigration()
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-10-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.modules.api
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
|
||||
const val SYNC_NEVER = 0L
|
||||
const val SYNC_ALWAYS = 1L
|
||||
const val SYNC_IF_EXPLICIT = 2L
|
||||
const val SYNC_IF_EXPLICIT_OR_ALL = 3L
|
||||
|
||||
@Entity(tableName = "endpointTimers",
|
||||
primaryKeys = ["profileId", "endpointId"])
|
||||
data class EndpointTimer (
|
||||
|
||||
val profileId: Int,
|
||||
|
||||
@ColumnInfo(name = "endpointId")
|
||||
val endpointId: Int,
|
||||
|
||||
@ColumnInfo(name = "endpointLastSync")
|
||||
var lastSync: Long? = null,
|
||||
|
||||
@ColumnInfo(name = "endpointNextSync")
|
||||
var nextSync: Long = SYNC_ALWAYS,
|
||||
|
||||
@ColumnInfo(name = "endpointViewId")
|
||||
var viewId: Int? = null
|
||||
|
||||
) {
|
||||
|
||||
/**
|
||||
* Tell this timer that an endpoint has just been synced.
|
||||
*/
|
||||
fun syncedNow(): EndpointTimer {
|
||||
lastSync = System.currentTimeMillis()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* This will "schedule" the next sync.
|
||||
*
|
||||
* @param nextSyncIn value in seconds
|
||||
*/
|
||||
fun syncIn(nextSyncIn: Long): EndpointTimer {
|
||||
nextSync = System.currentTimeMillis() + nextSyncIn*1000
|
||||
viewId = null
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this timer to sync only if [viewId] is the only
|
||||
* selected feature during the current process.
|
||||
*/
|
||||
fun syncWhenView(viewId: Int, syncIfAll: Boolean = false): EndpointTimer {
|
||||
nextSync = if (syncIfAll) SYNC_IF_EXPLICIT_OR_ALL else SYNC_IF_EXPLICIT
|
||||
this.viewId = viewId
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this endpoint to always sync.
|
||||
*/
|
||||
fun syncAlways(): EndpointTimer {
|
||||
nextSync = SYNC_ALWAYS
|
||||
viewId = null
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a suicide as this endpoint will never be synced again.
|
||||
*/
|
||||
fun syncNever(): EndpointTimer {
|
||||
nextSync = SYNC_NEVER
|
||||
viewId = null
|
||||
return this
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-10-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.db.modules.api
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
|
||||
@Dao
|
||||
interface EndpointTimerDao {
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun add(endpointTimer: EndpointTimer)
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun addAll(endpointTimerList: List<EndpointTimer>)
|
||||
|
||||
@Query("SELECT * FROM endpointTimers WHERE profileId = :profileId")
|
||||
fun getAllNow(profileId: Int): List<EndpointTimer>
|
||||
|
||||
@Query("DELETE FROM endpointTimers WHERE profileId = :profileId")
|
||||
fun clear(profileId: Int)
|
||||
}
|
@ -25,7 +25,7 @@ interface TeacherAbsenceDao {
|
||||
"LEFT JOIN teachers USING (profileId, teacherId) " +
|
||||
"LEFT JOIN metadata ON teacherAbsenceId = thingId AND metadata.thingType = " + Metadata.TYPE_TEACHER_ABSENCE +
|
||||
" AND metadata.profileId = :profileId WHERE teachers.profileId = :profileId")
|
||||
fun getAllFull(profileId: Int): List<TeacherAbsenceFull>
|
||||
fun getAllFullNow(profileId: Int): List<TeacherAbsenceFull>
|
||||
|
||||
@Query("SELECT *, teachers.teacherName || ' ' || teachers.teacherSurname as teacherFullName, " +
|
||||
"metadata.seen, metadata.notified, metadata.addedDate FROM teacherAbsence " +
|
||||
@ -34,4 +34,7 @@ interface TeacherAbsenceDao {
|
||||
" AND metadata.profileId = :profileId WHERE teachers.profileId = :profileId " +
|
||||
"AND :date BETWEEN teacherAbsenceDateFrom AND teacherAbsenceDateTo")
|
||||
fun getAllByDateFull(profileId: Int, date: Date): LiveData<List<TeacherAbsenceFull>>
|
||||
|
||||
@Query("DELETE FROM teacherAbsence WHERE profileId = :profileId")
|
||||
fun clear(profileId: Int)
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ public class AgendaFragment extends Fragment {
|
||||
}
|
||||
|
||||
if (app.profile.getStudentData("showTeacherAbsences", true)) {
|
||||
List<TeacherAbsenceFull> teacherAbsenceList = app.db.teacherAbsenceDao().getAllFull(App.profileId);
|
||||
List<TeacherAbsenceFull> teacherAbsenceList = app.db.teacherAbsenceDao().getAllFullNow(App.profileId);
|
||||
List<TeacherAbsenceCounter> teacherAbsenceCounters = new ArrayList<>();
|
||||
|
||||
for (TeacherAbsenceFull absence : teacherAbsenceList) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user