.*?
(.+?) (.+?)
""".toRegex(DOT_MATCHES_ALL)
- }
-
-
-
-
val LINKIFY_DATE_YMD by lazy {
"""(1\d{3}|20\d{2})[\-./](1[0-2]|0?\d)[\-./]([1-2]\d|3[0-1]|0?\d)""".toRegex()
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt
index e3692c33..097ed29e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt
@@ -8,17 +8,16 @@ import com.google.gson.JsonObject
import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
import pl.szczodrzynski.edziennik.data.api.edziennik.template.Template
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.Usos
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
import pl.szczodrzynski.edziennik.data.api.events.RegisterAvailabilityEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile
@@ -27,6 +26,7 @@ import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
import pl.szczodrzynski.edziennik.data.db.full.EventFull
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.utils.Utils.d
+import pl.szczodrzynski.edziennik.utils.managers.AvailabilityManager.Error.Type
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
companion object {
@@ -90,35 +90,21 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
return
}
- profile.registerName?.also { registerName ->
- var status = app.config.sync.registerAvailability[registerName]
- if (status == null || status.nextCheckAt < currentTimeUnix()) {
- val api = SzkolnyApi(app)
- api.runCatching({
- val availability = getRegisterAvailability()
- app.config.sync.registerAvailability = availability
- status = availability[registerName]
- }, onError = {
- val apiError = it.toApiError(TAG)
- if (apiError.errorCode == ERROR_API_INVALID_SIGNATURE) {
- return@also
- }
- taskCallback.onError(apiError)
- return
- })
- }
-
- if (status?.available != true
- || status?.minVersionCode ?: BuildConfig.VERSION_CODE > BuildConfig.VERSION_CODE) {
+ val error = app.availabilityManager.check(profile)
+ when (error?.type) {
+ Type.NOT_AVAILABLE -> {
if (EventBus.getDefault().hasSubscriberForEvent(RegisterAvailabilityEvent::class.java)) {
- EventBus.getDefault().postSticky(
- RegisterAvailabilityEvent(app.config.sync.registerAvailability)
- )
+ EventBus.getDefault().postSticky(RegisterAvailabilityEvent())
}
cancel()
taskCallback.onCompleted()
return
}
+ Type.API_ERROR -> {
+ taskCallback.onError(error.apiError!!)
+ return
+ }
+ else -> return@let
}
}
@@ -126,9 +112,9 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
- LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
+ LOGIN_TYPE_USOS -> Usos(app, profile, loginStore, taskCallback)
else -> null
}
if (edziennikInterface == null) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt
index 15da9765..27c61abc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/ProfileArchiver.kt
@@ -6,9 +6,9 @@ package pl.szczodrzynski.edziennik.data.api.edziennik
import android.content.Intent
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.Intent
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.Intent
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt
deleted file mode 100644
index 40601249..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
-
-import pl.szczodrzynski.edziennik.*
-import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
-import pl.szczodrzynski.edziennik.data.api.models.Data
-import pl.szczodrzynski.edziennik.data.db.entity.*
-
-/**
- * Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
- *
- * Use https://codepen.io/kubasz/pen/RwwwbGN to easily generate the student data getters/setters
- */
-class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
-
- fun isWebLoginValid() = webSessionIdExpiryTime-30 > currentTimeUnix() && webSessionId.isNotNullNorEmpty()
-
- override fun satisfyLoginMethods() {
- loginMethods.clear()
- if (isWebLoginValid()) {
- loginMethods += LOGIN_METHOD_EDUDZIENNIK_WEB
- }
- }
-
- override fun generateUserCode() = "$schoolName:$loginEmail:${studentId?.crc32()}"
-
- private var mLoginEmail: String? = null
- var loginEmail: String?
- get() { mLoginEmail = mLoginEmail ?: loginStore.getLoginData("email", null); return mLoginEmail }
- set(value) { loginStore.putLoginData("email", value); mLoginEmail = value }
-
- private var mLoginPassword: String? = null
- var loginPassword: String?
- get() { mLoginPassword = mLoginPassword ?: loginStore.getLoginData("password", null); return mLoginPassword }
- set(value) { loginStore.putLoginData("password", value); mLoginPassword = value }
-
- private var mStudentId: String? = null
- var studentId: String?
- get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", null); return mStudentId }
- set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value }
-
- private var mSchoolId: String? = null
- var schoolId: String?
- get() { mSchoolId = mSchoolId ?: profile?.getStudentData("schoolId", null); return mSchoolId }
- set(value) { profile?.putStudentData("schoolId", value) ?: return; mSchoolId = value }
-
- private var mClassId: String? = null
- var classId: String?
- get() { mClassId = mClassId ?: profile?.getStudentData("classId", null); return mClassId }
- set(value) { profile?.putStudentData("classId", value) ?: return; mClassId = value }
-
- /* __ __ _
- \ \ / / | |
- \ \ /\ / /__| |__
- \ \/ \/ / _ \ '_ \
- \ /\ / __/ |_) |
- \/ \/ \___|_._*/
- private var mWebSessionId: String? = null
- var webSessionId: String?
- get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("webSessionId", null); return mWebSessionId }
- set(value) { loginStore.putLoginData("webSessionId", value); mWebSessionId = value }
-
- private var mWebSessionIdExpiryTime: Long? = null
- var webSessionIdExpiryTime: Long
- get() { mWebSessionIdExpiryTime = mWebSessionIdExpiryTime ?: loginStore.getLoginData("webSessionIdExpiryTime", 0L); return mWebSessionIdExpiryTime ?: 0L }
- set(value) { loginStore.putLoginData("webSessionIdExpiryTime", value); mWebSessionIdExpiryTime = value }
-
- /* ____ _ _
- / __ \| | | |
- | | | | |_| |__ ___ _ __
- | | | | __| '_ \ / _ \ '__|
- | |__| | |_| | | | __/ |
- \____/ \__|_| |_|\___|*/
- private var mCurrentSemester: Int? = null
- var currentSemester: Int
- get() { mCurrentSemester = mCurrentSemester ?: profile?.getStudentData("currentSemester", 1); return mCurrentSemester ?: 1 }
- set(value) { profile?.putStudentData("currentSemester", value) ?: return; mCurrentSemester = value }
-
- private var mSchoolName: String? = null
- var schoolName: String?
- get() { mSchoolName = mSchoolName ?: profile?.getStudentData("schoolName", null); return mSchoolName }
- set(value) { profile?.putStudentData("schoolName", value) ?: return; mSchoolName = value }
-
- val studentEndpoint: String
- get() = "Students/$studentId/"
-
- val schoolEndpoint: String
- get() = "Schools/$schoolId/"
-
- val classStudentEndpoint: String
- get() = "Class/$studentId/"
-
- val schoolClassEndpoint: String
- get() = "Schools/$classId/"
-
- val studentAndClassEndpoint: String
- get() = "Students/$studentId/Klass/$classId/"
-
- val studentAndClassesEndpoint: String
- get() = "Students/$studentId/Classes/$classId/"
-
- val timetableEndpoint: String
- get() = "Plan/$studentId/"
-
- val studentAndTeacherClassEndpoint: String
- get() = "Students/$studentId/Teachers/$classId/"
-
- val courseStudentEndpoint: String
- get() = "Course/$studentId/"
-
- fun getSubject(longId: String, name: String): Subject {
- val id = longId.crc32()
- return subjectList.singleOrNull { it.id == id } ?: run {
- val subject = Subject(profileId, id, name, name)
- subjectList.put(id, subject)
- subject
- }
- }
-
- fun getTeacher(firstName: String, lastName: String, longId: String? = null): Teacher {
- val name = "$firstName $lastName".fixName()
- val id = name.crc32()
- return teacherList.singleOrNull { it.id == id }?.also {
- if (longId != null && it.loginId == null) it.loginId = longId
- } ?: run {
- val teacher = Teacher(profileId, id, firstName, lastName, longId)
- teacherList.put(id, teacher)
- teacher
- }
- }
-
- fun getTeacherByFirstLast(nameFirstLast: String, longId: String? = null): Teacher {
- val nameParts = nameFirstLast.split(" ")
- return getTeacher(nameParts[0], nameParts[1], longId)
- }
-
- fun getTeacherByLastFirst(nameLastFirst: String, longId: String? = null): Teacher {
- val nameParts = nameLastFirst.split(" ")
- return getTeacher(nameParts[1], nameParts[0], longId)
- }
-
- fun getEventType(longId: String, name: String): EventType {
- val id = longId.crc16().toLong()
- return eventTypes.singleOrNull { it.id == id } ?: run {
- val eventType = EventType(profileId, id, name, colorFromName(name))
- eventTypes.put(id, eventType)
- eventType
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt
deleted file mode 100644
index 23d9d3b1..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
-
-import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.data.api.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetHomework
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
-import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
-import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
-import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
-import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.data.db.entity.Teacher
-import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
-import pl.szczodrzynski.edziennik.data.db.full.EventFull
-import pl.szczodrzynski.edziennik.data.db.full.MessageFull
-import pl.szczodrzynski.edziennik.utils.Utils.d
-
-class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
- companion object {
- private const val TAG = "Edudziennik"
- }
-
- val internalErrorList = mutableListOf
()
- val data: DataEdudziennik
- private var afterLogin: (() -> Unit)? = null
-
- init {
- data = DataEdudziennik(app, profile, loginStore).apply {
- callback = wrapCallback(this@Edudziennik.callback)
- satisfyLoginMethods()
- }
- }
-
- private fun completed() {
- data.saveData()
- callback.onCompleted()
- }
-
- /* _______ _ _ _ _ _
- |__ __| | /\ | | (_) | | |
- | | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___
- | | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \
- | | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | |
- |_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
- __/ |
- |__*/
- override fun sync(featureIds: List, viewId: Int?, onlyEndpoints: List?, arguments: JsonObject?) {
- data.arguments = arguments
- data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId, onlyEndpoints)
- login()
- }
-
- private fun login(loginMethodId: Int? = null, afterLogin: (() -> Unit)? = null) {
- d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
- if (internalErrorList.isNotEmpty()) {
- d(TAG, " - Internal errors:")
- internalErrorList.forEach { d(TAG, " - code $it") }
- }
- loginMethodId?.let { data.prepareFor(edudziennikLoginMethods, it) }
- afterLogin?.let { this.afterLogin = it }
- EdudziennikLogin(data) {
- data()
- }
- }
-
- private fun data() {
- d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
- if (internalErrorList.isNotEmpty()) {
- d(TAG, " - Internal errors:")
- internalErrorList.forEach { d(TAG, " - code $it") }
- }
- afterLogin?.invoke() ?: EdudziennikData(data) {
- completed()
- }
- }
-
- override fun getMessage(message: MessageFull) {}
- override fun sendMessage(recipients: List, subject: String, text: String) {}
- override fun markAllAnnouncementsAsRead() {}
-
- override fun getAnnouncement(announcement: AnnouncementFull) {
- EdudziennikLoginWeb(data) {
- EdudziennikWebGetAnnouncement(data, announcement) {
- completed()
- }
- }
- }
-
- override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
- override fun getRecipientList() {}
-
- override fun getEvent(eventFull: EventFull) {
- EdudziennikLoginWeb(data) {
- EdudziennikWebGetHomework(data, eventFull) {
- completed()
- }
- }
- }
-
- override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
- override fun cancel() {
- d(TAG, "Cancelled")
- data.cancel()
- }
-
- private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
- return object : EdziennikCallback {
- override fun onCompleted() { callback.onCompleted() }
- override fun onProgress(step: Float) { callback.onProgress(step) }
- override fun onStartProgress(stringRes: Int) { callback.onStartProgress(stringRes) }
- override fun onError(apiError: ApiError) {
- if (apiError.errorCode in internalErrorList) {
- // finish immediately if the same error occurs twice during the same sync
- callback.onError(apiError)
- return
- }
- internalErrorList.add(apiError.errorCode)
- when (apiError.errorCode) {
- ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED -> {
- login()
- }
- ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID -> {
- login()
- }
- ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS -> {
- data()
- }
- else -> callback.onError(apiError)
- }
- }
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt
deleted file mode 100644
index c3fd17ed..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-23
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
-
-import pl.szczodrzynski.edziennik.data.api.*
-import pl.szczodrzynski.edziennik.data.api.models.Feature
-
-const val ENDPOINT_EDUDZIENNIK_WEB_START = 1000
-const val ENDPOINT_EDUDZIENNIK_WEB_TEACHERS = 1001
-const val ENDPOINT_EDUDZIENNIK_WEB_GRADES = 1011
-const val ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE = 1012
-const val ENDPOINT_EDUDZIENNIK_WEB_EXAMS = 1013
-const val ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE = 1014
-const val ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS = 1015
-const val ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK = 1016
-const val ENDPOINT_EDUDZIENNIK_WEB_EVENTS = 1017
-const val ENDPOINT_EDUDZIENNIK_WEB_NOTES = 1018
-const val ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER = 1030
-
-val EdudziennikFeatures = listOf(
- /* School and team info and subjects */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_STUDENT_INFO, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_START to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Teachers */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TEACHERS, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_TEACHERS to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Timetable */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TIMETABLE, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Grades */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_GRADES, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_GRADES to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Agenda */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_AGENDA, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_EXAMS to LOGIN_METHOD_EDUDZIENNIK_WEB,
- ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB,
- ENDPOINT_EDUDZIENNIK_WEB_EVENTS to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Homework */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_HOMEWORK, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Behaviour */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_BEHAVIOUR, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_NOTES to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Attendance */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ATTENDANCE, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Announcements */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ANNOUNCEMENTS, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
-
- /* Lucky number */
- Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
- ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER to LOGIN_METHOD_EDUDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB))
-)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt
deleted file mode 100644
index 7eb58d1c..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
-
-import pl.szczodrzynski.edziennik.R
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.*
-import pl.szczodrzynski.edziennik.utils.Utils
-
-class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) {
- companion object {
- private const val TAG = "EdudziennikData"
- }
-
- init {
- nextEndpoint(onSuccess)
- }
-
- private fun nextEndpoint(onSuccess: () -> Unit) {
- if (data.targetEndpointIds.isEmpty()) {
- onSuccess()
- return
- }
- if (data.cancelled) {
- onSuccess()
- return
- }
- val id = data.targetEndpointIds.firstKey()
- val lastSync = data.targetEndpointIds.remove(id)
- useEndpoint(id, lastSync) { endpointId ->
- data.progress(data.progressStep)
- nextEndpoint(onSuccess)
- }
- }
-
- private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
- Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
- when (endpointId) {
- ENDPOINT_EDUDZIENNIK_WEB_START -> {
- data.startProgress(R.string.edziennik_progress_endpoint_data)
- EdudziennikWebStart(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
- data.startProgress(R.string.edziennik_progress_endpoint_teachers)
- EdudziennikWebTeachers(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
- data.startProgress(R.string.edziennik_progress_endpoint_grades)
- EdudziennikWebGrades(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
- data.startProgress(R.string.edziennik_progress_endpoint_timetable)
- EdudziennikWebTimetable(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
- data.startProgress(R.string.edziennik_progress_endpoint_exams)
- EdudziennikWebExams(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
- data.startProgress(R.string.edziennik_progress_endpoint_attendance)
- EdudziennikWebAttendance(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
- data.startProgress(R.string.edziennik_progress_endpoint_announcements)
- EdudziennikWebAnnouncements(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
- data.startProgress(R.string.edziennik_progress_endpoint_homework)
- EdudziennikWebHomework(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
- data.startProgress(R.string.edziennik_progress_endpoint_events)
- EdudziennikWebEvents(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
- data.startProgress(R.string.edziennik_progress_endpoint_notices)
- EdudziennikWebNotes(data, lastSync, onSuccess)
- }
- ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
- data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
- EdudziennikWebLuckyNumber(data, lastSync, onSuccess)
- }
- else -> onSuccess(endpointId)
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt
deleted file mode 100644
index f5adfc5d..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
-
-import im.wangchao.mhttp.Request
-import im.wangchao.mhttp.Response
-import im.wangchao.mhttp.callback.TextCallbackHandler
-import pl.szczodrzynski.edziennik.data.api.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.utils.Utils.d
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Long?) {
- companion object {
- private const val TAG = "EdudziennikWeb"
- }
-
- val profileId
- get() = data.profile?.id ?: -1
-
- val profile
- get() = data.profile
-
- fun webGet(tag: String, endpoint: String, xhr: Boolean = false, semester: Int? = null, onSuccess: (text: String) -> Unit) {
- val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) {
- true -> endpoint
- else -> "$endpoint/"
- } + (semester?.let { "?semester=" + if(it == -1) "all" else it } ?: "")
-
- d(tag, "Request: Edudziennik/Web - $url")
-
- val callback = object : TextCallbackHandler() {
- override fun onSuccess(text: String?, response: Response?) {
- if (text == null || response == null) {
- data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
- .withResponse(response))
- return
- }
-
- if (semester == null && url.contains("start")) {
- profile?.also { profile ->
- val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
- val semesterCookie = cookies["semester"]?.toIntOrNull()
-
- semesterCookie?.let { data.currentSemester = it }
-
- if (semesterCookie == 2 && profile.dateSemester2Start > Date.getToday())
- profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
- }
- }
-
- try {
- onSuccess(text)
- } catch (e: Exception) {
- data.error(ApiError(tag, EXCEPTION_EDUDZIENNIK_WEB_REQUEST)
- .withThrowable(e)
- .withResponse(response)
- .withApiResponse(text))
- }
- }
-
- override fun onFailure(response: Response?, throwable: Throwable?) {
- val error = when (response?.code()) {
- 402 -> ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS
- 403 -> ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED
- else -> ERROR_REQUEST_FAILURE
- }
- data.error(ApiError(tag, error)
- .withResponse(response)
- .withThrowable(throwable))
- }
- }
-
- data.app.cookieJar.set("dziennikel.appspot.com", "sessionid", data.webSessionId)
-
- Request.builder()
- .url(url)
- .userAgent(EDUDZIENNIK_USER_AGENT)
- .apply {
- if (xhr) header("X-Requested-With", "XMLHttpRequest")
- }
- .get()
- .callback(callback)
- .build()
- .enqueue()
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt
deleted file mode 100644
index 32ca353c..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-26
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ANNOUNCEMENT_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.db.entity.Announcement
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- const val TAG = "EdudziennikWebAnnouncements"
- }
-
- init { data.profile?.also { profile ->
- webGet(TAG, data.schoolClassEndpoint + "Announcements") { text ->
- val doc = Jsoup.parse(text)
-
- if (doc.getElementsByClass("message").text().trim() != "Brak ogłoszeń.") {
- doc.select("table.list tbody tr").forEach { announcementElement ->
- val titleElement = announcementElement.child(0).child(0)
-
- val longId = EDUDZIENNIK_ANNOUNCEMENT_ID.find(titleElement.attr("href"))?.get(1)
- ?: return@forEach
- val id = longId.crc32()
- val subject = titleElement.text()
-
- val teacherName = announcementElement.child(1).text()
- val teacher = data.getTeacherByFirstLast(teacherName)
-
- val dateString = announcementElement.getElementsByClass("datetime").first().text()
- val startDate = Date.fromY_m_d(dateString)
- val addedDate = Date.fromIsoHm(dateString)
-
- val announcementObject = Announcement(
- profileId = profileId,
- id = id,
- subject = subject,
- text = null,
- startDate = startDate,
- endDate = null,
- teacherId = teacher.id,
- addedDate = addedDate
- ).also {
- it.idString = longId
- }
-
- data.announcementList.add(announcementObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_ANNOUNCEMENT,
- id,
- profile.empty,
- profile.empty
- ))
- }
- }
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt
deleted file mode 100644
index 7fe18171..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-24
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_ENTRIES
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPE
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPES
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.db.entity.Attendance
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
-import pl.szczodrzynski.edziennik.utils.models.Date
-import java.util.*
-
-class EdudziennikWebAttendance(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebAttendance"
- }
-
- private var requestSemester: Int? = null
-
- init {
- if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
- getAttendances()
- }
-
- private fun getAttendances() { data.profile?.also { profile ->
- webGet(TAG, data.studentEndpoint + "Presence", semester = requestSemester) { text ->
-
- val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
- val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
- val symbol = type?.get(1)?.trim() ?: "?"
- val name = type?.get(2)?.trim() ?: "nieznany rodzaj"
- return@map Triple(
- symbol,
- name,
- when (name.toLowerCase(Locale.ROOT)) {
- "obecność" -> Attendance.TYPE_PRESENT
- "nieobecność" -> Attendance.TYPE_ABSENT
- "spóźnienie" -> Attendance.TYPE_BELATED
- "nieobecność usprawiedliwiona" -> Attendance.TYPE_ABSENT_EXCUSED
- "dzień wolny" -> Attendance.TYPE_DAY_FREE
- "brak zajęć" -> Attendance.TYPE_DAY_FREE
- "oddelegowany" -> Attendance.TYPE_RELEASED
- else -> Attendance.TYPE_UNKNOWN
- }
- )
- } ?: emptyList()
-
- EDUDZIENNIK_ATTENDANCE_ENTRIES.findAll(text).forEach { attendanceElement ->
- val date = Date.fromY_m_d(attendanceElement[1])
- val lessonNumber = attendanceElement[2].toInt()
- val attendanceSymbol = attendanceElement[3]
-
- val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
- val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber }
-
- val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32()
-
- val (typeSymbol, typeName, baseType) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol }
- ?: return@forEach
-
- val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime
- ?: return@forEach
-
- val attendanceObject = Attendance(
- profileId = profileId,
- id = id,
- baseType = baseType,
- typeName = typeName,
- typeShort = data.app.attendanceManager.getTypeShort(baseType),
- typeSymbol = typeSymbol,
- typeColor = null,
- date = date,
- startTime = lesson?.displayStartTime ?: startTime,
- semester = profile.currentSemester,
- teacherId = lesson?.displayTeacherId ?: -1,
- subjectId = lesson?.displaySubjectId ?: -1
- ).also {
- it.lessonNumber = lessonNumber
- }
-
- data.attendanceList.add(attendanceObject)
- if (baseType != Attendance.TYPE_PRESENT) {
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_ATTENDANCE,
- id,
- profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN,
- profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN
- ))
- }
- }
-
- if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
- requestSemester = null
- getAttendances()
- } else {
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE)
- }
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt
deleted file mode 100644
index 35c68478..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2020-1-1
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EVENTS
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
-import pl.szczodrzynski.edziennik.data.db.entity.Event
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebEvents(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- const val TAG = "EdudziennikWebEvents"
- }
-
- init { data.profile?.also { profile ->
- webGet(TAG, data.studentAndClassesEndpoint + "KlassEvent", xhr = true) { text ->
- val doc = Jsoup.parseBodyFragment("")
-
- doc.getElementsByTag("tr").forEach { eventElement ->
- val date = Date.fromY_m_d(eventElement.child(1).text())
-
- val titleElement = eventElement.child(2).child(0)
- val title = titleElement.text().trim()
-
- val id = EDUDZIENNIK_EVENT_ID.find(titleElement.attr("href"))?.get(1)?.crc32()
- ?: return@forEach
-
- val eventObject = Event(
- profileId = profileId,
- id = id,
- date = date,
- time = null,
- topic = title,
- color = null,
- type = Event.TYPE_CLASS_EVENT,
- teacherId = -1,
- subjectId = -1,
- teamId = data.teamClass?.id ?: -1
- )
-
- data.eventList.add(eventObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_EVENT,
- id,
- profile.empty,
- profile.empty
- ))
- }
-
- data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt
deleted file mode 100644
index f6abf637..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-24
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_TYPE_ID
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EXAM_ID
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
-import pl.szczodrzynski.edziennik.data.db.entity.Event
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebExams(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- const val TAG = "EdudziennikWebExams"
- }
-
- init { profile?.also { profile ->
- webGet(TAG, data.studentAndClassEndpoint + "Evaluations", xhr = true) { text ->
- val doc = Jsoup.parseBodyFragment("")
-
- doc.select("tr").forEach { examElement ->
- val id = EDUDZIENNIK_EXAM_ID.find(examElement.child(0).child(0).attr("href"))
- ?.get(1)?.crc32() ?: return@forEach
- val topic = examElement.child(0).text().trim()
-
- val subjectElement = examElement.child(1).child(0)
- val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
- ?: return@forEach
- val subjectName = subjectElement.text().trim()
- val subject = data.getSubject(subjectId, subjectName)
-
- val dateString = examElement.child(2).text().trim()
- if (dateString.isBlank()) return@forEach
- val date = Date.fromY_m_d(dateString)
-
- val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
- val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime
-
- val eventTypeElement = examElement.child(3).child(0)
- val eventTypeId = EDUDZIENNIK_EVENT_TYPE_ID.find(eventTypeElement.attr("href"))?.get(1)
- ?: return@forEach
- val eventTypeName = eventTypeElement.text()
- val eventType = data.getEventType(eventTypeId, eventTypeName)
-
- val eventObject = Event(
- profileId = profileId,
- id = id,
- date = date,
- time = startTime,
- topic = topic,
- color = null,
- type = eventType.id,
- teacherId = -1,
- subjectId = subject.id,
- teamId = data.teamClass?.id ?: -1
- )
-
- data.eventList.add(eventObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_EVENT,
- id,
- profile.empty,
- profile.empty
- ))
- }
-
- data.toRemove.add(DataRemoveModel.Events.futureExceptTypes(listOf(
- Event.TYPE_HOMEWORK,
- Event.TYPE_CLASS_EVENT
- )))
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EXAMS)
- }
- }}
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt
deleted file mode 100644
index 5d915e64..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-26
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.data.api.Regexes
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
-import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
-import pl.szczodrzynski.edziennik.get
-
-class EdudziennikWebGetAnnouncement(override val data: DataEdudziennik,
- private val announcement: AnnouncementFull,
- val onSuccess: () -> Unit
-) : EdudziennikWeb(data, null) {
- companion object {
- const val TAG = "EdudziennikWebGetAnnouncement"
- }
-
- init {
- webGet(TAG, "Announcement/${announcement.idString}") { text ->
- val description = Regexes.EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION.find(text)?.get(1)?.trim() ?: ""
-
- announcement.text = description
-
- EventBus.getDefault().postSticky(AnnouncementGetEvent(announcement))
-
- data.announcementList.add(announcement)
- onSuccess()
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt
deleted file mode 100644
index 84171699..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import android.text.Html
-import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.data.api.Regexes
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
-import pl.szczodrzynski.edziennik.data.db.full.EventFull
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
-
-class EdudziennikWebGetHomework(
- override val data: DataEdudziennik,
- val event: EventFull,
- val onSuccess: () -> Unit
-) : EdudziennikWeb(data, null) {
- companion object {
- const val TAG = "EdudziennikWebGetHomework"
- }
-
- init {
- if (event.attachmentNames.isNotNullNorEmpty()) {
- val id = event.attachmentNames!![0]
-
- webGet(TAG, "Homework/$id") { text ->
- val description = Regexes.EDUDZIENNIK_HOMEWORK_DESCRIPTION.find(text)?.get(1)?.trim()
-
- if (description != null) event.topic = Html.fromHtml(description).toString()
-
- event.homeworkBody = ""
- event.attachmentNames = null
-
- data.eventList += event
- data.eventListReplace = true
-
- EventBus.getDefault().postSticky(EventGetEvent(event))
- onSuccess()
- }
- } else {
- EventBus.getDefault().postSticky(EventGetEvent(event))
- onSuccess()
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt
deleted file mode 100644
index 459f13aa..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-25
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import android.graphics.Color
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.colorFromCssName
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_GRADES
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
-import pl.szczodrzynski.edziennik.data.db.entity.Grade
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
-import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.Utils
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebGrades(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebGrades"
- }
-
- private var requestSemester: Int? = null
-
- init {
- if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
- getGrades()
- }
-
- private fun getGrades() { data.profile?.also { profile ->
- webGet(TAG, data.studentEndpoint + "start", semester = requestSemester) { text ->
- val semester = requestSemester ?: data.currentSemester
-
- val doc = Jsoup.parse(text)
- val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
-
- subjects?.forEach { subjectElement ->
- if (subjectElement.id().isBlank()) return@forEach
-
- val subjectId = subjectElement.id().trim()
- val subjectName = subjectElement.child(0).text().trim()
- val subject = data.getSubject(subjectId, subjectName)
-
- val gradeType = when {
- subjectElement.select("#sum").text().isNotBlank() -> TYPE_POINT_SUM
- else -> TYPE_NORMAL
- }
-
- val gradeCountToAverage = subjectElement.select("#avg").text().isNotBlank()
-
- val grades = subjectElement.select(".grade[data-edited]")
- val gradesInfo = subjectElement.select(".grade-tip")
-
- val gradeValues = if (grades.isNotEmpty()) {
- subjects.select(".avg-$subjectId .grade-tip > p").first()
- .text().split('+').map {
- val split = it.split('*')
- val value = split[1].trim().toFloatOrNull()
- val weight = value?.let { split[0].trim().toFloatOrNull() } ?: 0f
-
- Pair(value ?: 0f, weight)
- }
- } else emptyList()
-
- grades.forEachIndexed { index, gradeElement ->
- val id = Regexes.EDUDZIENNIK_GRADE_ID.find(gradeElement.attr("href"))?.get(1)?.crc32()
- ?: return@forEachIndexed
- val (value, weight) = gradeValues[index]
- val name = gradeElement.text().trim().let {
- if (it.contains(',') || it.contains('.')) {
- val replaced = it.replace(',', '.')
- val float = replaced.toFloatOrNull()
-
- if (float != null && float % 1 == 0f) float.toInt().toString()
- else it
- } else it
- }
-
- val info = gradesInfo[index]
- val fullName = info.child(0).text().trim()
- val columnName = info.child(4).text().trim()
- val comment = info.ownText()
-
- val description = columnName + if (comment.isNotBlank()) " - $comment" else null
-
- val teacherName = info.child(1).text()
- val teacher = data.getTeacherByLastFirst(teacherName)
-
- val addedDate = info.child(2).text().split(' ').let {
- val day = it[0].toInt()
- val month = Utils.monthFromName(it[1])
- val year = it[2].toInt()
-
- Date(year, month, day).inMillis
- }
-
- val color = Regexes.STYLE_CSS_COLOR.find(gradeElement.attr("style"))?.get(1)?.let {
- if (it.startsWith('#')) Color.parseColor(it)
- else colorFromCssName(it)
- } ?: -1
-
- val gradeObject = Grade(
- profileId = profileId,
- id = id,
- name = name,
- type = gradeType,
- value = value,
- weight = if (gradeCountToAverage) weight else 0f,
- color = color,
- category = fullName,
- description = description,
- comment = null,
- semester = semester,
- teacherId = teacher.id,
- subjectId = subject.id,
- addedDate = addedDate
- )
-
- data.gradeList.add(gradeObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_GRADE,
- id,
- profile.empty,
- profile.empty
- ))
- }
-
- val proposed = subjectElement.select(".proposal").firstOrNull()?.text()?.trim()
-
- if (proposed != null && proposed.isNotBlank()) {
- val proposedGradeObject = Grade(
- profileId = profileId,
- id = (-1 * subject.id) - 1,
- name = proposed,
- type = when (semester) {
- 1 -> TYPE_SEMESTER1_PROPOSED
- else -> TYPE_SEMESTER2_PROPOSED
- },
- value = proposed.toFloatOrNull() ?: 0f,
- weight = 0f,
- color = -1,
- category = null,
- description = null,
- comment = null,
- semester = semester,
- teacherId = -1,
- subjectId = subject.id
- )
-
- data.gradeList.add(proposedGradeObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_GRADE,
- proposedGradeObject.id,
- profile.empty,
- profile.empty
- ))
- }
-
- val final = subjectElement.select(".final").firstOrNull()?.text()?.trim()
-
- if (final != null && final.isNotBlank()) {
- val finalGradeObject = Grade(
- profileId = profileId,
- id = (-1 * subject.id) - 2,
- name = final,
- type = when (semester) {
- 1 -> TYPE_SEMESTER1_FINAL
- else -> TYPE_SEMESTER2_FINAL
- },
- value = final.toFloatOrNull() ?: 0f,
- weight = 0f,
- color = -1,
- category = null,
- description = null,
- comment = null,
- semester = semester,
- teacherId = -1,
- subjectId = subject.id
- )
-
- data.gradeList.add(finalGradeObject)
- data.metadataList.add(Metadata(
- data.profileId,
- Metadata.TYPE_GRADE,
- finalGradeObject.id,
- profile.empty,
- profile.empty
- ))
- }
- }
-
- if (!subjects.isNullOrEmpty()) {
- data.toRemove.addAll(listOf(
- TYPE_NORMAL,
- TYPE_POINT_SUM,
- TYPE_SEMESTER1_PROPOSED,
- TYPE_SEMESTER2_PROPOSED,
- TYPE_SEMESTER1_FINAL,
- TYPE_SEMESTER2_FINAL
- ).map {
- DataRemoveModel.Grades.semesterWithType(semester, it)
- })
- }
-
- if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
- requestSemester = null
- getGrades()
- } else {
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES)
- }
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt
deleted file mode 100644
index 169a5127..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-29
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_HOMEWORK_ID
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
-import pl.szczodrzynski.edziennik.data.db.entity.Event
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebHomework(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- const val TAG = "EdudziennikWebHomework"
- }
-
- init { data.profile?.also { profile ->
- webGet(TAG, data.courseStudentEndpoint + "Homework", xhr = true) { text ->
- val doc = Jsoup.parseBodyFragment("")
-
- if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
- doc.getElementsByTag("tr").forEach { homeworkElement ->
- val dateElement = homeworkElement.getElementsByClass("date").first().child(0)
- val idStr = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1) ?: return@forEach
- val id = idStr.crc32()
- val date = Date.fromY_m_d(dateElement.text())
-
- val subjectElement = homeworkElement.child(1).child(0)
- val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
- ?: return@forEach
- val subjectName = subjectElement.text()
- val subject = data.getSubject(subjectId, subjectName)
-
- val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
- val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime
-
- val teacherName = homeworkElement.child(2).text()
- val teacher = data.getTeacherByFirstLast(teacherName)
-
- val topic = homeworkElement.child(4).text()?.trim()
-
- val eventObject = Event(
- profileId = profileId,
- id = id,
- date = date,
- time = startTime,
- topic = topic ?: "",
- color = null,
- type = Event.TYPE_HOMEWORK,
- teacherId = teacher.id,
- subjectId = subject.id,
- teamId = data.teamClass?.id ?: -1
- )
-
- eventObject.attachmentNames = mutableListOf(idStr)
-
- data.eventList.add(eventObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_HOMEWORK,
- id,
- profile.empty,
- profile.empty
- ))
- }
- }
-
- data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt
deleted file mode 100644
index db8164c8..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-23
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebLuckyNumber"
- }
-
- init { data.profile?.also { profile ->
- webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
- text.toIntOrNull()?.also { luckyNumber ->
- val luckyNumberObject = LuckyNumber(
- profileId = profileId,
- date = Date.getToday(),
- number = luckyNumber
- )
-
- data.luckyNumberList.add(luckyNumberObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_LUCKY_NUMBER,
- luckyNumberObject.date.value.toLong(),
- true,
- profile.empty
- ))
- }
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt
deleted file mode 100644
index 35a78168..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2020-1-1
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_NOTE_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.Notice
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.utils.models.Date
-
-class EdudziennikWebNotes(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- const val TAG = "EdudziennikWebNotes"
- }
-
- init { data.profile?.also { profile ->
- webGet(TAG, data.classStudentEndpoint + "RegistryNotesStudent", xhr = true) { text ->
- val doc = Jsoup.parseBodyFragment("")
-
- doc.getElementsByTag("tr").forEach { noteElement ->
- val dateElement = noteElement.getElementsByClass("date").first().child(0)
- val addedDate = Date.fromY_m_d(dateElement.text()).inMillis
-
- val id = EDUDZIENNIK_NOTE_ID.find(dateElement.attr("href"))?.get(0)?.crc32()
- ?: return@forEach
-
- val teacherName = noteElement.child(1).text()
- val teacher = data.getTeacherByFirstLast(teacherName)
-
- val description = noteElement.child(3).text()
-
- val noticeObject = Notice(
- profileId = profileId,
- id = id,
- type = Notice.TYPE_NEUTRAL,
- semester = profile.currentSemester,
- text = description,
- category = null,
- points = null,
- teacherId = teacher.id,
- addedDate = addedDate
- )
-
- data.noticeList.add(noticeObject)
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_NOTICE,
- id,
- profile.empty,
- profile.empty
- ))
- }
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt
deleted file mode 100644
index 66cb7a59..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-23
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import pl.szczodrzynski.edziennik.MONTH
-import pl.szczodrzynski.edziennik.crc32
-import pl.szczodrzynski.edziennik.data.api.ERROR_EDUDZIENNIK_WEB_TEAM_MISSING
-import pl.szczodrzynski.edziennik.data.api.Regexes
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECTS_START
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_START
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.data.db.entity.Team
-import pl.szczodrzynski.edziennik.firstLettersName
-import pl.szczodrzynski.edziennik.get
-
-class EdudziennikWebStart(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebStart"
- }
-
- init {
- webGet(TAG, data.studentEndpoint + "start") { text ->
- getSchoolAndTeam(text)
- getSubjects(text)
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_START)
- }
- }
-
- private fun getSchoolAndTeam(text: String) {
- val schoolId = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)?.trim()
- val schoolLongName = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_NAME.find(text)?.get(1)?.trim()
- data.schoolId = schoolId
-
- val classId = Regexes.EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)?.trim()
- val className = Regexes.EDUDZIENNIK_CLASS_DETAIL_NAME.find(text)?.get(1)?.trim()
- data.classId = classId
-
- if (classId == null || className == null || schoolId == null || schoolLongName == null) {
- data.error(ApiError(TAG, ERROR_EDUDZIENNIK_WEB_TEAM_MISSING)
- .withApiResponse(text))
- return
- }
-
- val schoolName = schoolId.crc32().toString() + schoolLongName.firstLettersName + "_edu"
- data.schoolName = schoolName
-
- val teamId = classId.crc32()
- val teamCode = "$schoolName:$className"
-
- val teamObject = Team(
- data.profileId,
- teamId,
- className,
- Team.TYPE_CLASS,
- teamCode,
- -1
- )
-
- data.teamClass = teamObject
- data.teamList.put(teamObject.id, teamObject)
- }
-
- private fun getSubjects(text: String) {
- EDUDZIENNIK_SUBJECTS_START.findAll(text).forEach {
- val id = it[1].trim()
- val name = it[2].trim()
- data.getSubject(id, name)
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt
deleted file mode 100644
index d2f3ba15..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-25
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import pl.szczodrzynski.edziennik.MONTH
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHERS
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TEACHERS
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.get
-
-class EdudziennikWebTeachers(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebTeachers"
- }
-
- init {
- webGet(TAG, data.studentAndTeacherClassEndpoint + "grid") { text ->
- EDUDZIENNIK_TEACHERS.findAll(text).forEach {
- val lastName = it[1].trim()
- val firstName = it[2].trim()
- data.getTeacher(firstName, lastName)
- }
-
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS)
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt
deleted file mode 100644
index 94db15ef..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-23
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
-
-import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHER_ID
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
-import pl.szczodrzynski.edziennik.data.db.entity.Lesson
-import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.getString
-import pl.szczodrzynski.edziennik.singleOrNull
-import pl.szczodrzynski.edziennik.utils.Utils.d
-import pl.szczodrzynski.edziennik.utils.models.Date
-import pl.szczodrzynski.edziennik.utils.models.Time
-import pl.szczodrzynski.edziennik.utils.models.Week
-
-class EdudziennikWebTimetable(override val data: DataEdudziennik,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : EdudziennikWeb(data, lastSync) {
- companion object {
- private const val TAG = "EdudziennikWebTimetable"
- }
-
- init { data.profile?.also { profile ->
-
- val currentWeekStart = Week.getWeekStart()
-
- if (Date.getToday().weekDay > 4) {
- currentWeekStart.stepForward(0, 0, 7)
- }
-
- val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
-
- val weekStart = Date.fromY_m_d(getDate)
- val weekEnd = weekStart.clone().stepForward(0, 0, 6)
-
- webGet(TAG, data.timetableEndpoint + "print?date=$getDate") { text ->
- val doc = Jsoup.parse(text)
-
- val dataDays = mutableListOf()
- val dataStart = weekStart.clone()
- while (dataStart <= weekEnd) {
- dataDays += dataStart.value
- dataStart.stepForward(0, 0, 1)
- }
-
- val table = doc.select("#Schedule tbody").first()
-
- if (!table.text().contains("Brak planu lekcji.")) {
- table.children().forEach { row ->
- val rowElements = row.children()
-
- val lessonNumber = rowElements[0].text().toInt()
-
- val times = rowElements[1].text().split('-')
- val startTime = Time.fromH_m(times[0].trim())
- val endTime = Time.fromH_m(times[1].trim())
-
- data.lessonRanges.singleOrNull {
- it.lessonNumber == lessonNumber && it.startTime == startTime && it.endTime == endTime
- } ?: run {
- data.lessonRanges.put(lessonNumber, LessonRange(profileId, lessonNumber, startTime, endTime))
- }
-
- rowElements.subList(2, rowElements.size).forEachIndexed { index, lesson ->
- val course = lesson.select(".course").firstOrNull() ?: return@forEachIndexed
- val info = course.select("span > span")
-
- if (info.isEmpty()) return@forEachIndexed
-
- val type = when (course.hasClass("substitute")) {
- true -> Lesson.TYPE_CHANGE
- else -> Lesson.TYPE_NORMAL
- }
-
- /* Getting subject */
-
- val subjectElement = info[0].child(0)
- val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
- ?: return@forEachIndexed
- val subjectName = subjectElement.text().trim()
- val subject = data.getSubject(subjectId, subjectName)
-
- /* Getting teacher */
-
- val teacherId = if (info.size >= 2) {
- val teacherElement = info[1].child(0)
- val teacherLongId = EDUDZIENNIK_TEACHER_ID.find(teacherElement.attr("href"))?.get(1)
- val teacherName = teacherElement.text().trim()
- data.getTeacherByLastFirst(teacherName, teacherLongId).id
- } else null
-
- val lessonObject = Lesson(profileId, -1).also {
- it.type = type
- it.date = weekStart.clone().stepForward(0, 0, index)
- it.lessonNumber = lessonNumber
- it.startTime = startTime
- it.endTime = endTime
- it.subjectId = subject.id
- it.teacherId = teacherId
- it.teamId = data.teamClass?.id
-
- it.id = it.buildId()
- }
-
- data.lessonList.add(lessonObject)
- dataDays.remove(lessonObject.date!!.value)
-
- if (type != Lesson.TYPE_NORMAL) {
- val seen = profile.empty || lessonObject.date!! < Date.getToday()
-
- data.metadataList.add(Metadata(
- profileId,
- Metadata.TYPE_LESSON_CHANGE,
- lessonObject.id,
- seen,
- seen
- ))
- }
- }
- }
- }
-
- for (day in dataDays) {
- val lessonDate = Date.fromValue(day)
- data.lessonList += Lesson(profileId, lessonDate.value.toLong()).apply {
- type = Lesson.TYPE_NO_LESSONS
- date = lessonDate
- }
- }
-
- d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate")
-
- data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
- data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
- onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE)
- }
- } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt
deleted file mode 100644
index a93632b1..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin
-
-import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_EDUDZIENNIK
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ACCOUNT_NAME_START
-import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_STUDENTS_START
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
-import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
-import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.getShortName
-import pl.szczodrzynski.edziennik.set
-
-class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
- companion object {
- private const val TAG = "EdudziennikFirstLogin"
- }
-
- private val web = EdudziennikWeb(data, null)
- private val profileList = mutableListOf()
-
- init {
- val loginStoreId = data.loginStore.id
- val loginStoreType = LOGIN_TYPE_EDUDZIENNIK
- var firstProfileId = loginStoreId
-
- EdudziennikLoginWeb(data) {
- web.webGet(TAG, "") { text ->
- val accountNameLong = EDUDZIENNIK_ACCOUNT_NAME_START.find(text)?.get(1)?.fixName()
-
- EDUDZIENNIK_STUDENTS_START.findAll(text).forEach {
- val studentId = it[1]
- val studentNameLong = it[2].fixName()
-
- if (studentId.isBlank() || studentNameLong.isBlank()) return@forEach
-
- val studentNameShort = studentNameLong.getShortName()
- val accountName = if (accountNameLong == studentNameLong) null else accountNameLong
-
- val profile = Profile(
- firstProfileId++,
- loginStoreId,
- loginStoreType,
- studentNameLong,
- data.loginEmail,
- studentNameLong,
- studentNameShort,
- accountName
- ).apply {
- studentData["studentId"] = studentId
- }
- profileList.add(profile)
- }
-
- EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
- onSuccess()
- }
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt
deleted file mode 100644
index 6b1615a2..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login
-
-import im.wangchao.mhttp.Request
-import im.wangchao.mhttp.Response
-import im.wangchao.mhttp.callback.TextCallbackHandler
-import pl.szczodrzynski.edziennik.data.api.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getUnixDate
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
-import pl.szczodrzynski.edziennik.utils.Utils.d
-
-class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
- companion object {
- private const val TAG = "EdudziennikLoginWeb"
- }
-
- init { run {
- if (data.isWebLoginValid()) {
- onSuccess()
- }
- else {
- data.app.cookieJar.clear("dziennikel.appspot.com")
- if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
- loginWithCredentials()
- }
- else {
- data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING))
- }
- }
- }}
-
- private fun loginWithCredentials() {
- d(TAG, "Request: Edudziennik/Login/Web - https://dziennikel.appspot.com/login/?next=/")
-
- val callback = object : TextCallbackHandler() {
- override fun onSuccess(text: String?, response: Response?) {
- if (text == null || response == null) {
- data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
- .withResponse(response))
- return
- }
-
- val url = response.raw().request().url().toString()
-
- if (!url.contains("Student")) {
- when {
- text.contains("Wprowadzono nieprawidłową nazwę użytkownika lub hasło.") -> ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN
- else -> ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER
- }.let { errorCode ->
- data.error(ApiError(TAG, errorCode)
- .withApiResponse(text)
- .withResponse(response))
- return
- }
- }
-
- val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
- val sessionId = cookies["sessionid"]
-
- if (sessionId == null) {
- data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
- .withResponse(response)
- .withApiResponse(text))
- return
- }
-
- data.webSessionId = sessionId
- data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
- onSuccess()
- }
-
- override fun onFailure(response: Response?, throwable: Throwable?) {
- data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
- .withResponse(response)
- .withThrowable(throwable))
- }
- }
-
- Request.builder()
- .url("https://dziennikel.appspot.com/login/?next=/")
- .userAgent(EDUDZIENNIK_USER_AGENT)
- .contentType("application/x-www-form-urlencoded")
- .addParameter("email", data.loginEmail)
- .addParameter("password", data.loginPassword)
- .addParameter("auth_method", "password")
- .addParameter("next", "/")
- .post()
- .callback(callback)
- .build()
- .enqueue()
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/DataLibrus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/DataLibrus.kt
index e77dd50d..5d82191d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/DataLibrus.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/DataLibrus.kt
@@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_API
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_MESSAGES
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_PORTAL
@@ -13,7 +12,8 @@ import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_LIBRUS_SYNERGIA
import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/Librus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/Librus.kt
index abf3ac5f..0830752f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/Librus.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/Librus.kt
@@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages.Librus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
@@ -162,6 +163,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
return object : EdziennikCallback {
override fun onCompleted() { callback.onCompleted() }
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) { callback.onRequiresUserAction(event) }
override fun onProgress(step: Float) { callback.onProgress(step) }
override fun onStartProgress(stringRes: Int) { callback.onStartProgress(stringRes) }
override fun onError(apiError: ApiError) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/LibrusRecaptchaHelper.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/LibrusRecaptchaHelper.kt
index 3652f18a..a44076b4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/LibrusRecaptchaHelper.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/LibrusRecaptchaHelper.kt
@@ -10,7 +10,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
-import pl.szczodrzynski.edziennik.startCoroutineTimer
+import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
import kotlin.coroutines.CoroutineContext
class LibrusRecaptchaHelper(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusApi.kt
index d06cc219..2b736a0f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusApi.kt
@@ -11,7 +11,7 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection.*
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusData.kt
index 877d803b..db72ddcc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusData.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusData.kt
@@ -182,10 +182,6 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_pt_meetings)
LibrusApiPtMeetings(data, lastSync, onSuccess)
}
- ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES -> {
- data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_day_types)
- LibrusApiTeacherFreeDayTypes(data, lastSync, onSuccess)
- }
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS -> {
data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_days)
LibrusApiTeacherFreeDays(data, lastSync, onSuccess)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusPortal.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusPortal.kt
index 4a5e0af6..d1d34226 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusPortal.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/LibrusPortal.kt
@@ -7,7 +7,7 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAnnouncements.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAnnouncements.kt
index d19be231..fcf68cad 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAnnouncements.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAnnouncements.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiAnnouncements(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendanceTypes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendanceTypes.kt
index c620d13d..417a1de0 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendanceTypes.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendanceTypes.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiAttendanceTypes(override val data: DataLibrus,
override val lastSync: Long?,
@@ -58,7 +59,7 @@ class LibrusApiAttendanceTypes(override val data: DataLibrus,
))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 2*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 2* DAY)
onSuccess(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendances.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendances.kt
index 7857dc2a..314a0716 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendances.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiAttendances.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiAttendances(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeCategories.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeCategories.kt
index 650dfbb5..24992be1 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeCategories.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeCategories.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiBehaviourGradeCategories(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeComments.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeComments.kt
index eedb1d1d..4f44c0f0 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeComments.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGradeComments.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiBehaviourGradeComments(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGrades.kt
index fae79a50..7a528407 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiBehaviourGrades.kt
@@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
import java.text.DecimalFormat
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClasses.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClasses.kt
index 171e80e1..43baf873 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClasses.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClasses.kt
@@ -4,14 +4,14 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_CLASSES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Team
-import pl.szczodrzynski.edziennik.getJsonObject
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiClasses(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClassrooms.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClassrooms.kt
index 80a11105..6fbebca5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClassrooms.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiClassrooms.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_CLASSROOMS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Classroom
+import pl.szczodrzynski.edziennik.ext.*
import java.util.*
class LibrusApiClassrooms(override val data: DataLibrus,
@@ -25,8 +26,8 @@ class LibrusApiClassrooms(override val data: DataLibrus,
classrooms?.forEach { classroom ->
val id = classroom.getLong("Id") ?: return@forEach
- val name = classroom.getString("Name")?.toLowerCase(Locale.getDefault()) ?: ""
- val symbol = classroom.getString("Symbol")?.toLowerCase(Locale.getDefault()) ?: ""
+ val name = classroom.getString("Name")?.lowercase() ?: ""
+ val symbol = classroom.getString("Symbol")?.lowercase() ?: ""
val nameShort = name.fixWhiteSpaces().split(" ").onEach { it[0] }.joinToString()
val symbolParts = symbol.fixWhiteSpaces().split(" ")
@@ -40,7 +41,7 @@ class LibrusApiClassrooms(override val data: DataLibrus,
data.classrooms.put(id, Classroom(profileId, id, friendlyName))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSROOMS, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSROOMS, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_CLASSROOMS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGradeCategories.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGradeCategories.kt
index 94ce6972..c48d34f8 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGradeCategories.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGradeCategories.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiDescriptiveGradeCategories(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGrades.kt
index 8cc4f1c1..9b214d04 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiDescriptiveGrades.kt
@@ -15,6 +15,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_TEXT
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiDescriptiveGrades(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEventTypes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEventTypes.kt
index 331b8249..c2129ba6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEventTypes.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEventTypes.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_EVENT_TYPES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.EventType
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiEventTypes(override val data: DataLibrus,
override val lastSync: Long?,
@@ -30,7 +31,7 @@ class LibrusApiEventTypes(override val data: DataLibrus,
data.eventTypes.put(id, EventType(profileId, id, name, color))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_EVENT_TYPES, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_EVENT_TYPES, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_EVENT_TYPES)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEvents.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEvents.kt
index 7a76f88e..82a0e267 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEvents.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiEvents.kt
@@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeCategories.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeCategories.kt
index 518e643f..c6c4fecc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeCategories.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeCategories.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiGradeCategories(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeComments.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeComments.kt
index 971ac35b..96225b67 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeComments.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGradeComments.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiGradeComments(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGrades.kt
index c2e2d0ce..58621a0e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiGrades.kt
@@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPO
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiHomework.kt
index c1183c19..f304aaad 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiHomework.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiHomework(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLessons.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLessons.kt
index e32790c9..66075008 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLessons.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLessons.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_LESSONS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.LibrusLesson
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiLessons(override val data: DataLibrus,
override val lastSync: Long?,
@@ -39,7 +40,7 @@ class LibrusApiLessons(override val data: DataLibrus,
data.librusLessons.put(id, librusLesson)
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_LESSONS, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_LESSONS, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_LESSONS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLuckyNumber.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLuckyNumber.kt
index 80e6e299..6ebe9e63 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLuckyNumber.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiLuckyNumber.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_LUCKY_NUMBER
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -22,7 +22,7 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
}
init {
- var nextSync = System.currentTimeMillis() + 2*DAY*1000
+ var nextSync = System.currentTimeMillis() + 2* DAY *1000
apiGet(TAG, "LuckyNumbers") { json ->
if (json.isJsonNull) {
@@ -41,7 +41,7 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
if (luckyNumberDate >= Date.getToday())
nextSync = luckyNumberDate.combineWith(Time(15, 0, 0))
else
- nextSync = System.currentTimeMillis() + 6*HOUR*1000
+ nextSync = System.currentTimeMillis() + 6* HOUR *1000
data.luckyNumberList.add(luckyNumberObject)
data.metadataList.add(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiMe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiMe.kt
index 9d5ce1d4..ea46971f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiMe.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiMe.kt
@@ -4,10 +4,10 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_ME
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiMe(override val data: DataLibrus,
override val lastSync: Long?,
@@ -34,7 +34,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)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_ME, 2* DAY)
onSuccess(ENDPOINT_LIBRUS_API_ME)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNoticeTypes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNoticeTypes.kt
index 55e753ee..7e90fbb2 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNoticeTypes.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNoticeTypes.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NOTICE_TYPES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.NoticeType
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiNoticeTypes(override val data: DataLibrus,
override val lastSync: Long?,
@@ -29,7 +30,7 @@ class LibrusApiNoticeTypes(override val data: DataLibrus,
data.noticeTypes.put(id, NoticeType(profileId, id, name))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICE_TYPES, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICE_TYPES, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_NOTICE_TYPES)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNotices.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNotices.kt
index ba531afe..ea61428e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNotices.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiNotices.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Notice
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiNotices(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGradeCategories.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGradeCategories.kt
index bba6ead9..775f0897 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGradeCategories.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGradeCategories.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiPointGradeCategories(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGrades.kt
index 9da2c435..8a7ad29f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPointGrades.kt
@@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiPointGrades(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPtMeetings.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPtMeetings.kt
index 6c0a9dd7..170c6135 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPtMeetings.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPtMeetings.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -64,7 +65,7 @@ class LibrusApiPtMeetings(override val data: DataLibrus,
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_PT_MEETING))
- data.setSyncNext(ENDPOINT_LIBRUS_API_PT_MEETINGS, 12*HOUR)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_PT_MEETINGS, 12* HOUR)
onSuccess(ENDPOINT_LIBRUS_API_PT_MEETINGS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPushConfig.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPushConfig.kt
index 9073d03f..5dac1841 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPushConfig.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiPushConfig.kt
@@ -4,13 +4,13 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
-import pl.szczodrzynski.edziennik.JsonObject
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_PUSH_CONFIG
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getJsonObject
+import pl.szczodrzynski.edziennik.ext.JsonObject
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getJsonObject
class LibrusApiPushConfig(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSchools.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSchools.kt
index d405f9bf..e42ab949 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSchools.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSchools.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_SCHOOLS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Time
import java.util.*
@@ -29,7 +30,7 @@ class LibrusApiSchools(override val data: DataLibrus,
// create the school's short name using first letters of each long name's word
// append the town name and save to student data
val schoolNameShort = schoolNameLong?.firstLettersName
- val schoolTown = school?.getString("Town")?.toLowerCase(Locale.getDefault())
+ val schoolTown = school?.getString("Town")?.lowercase()
data.schoolName = schoolId.toString() + schoolNameShort + "_" + schoolTown
school?.getJsonArray("LessonsRange")?.let { ranges ->
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSubjects.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSubjects.kt
index cfd9bd31..17e30559 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSubjects.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiSubjects.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_SUBJECTS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Subject
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiSubjects(override val data: DataLibrus,
override val lastSync: Long?,
@@ -32,7 +33,7 @@ class LibrusApiSubjects(override val data: DataLibrus,
data.subjectList.put(1, Subject(profileId, 1, "Zachowanie", "zach"))
- data.setSyncNext(ENDPOINT_LIBRUS_API_SUBJECTS, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_SUBJECTS, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_SUBJECTS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDayTypes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDayTypes.kt
deleted file mode 100644
index e09504bf..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDayTypes.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2019-10-19
- */
-
-package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
-
-import pl.szczodrzynski.edziennik.*
-import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
-import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES
-import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
-import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsenceType
-
-class LibrusApiTeacherFreeDayTypes(override val data: DataLibrus,
- override val lastSync: Long?,
- val onSuccess: (endpointId: Int) -> Unit
-) : LibrusApi(data, lastSync) {
- companion object {
- const val TAG = "LibrusApiTeacherFreeDayTypes"
- }
-
- init {
- apiGet(TAG, "TeacherFreeDays/Types") { json ->
- val teacherAbsenceTypes = json.getJsonArray("Types")?.asJsonObjectList()
-
- teacherAbsenceTypes?.forEach { teacherAbsenceType ->
- val id = teacherAbsenceType.getLong("Id") ?: return@forEach
- val name = teacherAbsenceType.getString("Name") ?: return@forEach
-
- val teacherAbsenceTypeObject = TeacherAbsenceType(
- profileId,
- id,
- name
- )
-
- data.teacherAbsenceTypes.put(id, teacherAbsenceTypeObject)
- }
-
- data.setSyncNext(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES, 7 * DAY)
- onSuccess(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES)
- }
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDays.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDays.kt
index 973ada46..09ed5416 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDays.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTeacherFreeDays.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsence
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -35,8 +36,6 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
val id = teacherAbsence.getLong("Id") ?: return@forEach
val teacherId = teacherAbsence.getJsonObject("Teacher")?.getLong("Id")
?: return@forEach
- val type = teacherAbsence.getJsonObject("Type").getLong("Id") ?: return@forEach
- val name = data.teacherAbsenceTypes.singleOrNull { it.id == type }?.name
val dateFrom = Date.fromY_m_d(teacherAbsence.getString("DateFrom"))
val dateTo = Date.fromY_m_d(teacherAbsence.getString("DateTo"))
val timeFrom = teacherAbsence.getString("TimeFrom")?.let { Time.fromH_m_s(it) }
@@ -45,8 +44,8 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
val teacherAbsenceObject = TeacherAbsence(
profileId = profileId,
id = id,
- type = type,
- name = name,
+ type = -1L,
+ name = null,
dateFrom = dateFrom,
dateTo = dateTo,
timeFrom = timeFrom,
@@ -64,7 +63,7 @@ class LibrusApiTeacherFreeDays(override val data: DataLibrus,
))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS, 6*HOUR, DRAWER_ITEM_AGENDA)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS, 6* HOUR, DRAWER_ITEM_AGENDA)
onSuccess(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGradeCategories.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGradeCategories.kt
index 45b6b069..441e3b60 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGradeCategories.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGradeCategories.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_TEXT_GRADE_CATEGORIES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiTextGradeCategories(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGrades.kt
index 7b7c8c6f..bb19f11f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTextGrades.kt
@@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIV
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiTextGrades(override val data: DataLibrus,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTimetables.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTimetables.kt
index 9a463a6b..b224a381 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTimetables.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiTimetables.kt
@@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUnits.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUnits.kt
index 791283ed..03fcf4a5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUnits.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUnits.kt
@@ -8,6 +8,7 @@ import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_UNITS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiUnits(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUsers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUsers.kt
index 0ac9a5ea..fb82849f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUsers.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiUsers.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_USERS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiUsers(override val data: DataLibrus,
override val lastSync: Long?,
@@ -37,7 +38,7 @@ class LibrusApiUsers(override val data: DataLibrus,
data.teacherList.put(id, teacher)
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_USERS, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_USERS, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_USERS)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiVirtualClasses.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiVirtualClasses.kt
index 9937f808..2d6a7958 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiVirtualClasses.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/api/LibrusApiVirtualClasses.kt
@@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Team
+import pl.szczodrzynski.edziennik.ext.*
class LibrusApiVirtualClasses(override val data: DataLibrus,
override val lastSync: Long?,
@@ -31,7 +32,7 @@ class LibrusApiVirtualClasses(override val data: DataLibrus,
data.teamList.put(id, Team(profileId, id, name, 2, code, teacherId))
}
- data.setSyncNext(ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES, 4*DAY)
+ data.setSyncNext(ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES, 4* DAY)
onSuccess(ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetList.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetList.kt
index 9f962bf9..7d0cfeef 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetList.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetList.kt
@@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
import pl.szczodrzynski.edziennik.data.api.ERROR_NOT_IMPLEMENTED
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
@@ -13,8 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_MESS
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
import pl.szczodrzynski.edziennik.data.db.entity.*
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
@@ -109,7 +109,7 @@ class LibrusMessagesGetList(override val data: DataLibrus,
id
)
- element.select("isAnyFileAttached")?.text()?.let {
+ element.select("isAnyFileAttached").text()?.let {
if (it == "1")
messageObject.hasAttachments = true
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetMessage.kt
index 49ee0d52..8e6435c6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetMessage.kt
@@ -15,10 +15,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
-import pl.szczodrzynski.edziennik.notEmptyOrNull
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.notEmptyOrNull
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
import java.nio.charset.Charset
@@ -35,7 +35,7 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
"messageId" to messageObject.id,
"archive" to 0
)) { doc ->
- val message = doc.select("response GetMessage data").first()
+ val message = doc.select("response GetMessage data").first() ?: return@messagesGet
val body = Base64.decode(message.select("Message").text(), Base64.DEFAULT)
.toString(Charset.defaultCharset())
@@ -108,7 +108,7 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
readDate = readDate
)
- messageRecipientObject.fullName = profile.accountName ?: profile.studentNameLong ?: ""
+ messageRecipientObject.fullName = profile.accountName ?: profile.studentNameLong
messageRecipientList.add(messageRecipientObject)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetRecipientList.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetRecipientList.kt
index 053258d8..b6881f17 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetRecipientList.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesGetRecipientList.kt
@@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
import pl.szczodrzynski.edziennik.data.api.events.RecipientListGetEvent
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.ext.*
class LibrusMessagesGetRecipientList(override val data: DataLibrus,
val onSuccess: () -> Unit
@@ -28,9 +29,9 @@ class LibrusMessagesGetRecipientList(override val data: DataLibrus,
messagesGet(TAG, "Receivers/action/GetTypes", parameters = mapOf(
"includeClass" to 1
)) { doc ->
- doc.select("response GetTypes data list ArrayItem")?.forEach {
- val id = it.getElementsByTag("id")?.firstOrNull()?.ownText() ?: return@forEach
- val name = it.getElementsByTag("name")?.firstOrNull()?.ownText() ?: return@forEach
+ doc.select("response GetTypes data list ArrayItem").forEach {
+ val id = it.getElementsByTag("id").firstOrNull()?.ownText() ?: return@forEach
+ val name = it.getElementsByTag("name").firstOrNull()?.ownText() ?: return@forEach
listTypes += id to name
}
@@ -55,7 +56,7 @@ class LibrusMessagesGetRecipientList(override val data: DataLibrus,
if (dataEl is JsonObject) {
val listEl = dataEl.get("ArrayItem")
if (listEl is JsonArray) {
- listEl.asJsonObjectList()?.forEach { item ->
+ listEl.asJsonObjectList().forEach { item ->
processElement(item, type.first, type.second)
}
}
@@ -71,7 +72,7 @@ class LibrusMessagesGetRecipientList(override val data: DataLibrus,
private fun processElement(element: JsonObject, typeId: String, typeName: String, listName: String? = null) {
val listEl = element.getJsonObject("list")?.get("ArrayItem")
if (listEl is JsonArray) {
- listEl.asJsonObjectList()?.let { list ->
+ listEl.asJsonObjectList().let { list ->
val label = element.getString("label") ?: ""
list.forEach { item ->
processElement(item, typeId, typeName, label)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesSendMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesSendMessage.kt
index d568135e..02248e99 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesSendMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusMessagesSendMessage.kt
@@ -5,16 +5,15 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.messages
import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.base64Encode
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
import pl.szczodrzynski.edziennik.data.db.entity.Message
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
-import pl.szczodrzynski.edziennik.getJsonObject
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.base64Encode
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
class LibrusMessagesSendMessage(override val data: DataLibrus,
val recipients: List,
@@ -42,14 +41,14 @@ class LibrusMessagesSendMessage(override val data: DataLibrus,
val id = response.getLong("data")
if (response.getString("status") != "ok" || id == null) {
- val message = response.getString("message")
+ // val message = response.getString("message")
// TODO error
return@messagesGetJson
}
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = null) {
- val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.id == id }
- val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
+ val message = data.messageList.firstOrNull { it.isSent && it.id == id }
+ // val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusSandboxDownloadAttachment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusSandboxDownloadAttachment.kt
index 567071aa..c58c185f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusSandboxDownloadAttachment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/messages/LibrusSandboxDownloadAttachment.kt
@@ -7,8 +7,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusMessages
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils
import java.io.File
import kotlin.coroutines.CoroutineContext
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetHomework.kt
index 379bd42d..4ba502f0 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetHomework.kt
@@ -1,12 +1,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia
-import android.text.Html
import org.greenrobot.eventbus.EventBus
import org.jsoup.Jsoup
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
import pl.szczodrzynski.edziennik.data.db.full.EventFull
+import pl.szczodrzynski.edziennik.utils.html.BetterHtml
class LibrusSynergiaGetHomework(override val data: DataLibrus,
val event: EventFull,
@@ -23,7 +23,11 @@ class LibrusSynergiaGetHomework(override val data: DataLibrus,
val table = doc.select("table.decorated tbody > tr")
event.topic = table[1].select("td")[1].text()
- event.homeworkBody = Html.fromHtml(table[5].select("td")[1].html()).toString()
+ event.homeworkBody = BetterHtml.fromHtml(
+ context = null,
+ html = table[5].select("td")[1].html(),
+ ).toString()
+ event.isDownloaded = true
event.attachmentIds = mutableListOf()
event.attachmentNames = mutableListOf()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessage.kt
index 4cb1e246..b9df2af1 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessage.kt
@@ -10,10 +10,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
-import pl.szczodrzynski.edziennik.singleOrNull
-import pl.szczodrzynski.edziennik.swapFirstLastName
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.singleOrNull
+import pl.szczodrzynski.edziennik.ext.swapFirstLastName
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusSynergiaGetMessage(override val data: DataLibrus,
@@ -87,7 +87,7 @@ class LibrusSynergiaGetMessage(override val data: DataLibrus,
})
}
- val readDateText = readElement.select(".left").text()
+ val readDateText = readElement?.select(".left")?.text()
val readDate = when (readDateText.isNotNullNorEmpty()) {
true -> Date.fromIso(readDateText)
else -> 0
@@ -108,7 +108,7 @@ class LibrusSynergiaGetMessage(override val data: DataLibrus,
Message.TYPE_SENT -> {
- readElement.select("tr").forEachIndexed { i, receiver ->
+ readElement?.select("tr")?.forEachIndexed { i, receiver ->
if (i == 0) return@forEachIndexed // Skip the header
val receiverFullName = receiver.child(0).text()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessages.kt
index ffc8133a..01cc69f6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessages.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaGetMessages.kt
@@ -7,6 +7,7 @@ import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
import pl.szczodrzynski.edziennik.data.db.entity.*
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
@@ -36,19 +37,19 @@ class LibrusSynergiaGetMessages(override val data: DataLibrus,
fun getRecipientId(name: String): Long = data.teacherList.singleOrNull {
it.fullNameLastFirst == name
- }?.id ?: {
+ }?.id ?: run {
val teacherObject = Teacher(
- profileId,
- -1 * Utils.crc16(name.swapFirstLastName().toByteArray()).toLong(),
- name.splitName()?.second!!,
- name.splitName()?.first!!
+ profileId,
+ -1 * Utils.crc16(name.swapFirstLastName().toByteArray()).toLong(),
+ name.splitName()?.second!!,
+ name.splitName()?.first!!
)
data.teacherList.put(teacherObject.id, teacherObject)
teacherObject.id
- }.invoke()
+ }
doc.select(".decorated.stretch tbody > tr").forEach { messageElement ->
- val url = messageElement.select("a").first().attr("href")
+ val url = messageElement.select("a").first()?.attr("href") ?: return@forEach
val id = Regexes.LIBRUS_MESSAGE_ID.find(url)?.get(1)?.toLong() ?: return@forEach
val subject = messageElement.child(3).text()
val sentDate = Date.fromIso(messageElement.child(4).text())
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaHomework.kt
index d33f6911..ddf6635c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaHomework.kt
@@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia
import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
import pl.szczodrzynski.edziennik.data.api.POST
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
@@ -14,8 +13,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.HOUR
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusSynergiaHomework(override val data: DataLibrus,
@@ -42,7 +42,7 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
doc.select("table.myHomeworkTable > tbody").firstOrNull()?.also { homeworkTable ->
val homeworkElements = homeworkTable.children()
- homeworkElements.forEachIndexed { i, el ->
+ homeworkElements.forEach { el ->
val elements = el.children()
val subjectName = elements[0].text().trim()
@@ -56,7 +56,7 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
val eventDate = Date.fromY_m_d(elements[6].text().trim())
val id = "/podglad/([0-9]+)'".toRegex().find(
elements[9].select("input").attr("onclick")
- )?.get(1)?.toLong() ?: return@forEachIndexed
+ )?.get(1)?.toLong() ?: return@forEach
val lessons = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
val startTime = lessons.firstOrNull { it.subjectId == subjectId }?.startTime
@@ -79,6 +79,7 @@ class LibrusSynergiaHomework(override val data: DataLibrus,
teamId = data.teamClass?.id ?: -1,
addedDate = addedDate.inMillis
)
+ eventObject.isDownloaded = false
data.eventList.add(eventObject)
data.metadataList.add(Metadata(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaInfo.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaInfo.kt
index 66e11785..74458fb5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaInfo.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/data/synergia/LibrusSynergiaInfo.kt
@@ -5,10 +5,10 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.synergia
import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.MONTH
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_SYNERGIA_INFO
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusSynergia
+import pl.szczodrzynski.edziennik.ext.MONTH
class LibrusSynergiaInfo(override val data: DataLibrus,
override val lastSync: Long?,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/firstlogin/LibrusFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/firstlogin/LibrusFirstLogin.kt
index 68f44269..43e5bda9 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/firstlogin/LibrusFirstLogin.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/firstlogin/LibrusFirstLogin.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPor
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.*
class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginApi.kt
index 7151cf29..58f7181d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginApi.kt
@@ -12,9 +12,9 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getString
-import pl.szczodrzynski.edziennik.getUnixDate
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection.*
@@ -63,7 +63,7 @@ class LibrusLoginApi {
}
private fun copyFromLoginStore() {
- data.loginStore.data?.apply {
+ data.loginStore.data.apply {
if (has("accountLogin")) {
data.apiLogin = getString("accountLogin")
remove("accountLogin")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginMessages.kt
index 9bfad99f..2a61f641 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginMessages.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginMessages.kt
@@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.LibrusRecaptchaHelper
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getUnixDate
+import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.io.StringWriter
import javax.xml.parsers.DocumentBuilderFactory
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginPortal.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginPortal.kt
index f164e3ed..ab21c692 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginPortal.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginPortal.kt
@@ -10,7 +10,9 @@ import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection.*
import java.util.*
@@ -83,7 +85,7 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
} else {
val csrfMatcher = Pattern.compile("name=\"csrf-token\" content=\"([A-z0-9=+/\\-_]+?)\"", Pattern.DOTALL).matcher(text)
if (csrfMatcher.find()) {
- login(csrfMatcher.group(1))
+ login(csrfMatcher.group(1) ?: "")
} else {
data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING)
.withResponse(response)
@@ -147,12 +149,23 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
val error = if (response.code() == 200) null else
json.getJsonArray("errors")?.getString(0)
?: json.getJsonObject("errors")?.entrySet()?.firstOrNull()?.value?.asString
+
+ if (error?.contains("robotem") == true || json.getBoolean("captchaRequired") == true) {
+ data.requireUserAction(
+ type = UserActionRequiredEvent.Type.RECAPTCHA,
+ params = Bundle(
+ "siteKey" to LIBRUS_PORTAL_RECAPTCHA_KEY,
+ "referer" to LIBRUS_PORTAL_RECAPTCHA_REFERER,
+ ),
+ errorText = R.string.notification_user_action_required_captcha_librus,
+ )
+ return
+ }
+
error?.let { code ->
when {
code.contains("Sesja logowania wygasła") -> ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED
code.contains("Upewnij się, że nie") -> ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN
- // this doesn't work anyway: `errors` is an object with `g-recaptcha-response` set
- code.contains("robotem") -> ERROR_CAPTCHA_LIBRUS_PORTAL
code.contains("Podany adres e-mail jest nieprawidłowy.") -> ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN
else -> ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR
}.let { errorCode ->
@@ -162,12 +175,6 @@ class LibrusLoginPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
return
}
}
- if (json.getBoolean("captchaRequired") == true) {
- data.error(ApiError(TAG, ERROR_CAPTCHA_LIBRUS_PORTAL)
- .withResponse(response)
- .withApiResponse(json))
- return
- }
authorize(json.getString("redirect", LIBRUS_AUTHORIZE_URL))
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginSynergia.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginSynergia.kt
index 4a292cfe..a95af893 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginSynergia.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/LibrusLoginSynergia.kt
@@ -12,8 +12,8 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getString
-import pl.szczodrzynski.edziennik.getUnixDate
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.getUnixDate
import pl.szczodrzynski.edziennik.utils.Utils.d
import java.net.HttpURLConnection
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/SynergiaTokenExtractor.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/SynergiaTokenExtractor.kt
index 5072e5a2..807bb131 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/SynergiaTokenExtractor.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/librus/login/SynergiaTokenExtractor.kt
@@ -7,6 +7,7 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusPortal
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
class SynergiaTokenExtractor(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusPortal(data) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/DataMobidziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/DataMobidziennik.kt
index ddfb0113..cee3cda5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/DataMobidziennik.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/DataMobidziennik.kt
@@ -6,12 +6,14 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik
import android.util.LongSparseArray
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_MOBIDZIENNIK_WEB
+import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -35,6 +37,31 @@ class DataMobidziennik(app: App, profile: Profile?, loginStore: LoginStore) : Da
override fun generateUserCode() = "$loginServerName:$loginUsername:$studentId"
+ fun parseDateTime(dateStr: String): Pair {
+ // pt, 4 lut, 09:11
+ val dateParts = dateStr.split(',', ' ').filter { it.isNotEmpty() }
+ // [pt], [4], [lut], [09:11]
+ val date = Date.getToday()
+ date.day = dateParts[1].toIntOrNull() ?: 1
+ date.month = when (dateParts[2]) {
+ "sty" -> 1
+ "lut" -> 2
+ "mar" -> 3
+ "kwi" -> 4
+ "maj" -> 5
+ "cze" -> 6
+ "lip" -> 7
+ "sie" -> 8
+ "wrz" -> 9
+ "paź" -> 10
+ "lis" -> 11
+ "gru" -> 12
+ else -> 1
+ }
+ val time = Time.fromH_m(dateParts[3])
+ return date to time
+ }
+
val teachersMap = LongSparseArray()
val subjectsMap = LongSparseArray()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/Mobidziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/Mobidziennik.kt
index 0e002576..0144ad5d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/Mobidziennik.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/Mobidziennik.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.Mobidzien
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web.*
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.firstlogin.MobidziennikFirstLogin
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLogin
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
@@ -120,8 +121,15 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
override fun getEvent(eventFull: EventFull) {
login(LOGIN_METHOD_MOBIDZIENNIK_WEB) {
- MobidziennikWebGetHomework(data, eventFull) {
- completed()
+ if (eventFull.isHomework) {
+ MobidziennikWebGetHomework(data, eventFull) {
+ completed()
+ }
+ }
+ else {
+ MobidziennikWebGetEvent(data, eventFull) {
+ completed()
+ }
}
}
}
@@ -135,6 +143,7 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
return object : EdziennikCallback {
override fun onCompleted() { callback.onCompleted() }
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) { callback.onRequiresUserAction(event) }
override fun onProgress(step: Float) { callback.onProgress(step) }
override fun onStartProgress(stringRes: Int) { callback.onStartProgress(stringRes) }
override fun onError(apiError: ApiError) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/MobidziennikFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/MobidziennikFeatures.kt
index 7396ac52..7b39e455 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/MobidziennikFeatures.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/MobidziennikFeatures.kt
@@ -18,6 +18,7 @@ const val ENDPOINT_MOBIDZIENNIK_WEB_ATTENDANCE = 2050
const val ENDPOINT_MOBIDZIENNIK_WEB_MANUALS = 2100
const val ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL = 2200
const val ENDPOINT_MOBIDZIENNIK_WEB_HOMEWORK = 2300 // not used as an endpoint
+const val ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE = 2400
const val ENDPOINT_MOBIDZIENNIK_API2_MAIN = 3000
val MobidziennikFeatures = listOf(
@@ -38,6 +39,12 @@ val MobidziennikFeatures = listOf(
+ /**
+ * Timetable - web scraping - does nothing if the API_MAIN timetable is enough.
+ */
+ Feature(LOGIN_TYPE_MOBIDZIENNIK, FEATURE_TIMETABLE, listOf(
+ ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_MOBIDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_MOBIDZIENNIK_WEB, LOGIN_METHOD_MOBIDZIENNIK_WEB)),
/**
* Agenda - "API" + web scraping.
*/
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/MobidziennikData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/MobidziennikData.kt
index 09e1e9fb..b82f6355 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/MobidziennikData.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/MobidziennikData.kt
@@ -84,6 +84,10 @@ class MobidziennikData(val data: DataMobidziennik, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
MobidziennikWebManuals(data, lastSync, onSuccess)
}*/
+ ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE-> {
+ data.startProgress(R.string.edziennik_progress_endpoint_timetable)
+ MobidziennikWebTimetable(data, lastSync, onSuccess)
+ }
else -> onSuccess(endpointId)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiHomework.kt
index 683a8820..a79eaded 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiHomework.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
-import android.text.Html
import androidx.core.util.contains
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.utils.html.BetterHtml
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -26,7 +26,7 @@ class MobidziennikApiHomework(val data: DataMobidziennik, rows: List) {
val id = cols[0].toLong()
val teacherId = cols[7].toLong()
val subjectId = cols[6].toLong()
- val topic = Html.fromHtml(cols[1])?.toString()?.trim() ?: ""
+ val topic = BetterHtml.fromHtml(context = null, cols[1]).toString().trim()
val eventDate = Date.fromYmd(cols[2])
val startTime = Time.fromYmdHm(cols[3])
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTeams.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTeams.kt
index 6440b04e..dbd1c03d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTeams.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTeams.kt
@@ -6,8 +6,8 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.db.entity.Team
-import pl.szczodrzynski.edziennik.getById
-import pl.szczodrzynski.edziennik.values
+import pl.szczodrzynski.edziennik.ext.getById
+import pl.szczodrzynski.edziennik.ext.values
class MobidziennikApiTeams(val data: DataMobidziennik, tableTeams: List?, tableRelations: List?) {
init {
@@ -35,7 +35,6 @@ class MobidziennikApiTeams(val data: DataMobidziennik, tableTeams: List?
}
if (tableRelations != null) {
val allTeams = data.teamList.values()
- data.teamList.clear()
for (row in tableRelations) {
if (row.isEmpty())
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTimetable.kt
index aa07b1c3..8e490832 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiTimetable.kt
@@ -11,9 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.keys
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.keys
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -24,7 +24,7 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List) {
val dataStart = Date.getToday()
val dataEnd = dataStart.clone().stepForward(0, 0, 7 + (6 - dataStart.weekDay))
- data.toRemove.add(DataRemoveModel.Timetable.between(dataStart.clone(), dataEnd))
+ data.toRemove.add(DataRemoveModel.Timetable.between(dataStart.clone(), dataEnd, isExtra = false))
val dataDays = mutableListOf()
while (dataStart <= dataEnd) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiUsers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiUsers.kt
index b95a55fe..943983d4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiUsers.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api/MobidziennikApiUsers.kt
@@ -6,7 +6,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.api
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
-import pl.szczodrzynski.edziennik.fixName
+import pl.szczodrzynski.edziennik.ext.fixName
class MobidziennikApiUsers(val data: DataMobidziennik, rows: List) {
init {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api2/MobidziennikApi2Main.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api2/MobidziennikApi2Main.kt
index 70d32b18..9c231849 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api2/MobidziennikApi2Main.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/api2/MobidziennikApi2Main.kt
@@ -14,8 +14,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBID
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginApi2
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getJsonObject
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils
class MobidziennikApi2Main(val data: DataMobidziennik,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAccountEmail.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAccountEmail.kt
index ef4c2847..9dc3878c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAccountEmail.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAccountEmail.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
-import pl.szczodrzynski.edziennik.get
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.get
class MobidziennikWebAccountEmail(override val data: DataMobidziennik,
override val lastSync: Long?,
@@ -26,7 +26,7 @@ class MobidziennikWebAccountEmail(override val data: DataMobidziennik,
val email = Regexes.MOBIDZIENNIK_ACCOUNT_EMAIL.find(text)?.let { it[1] }
data.loginEmail = email
- data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL, if (email == null) 3*DAY else 7*DAY)
+ data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL, if (email == null) 3* DAY else 7* DAY)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAttendance.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAttendance.kt
index f23478b6..9160e4d6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAttendance.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebAttendance.kt
@@ -20,9 +20,9 @@ import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEA
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -48,7 +48,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
//syncWeeks.clear()
//syncWeeks += Date.fromY_m_d("2019-12-19")
- syncWeeks.minBy { it.value }?.let {
+ syncWeeks.minByOrNull { it.value }?.let {
data.toRemove.add(DataRemoveModel.Attendance.from(it))
}
@@ -131,11 +131,11 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
// verify the lesson count is the same as dates & entries
if (count != lessonDates.count() || count != entries.count())
return@forEach
- ranges.forEach { range ->
+ ranges.onEach { range ->
val lessonDate = dateIterator.next()
val entry = entriesIterator.next()
if (range == null || entry.isBlank())
- return@forEach
+ return@onEach
val startTime = Time.fromH_m(range[1])
range[2].split(" / ").mapNotNull {
@@ -186,7 +186,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
if (entry.startsWith(symbol) && symbol.length > typeSymbol.length)
typeSymbol = symbol
}
- entry = entry.removePrefix(typeSymbol)
+ // entry = entry.removePrefix(typeSymbol)
var isCustom = false
val baseType = when (typeSymbol) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebCalendar.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebCalendar.kt
index 95c1f6df..b6a10335 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebCalendar.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebCalendar.kt
@@ -12,10 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.Mobidzien
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.crc16
import pl.szczodrzynski.edziennik.utils.models.Date
-import java.util.*
class MobidziennikWebCalendar(override val data: DataMobidziennik,
override val lastSync: Long?,
@@ -30,7 +29,7 @@ class MobidziennikWebCalendar(override val data: DataMobidziennik,
MobidziennikLuckyNumberExtractor(data, text)
Regexes.MOBIDZIENNIK_CLASS_CALENDAR.find(text)?.let {
- val events = JsonParser().parse(it.groupValues[1]).asJsonArray
+ val events = JsonParser.parseString(it.groupValues[1]).asJsonArray
for (eventEl in events) {
val event = eventEl.asJsonObject
@@ -50,7 +49,7 @@ class MobidziennikWebCalendar(override val data: DataMobidziennik,
val dateString = event.getString("start") ?: continue
val eventDate = Date.fromY_m_d(dateString)
- val eventType = when (event.getString("color")?.toLowerCase(Locale.getDefault())) {
+ val eventType = when (event.getString("color")?.lowercase()) {
"#c54449" -> Event.TYPE_SHORT_QUIZ
"#ab0001" -> Event.TYPE_EXAM
"#008928" -> Event.TYPE_CLASS_EVENT
@@ -81,6 +80,7 @@ class MobidziennikWebCalendar(override val data: DataMobidziennik,
subjectId = -1,
teamId = data.teamClass?.id ?: -1
)
+ eventObject.isDownloaded = false
data.eventList.add(eventObject)
data.metadataList.add(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetAttachment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetAttachment.kt
index 52561a81..b8c6644f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetAttachment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetAttachment.kt
@@ -28,7 +28,7 @@ class MobidziennikWebGetAttachment(override val data: DataMobidziennik,
val targetFile = File(Utils.getStorageDir(), attachmentName)
val typeUrl = when (owner) {
- is Message -> if (owner.type == Message.TYPE_SENT)
+ is Message -> if (owner.isSent)
"dziennik/wiadwyslana/?id="
else
"dziennik/wiadodebrana/?id="
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetEvent.kt
new file mode 100644
index 00000000..69a2dce0
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetEvent.kt
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-1.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
+
+import org.greenrobot.eventbus.EventBus
+import pl.szczodrzynski.edziennik.data.api.POST
+import pl.szczodrzynski.edziennik.data.api.Regexes
+import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
+import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
+import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
+import pl.szczodrzynski.edziennik.data.db.full.EventFull
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.utils.models.Date
+
+class MobidziennikWebGetEvent(
+ override val data: DataMobidziennik,
+ val event: EventFull,
+ val onSuccess: () -> Unit
+) : MobidziennikWeb(data, null) {
+ companion object {
+ private const val TAG = "MobidziennikWebGetEvent"
+ }
+
+ init {
+ val params = listOf(
+ "typ" to "kalendarz",
+ "uczen" to data.studentId,
+ "id" to event.id,
+ )
+
+ webGet(TAG, "/dziennik/ajaxkalendarzklasowy", method = POST, parameters = params) { text ->
+ Regexes.MOBIDZIENNIK_EVENT_CONTENT.find(text)?.let {
+ val topic = it[1]
+ val teacherName = it[2]
+ val teacher = data.getTeacherByLastFirst(teacherName)
+ val addedDate = Date.fromY_m_d(it[3])
+ val body = it[4]
+ .replace("\n", "")
+ .replace(Regexes.HTML_BR, "\n")
+
+ event.topic = topic
+ event.homeworkBody = body
+ event.isDownloaded = true
+ event.teacherId = teacher.id
+ event.addedDate = addedDate.inMillis
+ }
+
+ data.eventList.add(event)
+ data.eventListReplace = true
+
+ EventBus.getDefault().postSticky(EventGetEvent(event))
+ onSuccess()
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetHomework.kt
index b0699b4b..9dbdd439 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetHomework.kt
@@ -10,43 +10,60 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidzienn
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
import pl.szczodrzynski.edziennik.data.db.full.EventFull
-import pl.szczodrzynski.edziennik.get
+import pl.szczodrzynski.edziennik.ext.get
import pl.szczodrzynski.edziennik.utils.models.Date
+import pl.szczodrzynski.edziennik.utils.models.Time
class MobidziennikWebGetHomework(override val data: DataMobidziennik,
val event: EventFull,
val onSuccess: () -> Unit
) : MobidziennikWeb(data, null) {
companion object {
- private const val TAG = "MobidziennikWebHomework"
+ private const val TAG = "MobidziennikWebGetHomework"
}
init {
- val endpoint = if (event.date >= Date.getToday())
- "zadaniadomowe"
- else
- "zadaniadomowearchiwalne"
-
- webGet(TAG, "/mobile/$endpoint") { text ->
+ webGet(TAG, "/dziennik/wyslijzadanie/?id_zadania=${event.id}&uczen=${data.studentId}") { text ->
MobidziennikLuckyNumberExtractor(data, text)
- Regexes.MOBIDZIENNIK_HOMEWORK_ROW.findAll(text).forEach { homeworkMatch ->
- val tableRow = homeworkMatch[1].ifBlank { return@forEach }
-
- val id = Regexes.MOBIDZIENNIK_HOMEWORK_ID.find(tableRow)?.get(1)?.toLongOrNull() ?: return@forEach
- if (event.id != id)
+ event.clearAttachments()
+ Regexes.MOBIDZIENNIK_WEB_ATTACHMENT.findAll(text).forEach { match ->
+ if (match[1].isNotEmpty())
return@forEach
-
- event.attachmentIds = mutableListOf()
- event.attachmentNames = mutableListOf()
- Regexes.MOBIDZIENNIK_HOMEWORK_ATTACHMENT.findAll(tableRow).forEach {
- event.attachmentIds?.add(it[2].toLongOrNull() ?: return@forEach)
- event.attachmentNames?.add(it[3])
- }
-
- event.homeworkBody = ""
+ val attachmentId = match[2].toLong()
+ val attachmentName = match[3]
+ event.addAttachment(attachmentId, attachmentName)
}
+ Regexes.MOBIDZIENNIK_WEB_HOMEWORK_ADDED_DATE.find(text)?.let {
+ // (Kowalski Jan), (wtorek), (2) (stycznia) (2019), godzina (12:34:56)
+ val month = when (it[4]) {
+ "stycznia" -> 1
+ "lutego" -> 2
+ "marca" -> 3
+ "kwietnia" -> 4
+ "maja" -> 5
+ "czerwca" -> 6
+ "lipca" -> 7
+ "sierpnia" -> 8
+ "września" -> 9
+ "października" -> 10
+ "listopada" -> 11
+ "grudnia" -> 12
+ else -> 1
+ }
+ val addedDate = Date(
+ it[5].toInt(),
+ month,
+ it[3].toInt()
+ )
+ val time = Time.fromH_m_s(it[6])
+ event.addedDate = addedDate.combineWith(time)
+ }
+
+ event.homeworkBody = ""
+ event.isDownloaded = true
+
data.eventList.add(event)
data.eventListReplace = true
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetMessage.kt
index 7282cc2d..3e196ec0 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetMessage.kt
@@ -10,14 +10,12 @@ import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
-import pl.szczodrzynski.edziennik.data.db.entity.Message
-import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.Utils.monthFromName
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -31,7 +29,7 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
}
init {
- val typeUrl = if (message.type == Message.TYPE_SENT)
+ val typeUrl = if (message.isSent)
"wiadwyslana"
else
"wiadodebrana"
@@ -42,13 +40,14 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
val doc = Jsoup.parse(text)
- val content = doc.select("#content").first()
+ val content = doc.select("#content").first() ?: return@webGet
val body = content.select(".wiadomosc_tresc").first()
+ val bodyHtml = body?.html() ?: ""
- if (message.type == TYPE_RECEIVED) {
+ if (message.isReceived) {
var readDate = System.currentTimeMillis()
- Regexes.MOBIDZIENNIK_MESSAGE_READ_DATE.find(body.html())?.let {
+ Regexes.MOBIDZIENNIK_MESSAGE_READ_DATE.find(bodyHtml)?.let {
val date = Date(
it[3].toIntOrNull() ?: 2019,
monthFromName(it[2]),
@@ -73,35 +72,35 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
} else {
message.senderId = null
- content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
- val senderEl = recipientEl.select("td:eq(1)")?.first() ?: return@forEach
+ content.select("table.spis tr:has(td)").forEach { recipientEl ->
+ val senderEl = recipientEl.select("td:eq(1)").first() ?: return@forEach
val senderName = senderEl.text().fixName()
val teacher = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }
val receiverId = teacher?.id ?: -1
var readDate = 0L
- val isReadEl = recipientEl.select("td:eq(4)")?.first() ?: return@forEach
+ val isReadEl = recipientEl.select("td:eq(4)").first() ?: return@forEach
if (isReadEl.html().contains("tak")) {
- val readDateEl = recipientEl.select("td:eq(5) small")?.first() ?: return@forEach
+ val readDateEl = recipientEl.select("td:eq(5) small").first() ?: return@forEach
Regexes.MOBIDZIENNIK_MESSAGE_SENT_READ_DATE.find(readDateEl.ownText())?.let {
val date = Date(
- it[3].toIntOrNull() ?: 2019,
- monthFromName(it[2]),
- it[1].toIntOrNull() ?: 1
+ it[3].toIntOrNull() ?: 2019,
+ monthFromName(it[2]),
+ it[1].toIntOrNull() ?: 1
)
val time = Time.fromH_m_s(
- it[4] // TODO blank string safety
+ it[4] // TODO blank string safety
)
readDate = date.combineWith(time)
}
}
val recipient = MessageRecipientFull(
- profileId = profileId,
- id = receiverId,
- messageId = message.id,
- readDate = readDate
+ profileId = profileId,
+ id = receiverId,
+ messageId = message.id,
+ readDate = readDate
)
recipient.fullName = teacher?.fullName ?: "?"
@@ -111,25 +110,23 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
}
// this line removes the sender and read date details
- body.select("div").remove()
+ body?.select("div")?.remove()
// this needs to be at the end
message.apply {
- this.body = body.html()
+ this.body = body?.html()
clearAttachments()
- content.select("ul li").map { it.select("a").first() }.forEach {
- val attachmentName = it.ownText()
- Regexes.MOBIDZIENNIK_MESSAGE_ATTACHMENT.find(it.outerHtml())?.let { match ->
- val attachmentId = match[1].toLong()
- var size = match[2].toFloatOrNull() ?: -1f
- when (match[3]) {
- "K" -> size *= 1024f
- "M" -> size *= 1024f * 1024f
- "G" -> size *= 1024f * 1024f * 1024f
- }
- message.addAttachment(attachmentId, attachmentName, size.toLong())
+ Regexes.MOBIDZIENNIK_WEB_ATTACHMENT.findAll(text).forEach { match ->
+ val attachmentId = match[2].toLong()
+ val attachmentName = match[3]
+ var size = match[4].toFloatOrNull() ?: -1f
+ when (match[5]) {
+ "K" -> size *= 1024f
+ "M" -> size *= 1024f * 1024f
+ "G" -> size *= 1024f * 1024f * 1024f
}
+ message.addAttachment(attachmentId, attachmentName, size.toLong())
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetRecipientList.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetRecipientList.kt
index 0ed1e4a6..b6f2afa7 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetRecipientList.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGetRecipientList.kt
@@ -9,12 +9,12 @@ import androidx.room.OnConflictStrategy
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.events.RecipientListGetEvent
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.ext.*
class MobidziennikWebGetRecipientList(override val data: DataMobidziennik,
val onSuccess: () -> Unit
@@ -26,7 +26,7 @@ class MobidziennikWebGetRecipientList(override val data: DataMobidziennik,
init {
webGet(TAG, "/mobile/dodajwiadomosc") { text ->
Regexes.MOBIDZIENNIK_MESSAGE_RECIPIENTS_JSON.find(text)?.let { match ->
- val recipientLists = JsonParser().parse(match[1]).asJsonArray
+ val recipientLists = JsonParser.parseString(match[1]).asJsonArray
recipientLists?.asJsonObjectList()?.forEach { list ->
val listType = list.getString("typ")?.toIntOrNull() ?: -1
val listName = list.getString("nazwa") ?: ""
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGrades.kt
index 43b67d23..285441b6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebGrades.kt
@@ -14,9 +14,9 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.fixWhiteSpaces
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixWhiteSpaces
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebHomework.kt
index 944b21ea..f9638ac1 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebHomework.kt
@@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBID
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
import pl.szczodrzynski.edziennik.data.db.full.EventFull
-import pl.szczodrzynski.edziennik.get
+import pl.szczodrzynski.edziennik.ext.get
class MobidziennikWebHomework(override val data: DataMobidziennik,
override val lastSync: Long?,
@@ -33,14 +33,14 @@ class MobidziennikWebHomework(override val data: DataMobidziennik,
webGet(TAG, "/mobile/$endpoint") { text ->
MobidziennikLuckyNumberExtractor(data, text)
- Regexes.MOBIDZIENNIK_HOMEWORK_ROW.findAll(text).forEach { homeworkMatch ->
+ Regexes.MOBIDZIENNIK_MOBILE_HOMEWORK_ROW.findAll(text).forEach { homeworkMatch ->
val tableRow = homeworkMatch[1].ifBlank { return@forEach }
/*val items = Regexes.MOBIDZIENNIK_HOMEWORK_ITEM.findAll(tableRow).map { match ->
match[1] to match[2].fixWhiteSpaces()
}.toList()*/
- val id = Regexes.MOBIDZIENNIK_HOMEWORK_ID.find(tableRow)?.get(1)?.toLongOrNull() ?: return@forEach
+ val id = Regexes.MOBIDZIENNIK_MOBILE_HOMEWORK_ID.find(tableRow)?.get(1)?.toLongOrNull() ?: return@forEach
if (event.id != id)
return@forEach
@@ -48,12 +48,13 @@ class MobidziennikWebHomework(override val data: DataMobidziennik,
event.attachmentIds = mutableListOf()
event.attachmentNames = mutableListOf()
- Regexes.MOBIDZIENNIK_HOMEWORK_ATTACHMENT.findAll(tableRow).forEach {
- event.attachmentIds?.add(it[1].toLongOrNull() ?: return@forEach)
+ Regexes.MOBIDZIENNIK_MOBILE_HOMEWORK_ATTACHMENT.findAll(tableRow).onEach {
+ event.attachmentIds?.add(it[1].toLongOrNull() ?: return@onEach)
event.attachmentNames?.add(it[2])
}
event.homeworkBody = ""
+ event.isDownloaded = true
}
//data.eventList.add(eventObject)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesAll.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesAll.kt
index 4e8f900a..aebff41e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesAll.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesAll.kt
@@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
@@ -14,9 +13,11 @@ import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
+import java.net.URLEncoder
class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
override val lastSync: Long?,
@@ -27,30 +28,31 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
}
init {
- webGet(TAG, "/dziennik/wyszukiwarkawiadomosci?q=+") { text ->
+ val query = URLEncoder.encode(data.profile?.studentNameLong ?: "a", "UTF-8")
+ webGet(TAG, "/dziennik/wyszukiwarkawiadomosci?q=$query") { text ->
MobidziennikLuckyNumberExtractor(data, text)
val doc = Jsoup.parse(text)
- val listElement = doc.getElementsByClass("spis")?.first()
+ val listElement = doc.getElementsByClass("spis").first()
if (listElement == null) {
- data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL, 7*DAY)
+ data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL, 7* DAY)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL)
return@webGet
}
val list = listElement.getElementsByClass("podswietl")
- list?.forEach { item ->
+ list.forEach { item ->
val id = item.attr("rel").replace("[^\\d]".toRegex(), "").toLongOrNull() ?: return@forEach
val subjectEl = item.select("td:eq(0) div").first()
- val subject = subjectEl.text()
+ val subject = subjectEl?.text() ?: ""
val addedDateEl = item.select("td:eq(1)").first()
- val addedDate = Date.fromIsoHm(addedDateEl.text())
+ val addedDate = Date.fromIsoHm(addedDateEl?.text())
val typeEl = item.select("td:eq(2) img").first()
var type = TYPE_RECEIVED
- if (typeEl.outerHtml().contains("mail_send.png"))
+ if (typeEl?.outerHtml()?.contains("mail_send.png") == true)
type = TYPE_SENT
val senderEl = item.select("td:eq(3) div").first()
@@ -58,13 +60,13 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
if (type == TYPE_RECEIVED) {
// search sender teacher
- val senderName = senderEl.text().fixName()
+ val senderName = senderEl?.text().fixName()
senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
data.messageRecipientList.add(MessageRecipient(profileId, -1, id))
} else {
// TYPE_SENT, so multiple recipients possible
- val recipientNames = senderEl.text().split(", ")
- for (recipientName in recipientNames) {
+ val recipientNames = senderEl?.text()?.split(", ")
+ recipientNames?.forEach { recipientName ->
val name = recipientName.fixName()
val recipientId = data.teacherList.singleOrNull { it.fullNameLastFirst == name }?.id ?: -1
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, recipientId, id))
@@ -72,13 +74,13 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
}
val message = Message(
- profileId = profileId,
- id = id,
- type = type,
- subject = subject,
- body = null,
- senderId = senderId,
- addedDate = addedDate
+ profileId = profileId,
+ id = id,
+ type = type,
+ subject = subject,
+ body = null,
+ senderId = senderId,
+ addedDate = addedDate
)
data.messageList.add(message)
@@ -87,7 +89,7 @@ class MobidziennikWebMessagesAll(override val data: DataMobidziennik,
// sync every 7 days as we probably don't expect more than
// 30 received messages during a week, without any normal sync
- data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL, 7*DAY)
+ data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL, 7* DAY)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_ALL)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesInbox.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesInbox.kt
index be762228..b3819784 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesInbox.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesInbox.kt
@@ -12,8 +12,8 @@ import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
@@ -36,26 +36,35 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
val doc = Jsoup.parse(text)
- val list = doc.getElementsByClass("spis")?.first()?.getElementsByClass("podswietl")
+ val today = Date.getToday()
+ var currentYear = today.year
+ var currentMonth = today.month
+
+ val list = doc.getElementsByClass("spis").first()?.getElementsByClass("podswietl")
list?.forEach { item ->
val id = item.attr("rel").toLongOrNull() ?: return@forEach
val subjectEl = item.select("td:eq(0)").first()
var hasAttachments = false
- if (subjectEl.getElementsByTag("a").size != 0) {
+ if (subjectEl?.getElementsByTag("a")?.size ?: 0 > 0) {
hasAttachments = true
}
- val subject = subjectEl.ownText()
+ val subject = subjectEl?.ownText() ?: ""
- val addedDateEl = item.select("td:eq(1) small").first()
- val addedDate = Date.fromIsoHm(addedDateEl.text())
+ val addedDateEl = item.select("td:eq(4)").first()
+ val (date, time) = data.parseDateTime(addedDateEl?.text()?.trim() ?: "")
+ if (date.month > currentMonth) {
+ currentYear--
+ }
+ currentMonth = date.month
+ date.year = currentYear
- val senderEl = item.select("td:eq(2)").first()
- val senderName = senderEl.ownText().fixName()
+ val senderEl = item.select("td:eq(3)").first()
+ val senderName = senderEl?.ownText().fixName()
val senderId = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }?.id
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, -1, id))
- val isRead = item.select("td:eq(3) span").first().hasClass("wiadomosc_przeczytana")
+ val isRead = item.select("td:eq(5) span").first()?.hasClass("wiadomosc_przeczytana") == true
val message = Message(
profileId = profileId,
@@ -64,7 +73,7 @@ class MobidziennikWebMessagesInbox(override val data: DataMobidziennik,
subject = subject,
body = null,
senderId = senderId,
- addedDate = addedDate
+ addedDate = date.combineWith(time)
)
if (hasAttachments)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesSent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesSent.kt
index 543df329..7f249cf6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesSent.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebMessagesSent.kt
@@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
import org.jsoup.Jsoup
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
import pl.szczodrzynski.edziennik.data.api.Regexes
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
@@ -15,9 +14,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.singleOrNull
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.singleOrNull
import pl.szczodrzynski.edziennik.utils.models.Date
class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
@@ -40,37 +40,48 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
val doc = Jsoup.parse(text)
- val list = doc.getElementsByClass("spis")?.first()?.getElementsByClass("podswietl")
+ val today = Date.getToday()
+ var currentYear = today.year
+ var currentMonth = today.month
+
+ val list = doc.getElementsByClass("spis").first()?.getElementsByClass("podswietl")
list?.forEach { item ->
val id = item.attr("rel").toLongOrNull() ?: return@forEach
val subjectEl = item.select("td:eq(0)").first()
+ val subject = subjectEl?.ownText() ?: ""
+
+ val attachmentsEl = item.select("td:eq(1)").first()
var hasAttachments = false
- if (subjectEl.getElementsByTag("a").size != 0) {
+ if (attachmentsEl?.getElementsByTag("a")?.size ?: 0 > 0) {
hasAttachments = true
}
- val subject = subjectEl.ownText()
- val readByString = item.select("td:eq(2)").first().text()
+ val readByString = item.select("td:eq(4)").first()?.text() ?: ""
val (readBy, sentTo) = Regexes.MOBIDZIENNIK_MESSAGE_SENT_READ_BY.find(readByString).let {
(it?.get(1)?.toIntOrNull() ?: 0) to (it?.get(2)?.toIntOrNull() ?: 0)
}
- val recipientEl = item.select("td:eq(1) a span").first()
- val recipientNames = recipientEl.ownText().split(", ")
+ val recipientEl = item.select("td:eq(2) a span").first()
+ val recipientNames = recipientEl?.ownText()?.split(", ")
val readState = when (readBy) {
0 -> 0
sentTo -> 1
else -> -1
}.toLong()
- for (recipientName in recipientNames) {
+ recipientNames?.forEach { recipientName ->
val name = recipientName.fixName()
val recipientId = data.teacherList.singleOrNull { it.fullNameLastFirst == name }?.id ?: -1
data.messageRecipientIgnoreList.add(MessageRecipient(profileId, recipientId, -1, readState, id))
}
- val addedDateEl = item.select("td:eq(3) small").first()
- val addedDate = Date.fromIsoHm(addedDateEl.text())
+ val addedDateEl = item.select("td:eq(3)").first()
+ val (date, time) = data.parseDateTime(addedDateEl?.text()?.trim() ?: "")
+ if (date.month > currentMonth) {
+ currentYear--
+ }
+ currentMonth = date.month
+ date.year = currentYear
val message = Message(
profileId = profileId,
@@ -79,7 +90,7 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
subject = subject,
body = null,
senderId = null,
- addedDate = addedDate
+ addedDate = date.combineWith(time)
)
if (hasAttachments)
@@ -96,7 +107,7 @@ class MobidziennikWebMessagesSent(override val data: DataMobidziennik,
))
}
- data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_SENT, 1*DAY, DRAWER_ITEM_MESSAGES)
+ data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_SENT, 1* DAY, DRAWER_ITEM_MESSAGES)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_MESSAGES_SENT)
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebSendMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebSendMessage.kt
index 89178b8b..b5a6c5ee 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebSendMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebSendMessage.kt
@@ -9,7 +9,6 @@ import pl.szczodrzynski.edziennik.data.api.POST
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
-import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
@@ -43,7 +42,7 @@ class MobidziennikWebSendMessage(override val data: DataMobidziennik,
// TODO create MobidziennikWebMessagesSent and replace this
MobidziennikWebMessagesAll(data, null) {
- val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
+ val message = data.messageList.firstOrNull { it.isSent && it.subject == subject }
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebTimetable.kt
new file mode 100644
index 00000000..dd0ff03f
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/data/web/MobidziennikWebTimetable.kt
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-9-8.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.web
+
+import android.annotation.SuppressLint
+import org.jsoup.Jsoup
+import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.data.api.Regexes
+import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
+import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE
+import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
+import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel.Timetable.Companion.between
+import pl.szczodrzynski.edziennik.data.db.entity.Lesson
+import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.MS
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.utils.models.Date
+import pl.szczodrzynski.edziennik.utils.models.Time
+import pl.szczodrzynski.edziennik.utils.models.Week
+import kotlin.collections.set
+
+class MobidziennikWebTimetable(
+ override val data: DataMobidziennik,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit
+) : MobidziennikWeb(data, lastSync) {
+ companion object {
+ private const val TAG = "MobidziennikWebTimetable"
+ }
+
+ private val rangesH = mutableMapOf, Date>()
+ private val hoursV = mutableMapOf>()
+ private var startDate: Date
+
+ private fun parseCss(css: String): Map {
+ return css.split(";").mapNotNull {
+ val spl = it.split(":")
+ if (spl.size != 2)
+ return@mapNotNull null
+ return@mapNotNull spl[0].trim() to spl[1].trim()
+ }.toMap()
+ }
+
+ private fun getRangeH(h: Float): Date? {
+ return rangesH.entries.firstOrNull {
+ h in it.key
+ }?.value
+ }
+
+ private fun stringToDate(date: String): Date? {
+ val items = date.split(" ")
+ val day = items.getOrNull(0)?.toIntOrNull() ?: return null
+ val year = items.getOrNull(2)?.toIntOrNull() ?: return null
+ val month = when (items.getOrNull(1)) {
+ "stycznia" -> 1
+ "lutego" -> 2
+ "marca" -> 3
+ "kwietnia" -> 4
+ "maja" -> 5
+ "czerwca" -> 6
+ "lipca" -> 7
+ "sierpnia" -> 8
+ "września" -> 9
+ "października" -> 10
+ "listopada" -> 11
+ "grudnia" -> 12
+ else -> return null
+ }
+ return Date(year, month, day)
+ }
+
+ init {
+ val currentWeekStart = Week.getWeekStart()
+ val nextWeekEnd = Week.getWeekEnd().stepForward(0, 0, 7)
+ if (Date.getToday().weekDay > 4) {
+ currentWeekStart.stepForward(0, 0, 7)
+ }
+ startDate = data.arguments?.getString("weekStart")?.let {
+ Date.fromY_m_d(it)
+ } ?: currentWeekStart
+
+ val syncFutureDate = startDate > nextWeekEnd
+ val syncPastDate = startDate < currentWeekStart
+ val syncExtraLessons = System.currentTimeMillis() - (lastSync ?: 0) > 2 * DAY * MS
+ // sync not needed - everything present in the "API"
+ if (!syncFutureDate && !syncPastDate && !syncExtraLessons) {
+ onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE)
+ }
+ else {
+ val types = when {
+ syncFutureDate || syncPastDate -> mutableListOf("podstawowy", "pozalekcyjny")
+ syncExtraLessons -> mutableListOf("pozalekcyjny")
+ else -> mutableListOf()
+ }
+
+ val syncingExtra = types.contains("pozalekcyjny")
+
+ syncTypes(types, startDate) {
+ if (syncingExtra) {
+ val endDate = startDate.clone().stepForward(0, 0, 7)
+ data.toRemove.add(between(startDate, endDate, isExtra = true))
+ }
+
+ // set as synced now only when not syncing future/past date
+ // (to avoid waiting 2 days for normal sync after future/past sync)
+ if (!syncFutureDate && !syncPastDate)
+ data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
+ onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_TIMETABLE)
+ }
+ }
+ }
+
+ private fun syncTypes(types: MutableList, startDate: Date, onSuccess: () -> Unit) {
+ if (types.isEmpty()) {
+ onSuccess()
+ return
+ }
+ val type = types.removeAt(0)
+ webGet(TAG, "/dziennik/planlekcji?typ=$type&tydzien=${startDate.stringY_m_d}") { html ->
+ MobidziennikLuckyNumberExtractor(data, html)
+ readRangesH(html)
+ readRangesV(html)
+ readLessons(html, isExtra = type == "pozalekcyjny")
+ syncTypes(types, startDate, onSuccess)
+ }
+ }
+
+ private fun readRangesH(html: String) {
+ val htmlH = Regexes.MOBIDZIENNIK_TIMETABLE_TOP.find(html) ?: return
+ val docH = Jsoup.parse(htmlH.value)
+
+ var posH = 0f
+ for (el in docH.select("div > div")) {
+ val css = parseCss(el.attr("style"))
+ val width = css["width"]
+ ?.trimEnd('%')
+ ?.toFloatOrNull()
+ ?: continue
+ val value = stringToDate(el.attr("title"))
+ ?: continue
+
+ val range = posH.rangeTo(posH + width)
+ posH += width
+
+ rangesH[range] = value
+ }
+ }
+
+ private fun readRangesV(html: String) {
+ val htmlV = Regexes.MOBIDZIENNIK_TIMETABLE_LEFT.find(html) ?: return
+ val docV = Jsoup.parse(htmlV.value)
+
+ for (el in docV.select("div > div")) {
+ val css = parseCss(el.attr("style"))
+ val top = css["top"]
+ ?.trimEnd('%')
+ ?.toFloatOrNull()
+ ?: continue
+ val values = el.text().split(" ")
+
+ val time = values.getOrNull(0)?.let {
+ Time.fromH_m(it)
+ } ?: continue
+ val num = values.getOrNull(1)?.toIntOrNull()
+
+ hoursV[(top * 100).toInt()] = time to num
+ }
+ }
+
+ private val whitespaceRegex = "\\s+".toRegex()
+ private val classroomRegex = "\\((.*)\\)".toRegex()
+ private fun cleanup(str: String): List {
+ return str
+ .replace(whitespaceRegex, " ")
+ .replace("\n", "")
+ .replace("<small>", "$")
+ .replace("</small>", "$")
+ .replace("<br />", "\n")
+ .replace("<br/>", "\n")
+ .replace("<br>", "\n")
+ .replace("
", "\n")
+ .replace("
", "\n")
+ .replace("
", "\n")
+ .replace("", "%")
+ .replace("", "%")
+ .replace("", "")
+ .replace("", "")
+ .split("\n")
+ .map { it.trim() }
+ }
+
+ @SuppressLint("LongLogTag", "LogNotTimber")
+ private fun readLessons(html: String, isExtra: Boolean) {
+ val matches = Regexes.MOBIDZIENNIK_TIMETABLE_CELL.findAll(html)
+
+ val noLessonDays = mutableListOf()
+ for (i in 0..6) {
+ noLessonDays.add(startDate.clone().stepForward(0, 0, i))
+ }
+
+ for (match in matches) {
+ val css = parseCss("${match[1]};${match[2]}")
+ val left = css["left"]?.trimEnd('%')?.toFloatOrNull() ?: continue
+ val top = css["top"]?.trimEnd('%')?.toFloatOrNull() ?: continue
+ val width = css["width"]?.trimEnd('%')?.toFloatOrNull() ?: continue
+ val height = css["height"]?.trimEnd('%')?.toFloatOrNull() ?: continue
+
+ val posH = left + width / 2f
+ val topInt = (top * 100).toInt()
+ val bottomInt = ((top + height) * 100).toInt()
+
+ val lessonDate = getRangeH(posH) ?: continue
+ val (startTime, lessonNumber) = hoursV[topInt] ?: continue
+ val endTime = hoursV[bottomInt]?.first ?: continue
+
+ noLessonDays.remove(lessonDate)
+
+ var typeName: String? = null
+ var subjectName: String? = null
+ var teacherName: String? = null
+ var classroomName: String? = null
+ var teamName: String? = null
+ val items = (cleanup(match[3]) + cleanup(match[4])).toMutableList()
+
+ // comparing items size before and after the iteration
+ var length = 0
+ while (items.isNotEmpty() && length != items.size) {
+ length = items.size
+ var i = 0
+ while (i < items.size) {
+ // just to remain safe - I have no idea how all of this works.
+ if (i < 0)
+ break
+ val item = items[i]
+ when {
+ // remove empty items
+ item.isEmpty() -> {
+ items.remove(item)
+ i--
+ }
+ // remove HH:MM items - it's calculated from the block position
+ item.contains(":") && item.contains(" - ") -> {
+ items.remove(item)
+ i--
+ }
+
+ item.startsWith("%") -> {
+ // the one wrapped in % is the short subject name
+ items.remove(item)
+ // remove the first remaining item
+ subjectName = items.removeAt(0)
+ // decrement the index counter
+ i -= 2
+ }
+
+ item.startsWith("$") -> {
+ typeName = item.trim('$')
+ items.remove(item)
+ i--
+ }
+ typeName != null && (item.contains(typeName) || item.contains("")) -> {
+ items.remove(item)
+ i--
+ }
+
+ item.contains("(") && item.contains(")") -> {
+ classroomName = classroomRegex.find(item)?.get(1)
+ items[i] = item.replace("($classroomName)", "").trim()
+ }
+ classroomName != null && item.contains(classroomName) -> {
+ items[i] = item.replace("($classroomName)", "").trim()
+ }
+
+ item.contains("class=\"wyjatek tooltip\"") -> {
+ items.remove(item)
+ i--
+ }
+ }
+ // finally advance to the next item
+ i++
+ }
+ }
+
+ if (items.size == 2 && items[0].contains(" - ")) {
+ val parts = items[0].split(" - ")
+ teamName = parts[0]
+ teacherName = parts[1]
+ }
+ else if (items.size == 2 && typeName?.contains("odwołana") == true) {
+ teamName = items[0]
+ }
+ else if (items.size == 4) {
+ teamName = items[0]
+ teacherName = items[1]
+ }
+
+ val type = when (typeName) {
+ "zastępstwo" -> Lesson.TYPE_CHANGE
+ "lekcja odwołana", "odwołana" -> Lesson.TYPE_CANCELLED
+ else -> Lesson.TYPE_NORMAL
+ }
+ val subject = subjectName?.let { data.getSubject(null, it) }
+ val teacher = teacherName?.let { data.getTeacherByLastFirst(it) }
+ val team = teamName?.let { data.getTeam(
+ id = null,
+ name = it,
+ schoolCode = data.loginServerName ?: return@let null,
+ isTeamClass = false
+ ) }
+
+ Lesson(data.profileId, -1).also {
+ it.type = type
+ if (type == Lesson.TYPE_CANCELLED) {
+ it.oldDate = lessonDate
+ it.oldLessonNumber = lessonNumber
+ it.oldStartTime = startTime
+ it.oldEndTime = endTime
+ it.oldSubjectId = subject?.id ?: -1
+ it.oldTeamId = team?.id ?: -1
+ }
+ else {
+ it.date = lessonDate
+ it.lessonNumber = lessonNumber
+ it.startTime = startTime
+ it.endTime = endTime
+ it.subjectId = subject?.id ?: -1
+ it.teacherId = teacher?.id ?: -1
+ it.teamId = team?.id ?: -1
+ it.classroom = classroomName
+ }
+
+ it.id = it.buildId()
+ it.isExtra = isExtra
+
+ val seen = profile?.empty == false || lessonDate < Date.getToday()
+
+ if (it.type != Lesson.TYPE_NORMAL) {
+ data.metadataList.add(
+ Metadata(
+ data.profileId,
+ Metadata.TYPE_LESSON_CHANGE,
+ it.id,
+ seen,
+ seen
+ )
+ )
+ }
+ data.lessonList += it
+ }
+ }
+
+ for (date in noLessonDays) {
+ data.lessonList += Lesson(data.profileId, date.value.toLong()).also {
+ it.type = Lesson.TYPE_NO_LESSONS
+ it.date = date
+ }
+ }
+ }
+}
+
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt
index 11b668f9..91390c5c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/firstlogin/MobidziennikFirstLogin.kt
@@ -7,8 +7,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.Mobidzien
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginWeb
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.set
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.set
import pl.szczodrzynski.edziennik.utils.models.Date
class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginApi2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginApi2.kt
index db750981..9258886b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginApi2.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginApi2.kt
@@ -9,10 +9,14 @@ import com.google.gson.JsonObject
import im.wangchao.mhttp.Request
import im.wangchao.mhttp.Response
import im.wangchao.mhttp.callback.JsonCallbackHandler
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.JsonObject
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.Utils
class MobidziennikLoginApi2(val data: DataMobidziennik, val onSuccess: () -> Unit) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginWeb.kt
index 78526b0c..ce801a73 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginWeb.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/mobidziennik/login/MobidziennikLoginWeb.kt
@@ -11,8 +11,8 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getUnixDate
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.getUnixDate
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.Utils.d
class MobidziennikLoginWeb(val data: DataMobidziennik, val onSuccess: () -> Unit) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/DataPodlasie.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/DataPodlasie.kt
index d117c139..0a5cce84 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/DataPodlasie.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/DataPodlasie.kt
@@ -4,11 +4,13 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_PODLASIE_API
import pl.szczodrzynski.edziennik.data.api.models.Data
-import pl.szczodrzynski.edziennik.data.db.entity.*
-import kotlin.text.replace
+import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
+import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.crc32
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
class DataPodlasie(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
@@ -81,39 +83,4 @@ class DataPodlasie(app: App, profile: Profile?, loginStore: LoginStore) : Data(a
val loginShort: String?
get() = studentLogin?.split('@')?.get(0)
-
- fun getSubject(name: String): Subject {
- val id = name.crc32()
- return subjectList.singleOrNull { it.id == id } ?: run {
- val subject = Subject(profileId, id, name, name)
- subjectList.put(id, subject)
- subject
- }
- }
-
- fun getTeacher(firstName: String, lastName: String): Teacher {
- val name = "$firstName $lastName".fixName()
- return teacherList.singleOrNull { it.fullName == name } ?: run {
- val id = name.crc32()
- val teacher = Teacher(profileId, id, firstName, lastName)
- teacherList.put(id, teacher)
- teacher
- }
- }
-
- fun getTeam(name: String? = null): Team {
- if (name == "cała klasa" || name == null) return teamClass ?: run {
- val id = className!!.crc32()
- val teamCode = "$schoolShortName:$className"
- val team = Team(profileId, id, className, Team.TYPE_CLASS, teamCode, -1)
- teamList.put(id, team)
- return team
- } else {
- val id = name.crc32()
- val teamCode = "$schoolShortName:$name"
- val team = Team(profileId, id, name, Team.TYPE_VIRTUAL, teamCode, -1)
- teamList.put(id, team)
- return team
- }
- }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/Podlasie.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/Podlasie.kt
index d7ec441f..0eaaebae 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/Podlasie.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/Podlasie.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.PodlasieData
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.firstlogin.PodlasieFirstLogin
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLogin
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
@@ -142,6 +143,10 @@ class Podlasie(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted()
}
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) {
+ callback.onRequiresUserAction(event)
+ }
+
override fun onProgress(step: Float) {
callback.onProgress(step)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/PodlasieApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/PodlasieApi.kt
index 985b9899..726b851a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/PodlasieApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/PodlasieApi.kt
@@ -12,9 +12,9 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getJsonObject
-import pl.szczodrzynski.edziennik.toHexString
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.toHexString
import pl.szczodrzynski.edziennik.utils.Utils
import java.security.MessageDigest
import java.text.SimpleDateFormat
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiEvents.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiEvents.kt
index 8a169ee7..f51c7477 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiEvents.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiEvents.kt
@@ -9,8 +9,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import java.util.*
@@ -26,7 +26,7 @@ class PodlasieApiEvents(val data: DataPodlasie, val rows: List) {
val name = event.getString("Name")?.replace(""", "\"") ?: ""
val description = event.getString("Description")?.replace(""", "\"") ?: ""
- val type = when (event.getString("Category")?.toLowerCase(Locale.getDefault())) {
+ val type = when (event.getString("Category")?.lowercase()) {
"klasówka" -> Event.TYPE_EXAM
"praca domowa" -> Event.TYPE_HOMEWORK
"wycieczka" -> Event.TYPE_EXCURSION
@@ -57,6 +57,7 @@ class PodlasieApiEvents(val data: DataPodlasie, val rows: List) {
addedDate = addedDate
).apply {
homeworkBody = description
+ isDownloaded = true
}
data.eventList.add(eventObject)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiFinalGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiFinalGrades.kt
index 7c4575aa..94dadfc8 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiFinalGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiFinalGrades.kt
@@ -15,8 +15,8 @@ import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_FINAL
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
class PodlasieApiFinalGrades(val data: DataPodlasie, val rows: List) {
init { data.profile?.also { profile ->
@@ -36,7 +36,7 @@ class PodlasieApiFinalGrades(val data: DataPodlasie, val rows: List)
}
val subjectName = grade.getString("SchoolSubject") ?: return@forEach
- val subject = data.getSubject(subjectName)
+ val subject = data.getSubject(null, subjectName)
val addedDate = if (profile.empty) profile.getSemesterStart(semester).inMillis
else System.currentTimeMillis()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiGrades.kt
index d5696567..4aa749ef 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiGrades.kt
@@ -10,10 +10,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.getFloat
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getFloat
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
class PodlasieApiGrades(val data: DataPodlasie, val rows: List) {
@@ -34,7 +34,7 @@ class PodlasieApiGrades(val data: DataPodlasie, val rows: List) {
val teacher = data.getTeacher(teacherFirstName, teacherLastName)
val subjectName = grade.getString("SchoolSubject") ?: return@forEach
- val subject = data.getSubject(subjectName)
+ val subject = data.getSubject(null, subjectName)
val addedDate = grade.getString("ReceivedDate")?.let { Date.fromY_m_d(it).inMillis }
?: System.currentTimeMillis()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiHomework.kt
index 6ab53328..be2fd062 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiHomework.kt
@@ -5,13 +5,13 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.api
import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.crc32
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.get
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.crc32
+import pl.szczodrzynski.edziennik.ext.get
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
class PodlasieApiHomework(val data: DataPodlasie, val rows: List) {
@@ -37,6 +37,7 @@ class PodlasieApiHomework(val data: DataPodlasie, val rows: List) {
addedDate = addedDate
).apply {
homeworkBody = description
+ isDownloaded = true
}
eventObject.attachmentIds = mutableListOf()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiMain.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiMain.kt
index 6fe77b5c..bf9379b3 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiMain.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiMain.kt
@@ -4,14 +4,14 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.api
-import pl.szczodrzynski.edziennik.asJsonObjectList
import pl.szczodrzynski.edziennik.data.api.PODLASIE_API_USER_ENDPOINT
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.ENDPOINT_PODLASIE_API_MAIN
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.PodlasieApi
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getJsonArray
+import pl.szczodrzynski.edziennik.ext.asJsonObjectList
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getJsonArray
class PodlasieApiMain(override val data: DataPodlasie,
override val lastSync: Long?,
@@ -22,7 +22,13 @@ class PodlasieApiMain(override val data: DataPodlasie,
init {
apiGet(TAG, PODLASIE_API_USER_ENDPOINT) { json ->
- data.getTeam() // Save the class team when it doesn't exist.
+ // Save the class team when it doesn't exist.
+ data.getTeam(
+ id = null,
+ name = data.className ?: "",
+ schoolCode = data.schoolShortName ?: "",
+ isTeamClass = true
+ )
json.getInt("LuckyNumber")?.let { PodlasieApiLuckyNumber(data, it) }
json.getJsonArray("Teacher")?.asJsonObjectList()?.let { PodlasieApiTeachers(data, it) }
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTeachers.kt
index ca1fa7b4..f4769169 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTeachers.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTeachers.kt
@@ -7,9 +7,9 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.api
import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
class PodlasieApiTeachers(val data: DataPodlasie, val rows: List) {
init {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTimetable.kt
index a9a12d5d..8c95d054 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/data/api/PodlasieApiTimetable.kt
@@ -8,8 +8,8 @@ import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.DataPodlasie
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week
@@ -43,14 +43,21 @@ class PodlasieApiTimetable(val data: DataPodlasie, rows: List) {
val startTime = lesson.getString("TimeFrom")?.let { Time.fromH_m_s(it) }
?: return@forEach
val endTime = lesson.getString("TimeTo")?.let { Time.fromH_m_s(it) } ?: return@forEach
- val subject = lesson.getString("SchoolSubject")?.let { data.getSubject(it) }
+ val subject = lesson.getString("SchoolSubject")?.let { data.getSubject(null, it) }
?: return@forEach
val teacherFirstName = lesson.getString("TeacherFirstName") ?: return@forEach
val teacherLastName = lesson.getString("TeacherLastName") ?: return@forEach
val teacher = data.getTeacher(teacherFirstName, teacherLastName)
- val team = lesson.getString("Group")?.let { data.getTeam(it) } ?: return@forEach
+ val team = lesson.getString("Group")?.let {
+ data.getTeam(
+ id = null,
+ name = it,
+ schoolCode = data.schoolShortName ?: "",
+ isTeamClass = it == "cała klasa"
+ )
+ } ?: return@forEach
val classroom = lesson.getString("Room")
Lesson(data.profileId, -1).also {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/firstlogin/PodlasieFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/firstlogin/PodlasieFirstLogin.kt
index a1e9d0eb..a99ea2ee 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/firstlogin/PodlasieFirstLogin.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/podlasie/firstlogin/PodlasieFirstLogin.kt
@@ -5,7 +5,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.firstlogin
import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_PODLASIE
import pl.szczodrzynski.edziennik.data.api.PODLASIE_API_LOGOUT_DEVICES_ENDPOINT
import pl.szczodrzynski.edziennik.data.api.PODLASIE_API_USER_ENDPOINT
@@ -14,6 +13,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data.PodlasieApi
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLoginApi
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.getShortName
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.set
class PodlasieFirstLogin(val data: DataPodlasie, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/DataTemplate.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/DataTemplate.kt
index dcf569cf..17644978 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/DataTemplate.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/DataTemplate.kt
@@ -5,13 +5,13 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_API
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_TEMPLATE_WEB
import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
/**
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/Template.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/Template.kt
index 843d36e9..8abf079f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/Template.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/Template.kt
@@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.CODE_INTERNAL_LIBRUS_ACCOUNT_410
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.TemplateData
import pl.szczodrzynski.edziennik.data.api.edziennik.template.firstlogin.TemplateFirstLogin
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLogin
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
@@ -108,6 +109,10 @@ class Template(val app: App, val profile: Profile?, val loginStore: LoginStore,
callback.onCompleted()
}
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) {
+ callback.onRequiresUserAction(event)
+ }
+
override fun onProgress(step: Float) {
callback.onProgress(step)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateApi.kt
index d3d4c607..69e8f654 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateApi.kt
@@ -5,11 +5,11 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.data
import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.ERROR_TEMPLATE_WEB_OTHER
import pl.szczodrzynski.edziennik.data.api.GET
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
open class TemplateApi(open val data: DataTemplate, open val lastSync: Long?) {
companion object {
@@ -28,6 +28,7 @@ open class TemplateApi(open val data: DataTemplate, open val lastSync: Long?) {
* You can customize this method's parameters to best fit the implemented e-register.
* Just make sure that [tag] and [onSuccess] is present.
*/
+ @Suppress("UNUSED_PARAMETER")
fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject?) -> Unit) {
val json = JsonObject()
json.addProperty("foo", "bar")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateWeb.kt
index 0db508c7..2db8c41b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateWeb.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/TemplateWeb.kt
@@ -5,11 +5,11 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.data
import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.ERROR_TEMPLATE_WEB_OTHER
import pl.szczodrzynski.edziennik.data.api.GET
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
open class TemplateWeb(open val data: DataTemplate, open val lastSync: Long?) {
companion object {
@@ -28,6 +28,7 @@ open class TemplateWeb(open val data: DataTemplate, open val lastSync: Long?) {
* You can customize this method's parameters to best fit the implemented e-register.
* Just make sure that [tag] and [onSuccess] is present.
*/
+ @Suppress("UNUSED_PARAMETER")
fun webGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject?) -> Unit) {
val json = JsonObject()
json.addProperty("foo", "bar")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/api/TemplateApiSample.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/api/TemplateApiSample.kt
index 632a8e74..d61dc8f9 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/api/TemplateApiSample.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/api/TemplateApiSample.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.data.api
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.edziennik.template.ENDPOINT_TEMPLATE_API_SAMPLE
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.TemplateApi
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.DAY
class TemplateApiSample(override val data: DataTemplate,
override val lastSync: Long?,
@@ -20,7 +20,7 @@ class TemplateApiSample(override val data: DataTemplate,
}
init {
- apiGet(TAG, "/api/v3/getData.php") { json ->
+ apiGet(TAG, "/api/v3/getData.php") { _ ->
// here you can access and update any fields of the `data` object
// ================
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample.kt
index f0ba882e..0732710a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample.kt
@@ -4,13 +4,13 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.edziennik.template.ENDPOINT_TEMPLATE_WEB_SAMPLE
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.TemplateWeb
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.DAY
class TemplateWebSample(override val data: DataTemplate,
override val lastSync: Long?,
@@ -21,7 +21,7 @@ class TemplateWebSample(override val data: DataTemplate,
}
init {
- webGet(TAG, "/api/v3/getData.php") { json ->
+ webGet(TAG, "/api/v3/getData.php") {
// here you can access and update any fields of the `data` object
// ================
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample2.kt
index 02d58231..ecf41b64 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample2.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/data/web/TemplateWebSample2.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.edziennik.template.ENDPOINT_TEMPLATE_WEB_SAMPLE_2
import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.TemplateWeb
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.DAY
class TemplateWebSample2(override val data: DataTemplate,
override val lastSync: Long?,
@@ -20,7 +20,7 @@ class TemplateWebSample2(override val data: DataTemplate,
}
init {
- webGet(TAG, "/api/v3/getData.php") { json ->
+ webGet(TAG, "/api/v3/getData.php") {
// here you can access and update any fields of the `data` object
// ================
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginApi.kt
index fc1fc20e..f49e433a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginApi.kt
@@ -4,12 +4,12 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.login
-import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.HOUR
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
class TemplateLoginApi(val data: DataTemplate, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginWeb.kt
index d7a24ef0..2f5b72c6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginWeb.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/template/login/TemplateLoginWeb.kt
@@ -4,11 +4,11 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.template.login
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
class TemplateLoginWeb(val data: DataTemplate, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt
new file mode 100644
index 00000000..5cd054f8
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/DataUsos.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-11.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos
+
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_USOS_API
+import pl.szczodrzynski.edziennik.data.api.models.Data
+import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
+import pl.szczodrzynski.edziennik.data.db.entity.Profile
+
+class DataUsos(
+ app: App,
+ profile: Profile?,
+ loginStore: LoginStore,
+) : Data(app, profile, loginStore) {
+
+ fun isApiLoginValid() = oauthTokenKey != null && oauthTokenSecret != null && oauthTokenIsUser
+
+ override fun satisfyLoginMethods() {
+ loginMethods.clear()
+ if (isApiLoginValid()) {
+ loginMethods += LOGIN_METHOD_USOS_API
+ }
+ }
+
+ override fun generateUserCode() = "$schoolId:${profile?.studentNumber ?: studentId}"
+
+ var schoolId: String?
+ get() { mSchoolId = mSchoolId ?: loginStore.getLoginData("schoolId", null); return mSchoolId }
+ set(value) { loginStore.putLoginData("schoolId", value); mSchoolId = value }
+ private var mSchoolId: String? = null
+
+ var instanceUrl: String?
+ get() { mInstanceUrl = mInstanceUrl ?: loginStore.getLoginData("instanceUrl", null); return mInstanceUrl }
+ set(value) { loginStore.putLoginData("instanceUrl", value); mInstanceUrl = value }
+ private var mInstanceUrl: String? = null
+
+ var oauthLoginResponse: String?
+ get() { mOauthLoginResponse = mOauthLoginResponse ?: loginStore.getLoginData("oauthLoginResponse", null); return mOauthLoginResponse }
+ set(value) { loginStore.putLoginData("oauthLoginResponse", value); mOauthLoginResponse = value }
+ private var mOauthLoginResponse: String? = null
+
+ var oauthConsumerKey: String?
+ get() { mOauthConsumerKey = mOauthConsumerKey ?: loginStore.getLoginData("oauthConsumerKey", null); return mOauthConsumerKey }
+ set(value) { loginStore.putLoginData("oauthConsumerKey", value); mOauthConsumerKey = value }
+ private var mOauthConsumerKey: String? = null
+
+ var oauthConsumerSecret: String?
+ get() { mOauthConsumerSecret = mOauthConsumerSecret ?: loginStore.getLoginData("oauthConsumerSecret", null); return mOauthConsumerSecret }
+ set(value) { loginStore.putLoginData("oauthConsumerSecret", value); mOauthConsumerSecret = value }
+ private var mOauthConsumerSecret: String? = null
+
+ var oauthTokenKey: String?
+ get() { mOauthTokenKey = mOauthTokenKey ?: loginStore.getLoginData("oauthTokenKey", null); return mOauthTokenKey }
+ set(value) { loginStore.putLoginData("oauthTokenKey", value); mOauthTokenKey = value }
+ private var mOauthTokenKey: String? = null
+
+ var oauthTokenSecret: String?
+ get() { mOauthTokenSecret = mOauthTokenSecret ?: loginStore.getLoginData("oauthTokenSecret", null); return mOauthTokenSecret }
+ set(value) { loginStore.putLoginData("oauthTokenSecret", value); mOauthTokenSecret = value }
+ private var mOauthTokenSecret: String? = null
+
+ var oauthTokenIsUser: Boolean
+ get() { mOauthTokenIsUser = mOauthTokenIsUser ?: loginStore.getLoginData("oauthTokenIsUser", false); return mOauthTokenIsUser ?: false }
+ set(value) { loginStore.putLoginData("oauthTokenIsUser", value); mOauthTokenIsUser = value }
+ private var mOauthTokenIsUser: Boolean? = null
+
+ var studentId: Int
+ get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", 0); return mStudentId ?: 0 }
+ set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value }
+ private var mStudentId: Int? = null
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/Usos.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/Usos.kt
new file mode 100644
index 00000000..cbf92ca8
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/Usos.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-11.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos
+
+import com.google.gson.JsonObject
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosData
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.firstlogin.UsosFirstLogin
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLogin
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
+import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
+import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
+import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.data.api.prepare
+import pl.szczodrzynski.edziennik.data.api.usosLoginMethods
+import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
+import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
+import pl.szczodrzynski.edziennik.data.db.full.EventFull
+import pl.szczodrzynski.edziennik.data.db.full.MessageFull
+import pl.szczodrzynski.edziennik.utils.Utils.d
+
+class Usos(
+ val app: App,
+ val profile: Profile?,
+ val loginStore: LoginStore,
+ val callback: EdziennikCallback,
+) : EdziennikInterface {
+ companion object {
+ private const val TAG = "Usos"
+ }
+
+ val internalErrorList = mutableListOf()
+ val data: DataUsos
+
+ init {
+ data = DataUsos(app, profile, loginStore).apply {
+ callback = wrapCallback(this@Usos.callback)
+ satisfyLoginMethods()
+ }
+ }
+
+ private fun completed() {
+ data.saveData()
+ callback.onCompleted()
+ }
+
+ override fun sync(
+ featureIds: List,
+ viewId: Int?,
+ onlyEndpoints: List?,
+ arguments: JsonObject?,
+ ) {
+ data.arguments = arguments
+ data.prepare(usosLoginMethods, UsosFeatures, featureIds, viewId, onlyEndpoints)
+ d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
+ d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
+ UsosLogin(data) {
+ UsosData(data) {
+ completed()
+ }
+ }
+ }
+
+ override fun getMessage(message: MessageFull) {}
+ override fun sendMessage(recipients: List, subject: String, text: String) {}
+ override fun markAllAnnouncementsAsRead() {}
+ override fun getAnnouncement(announcement: AnnouncementFull) {}
+ override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
+ override fun getRecipientList() {}
+ override fun getEvent(eventFull: EventFull) {}
+
+ override fun firstLogin() {
+ UsosFirstLogin(data) {
+ completed()
+ }
+ }
+
+ override fun cancel() {
+ d(TAG, "Cancelled")
+ data.cancel()
+ }
+
+ private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
+ return object : EdziennikCallback {
+ override fun onCompleted() {
+ callback.onCompleted()
+ }
+
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) {
+ callback.onRequiresUserAction(event)
+ }
+
+ override fun onProgress(step: Float) {
+ callback.onProgress(step)
+ }
+
+ override fun onStartProgress(stringRes: Int) {
+ callback.onStartProgress(stringRes)
+ }
+
+ override fun onError(apiError: ApiError) {
+ when (apiError.errorCode) {
+ in internalErrorList -> {
+ // finish immediately if the same error occurs twice during the same sync
+ callback.onError(apiError)
+ }
+ else -> callback.onError(apiError)
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/UsosFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/UsosFeatures.kt
new file mode 100644
index 00000000..50c15582
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/UsosFeatures.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-11.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos
+
+import pl.szczodrzynski.edziennik.data.api.*
+import pl.szczodrzynski.edziennik.data.api.models.Feature
+
+const val ENDPOINT_USOS_API_USER = 7000
+const val ENDPOINT_USOS_API_TERMS = 7010
+const val ENDPOINT_USOS_API_COURSES = 7020
+const val ENDPOINT_USOS_API_TIMETABLE = 7030
+
+val UsosFeatures = listOf(
+ /*
+ * Student information
+ */
+ Feature(LOGIN_TYPE_USOS, FEATURE_STUDENT_INFO, listOf(
+ ENDPOINT_USOS_API_USER to LOGIN_METHOD_USOS_API,
+ ), listOf(LOGIN_METHOD_USOS_API)),
+
+ /*
+ * Terms & courses
+ */
+ Feature(LOGIN_TYPE_USOS, FEATURE_SCHOOL_INFO, listOf(
+ ENDPOINT_USOS_API_TERMS to LOGIN_METHOD_USOS_API,
+ ), listOf(LOGIN_METHOD_USOS_API)),
+ Feature(LOGIN_TYPE_USOS, FEATURE_TEAM_INFO, listOf(
+ ENDPOINT_USOS_API_COURSES to LOGIN_METHOD_USOS_API,
+ ), listOf(LOGIN_METHOD_USOS_API)),
+
+ /*
+ * Timetable
+ */
+ Feature(LOGIN_TYPE_USOS, FEATURE_TIMETABLE, listOf(
+ ENDPOINT_USOS_API_TIMETABLE to LOGIN_METHOD_USOS_API,
+ ), listOf(LOGIN_METHOD_USOS_API)),
+)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt
new file mode 100644
index 00000000..9f716d50
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosApi.kt
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-13.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import im.wangchao.mhttp.Request
+import im.wangchao.mhttp.Response
+import im.wangchao.mhttp.body.MediaTypeUtils
+import im.wangchao.mhttp.callback.JsonArrayCallbackHandler
+import im.wangchao.mhttp.callback.JsonCallbackHandler
+import im.wangchao.mhttp.callback.TextCallbackHandler
+import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_API_MISSING_RESPONSE
+import pl.szczodrzynski.edziennik.data.api.SERVER_USER_AGENT
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi
+import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
+import pl.szczodrzynski.edziennik.utils.Utils.d
+import java.net.HttpURLConnection.*
+import java.util.UUID
+
+open class UsosApi(open val data: DataUsos, open val lastSync: Long?) {
+ companion object {
+ private const val TAG = "UsosApi"
+ }
+
+ enum class ResponseType {
+ OBJECT,
+ ARRAY,
+ PLAIN,
+ }
+
+ val profileId
+ get() = data.profile?.id ?: -1
+
+ val profile
+ get() = data.profile
+
+ protected fun JsonObject.getLangString(key: String) =
+ this.getJsonObject(key)?.getString("pl")
+
+ protected fun JsonObject.getLecturerIds(key: String) =
+ this.getJsonArray(key)?.asJsonObjectList()?.mapNotNull {
+ val id = it.getLong("id") ?: return@mapNotNull null
+ val firstName = it.getString("first_name") ?: return@mapNotNull null
+ val lastName = it.getString("last_name") ?: return@mapNotNull null
+ data.getTeacher(firstName, lastName, id = id).id
+ } ?: listOf()
+
+ private fun valueToString(value: Any) = when (value) {
+ is String -> value
+ is Number -> value.toString()
+ is List<*> -> listToString(value)
+ else -> value.toString()
+ }
+
+ private fun listToString(list: List<*>): String {
+ return list.map {
+ if (it is Pair<*, *> && it.first is String && it.second is List<*>)
+ return@map "${it.first}[${listToString(it.second as List<*>)}]"
+ return@map valueToString(it ?: "")
+ }.joinToString("|")
+ }
+
+ private fun buildSignature(method: String, url: String, params: Map): String {
+ val query = params.toQueryString()
+ val signatureString = listOf(
+ method.uppercase(),
+ url.urlEncode(),
+ query.urlEncode(),
+ ).joinToString("&")
+ val signingKey = listOf(
+ data.oauthConsumerSecret ?: "",
+ data.oauthTokenSecret ?: "",
+ ).joinToString("&") { it.urlEncode() }
+ return signatureString.hmacSHA1(signingKey)
+ }
+
+ fun apiRequest(
+ tag: String,
+ service: String,
+ params: Map? = null,
+ fields: List? = null,
+ responseType: ResponseType,
+ onSuccess: (data: T, response: Response?) -> Unit,
+ ) {
+ val url = "${data.instanceUrl}services/$service"
+ d(tag, "Request: Usos/Api - $url")
+
+ val formData = mutableMapOf()
+ if (params != null)
+ formData.putAll(params.mapValues {
+ valueToString(it.value)
+ })
+ if (fields != null)
+ formData["fields"] = valueToString(fields)
+
+ val auth = mutableMapOf(
+ "realm" to url,
+ "oauth_consumer_key" to (data.oauthConsumerKey ?: ""),
+ "oauth_nonce" to UUID.randomUUID().toString(),
+ "oauth_signature_method" to "HMAC-SHA1",
+ "oauth_timestamp" to currentTimeUnix().toString(),
+ "oauth_token" to (data.oauthTokenKey ?: ""),
+ "oauth_version" to "1.0",
+ )
+ val signature = buildSignature(
+ method = "POST",
+ url = url,
+ params = formData + auth.filterKeys { it.startsWith("oauth_") },
+ )
+ auth["oauth_signature"] = signature
+
+ val authString = auth.map {
+ """${it.key}="${it.value.urlEncode()}""""
+ }.joinToString(", ")
+
+ Request.builder()
+ .url(url)
+ .userAgent(SERVER_USER_AGENT)
+ .addHeader("Authorization", "OAuth $authString")
+ .post()
+ .setTextBody(formData.toQueryString(), MediaTypeUtils.APPLICATION_FORM)
+ .allowErrorCode(HTTP_BAD_REQUEST)
+ .allowErrorCode(HTTP_UNAUTHORIZED)
+ .allowErrorCode(HTTP_FORBIDDEN)
+ .allowErrorCode(HTTP_NOT_FOUND)
+ .allowErrorCode(HTTP_UNAVAILABLE)
+ .callback(getCallback(tag, responseType, onSuccess))
+ .build()
+ .enqueue()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ private fun getCallback(
+ tag: String,
+ responseType: ResponseType,
+ onSuccess: (data: T, response: Response?) -> Unit,
+ ) = when (responseType) {
+ ResponseType.OBJECT -> object : JsonCallbackHandler() {
+ override fun onSuccess(data: JsonObject?, response: Response) {
+ processResponse(tag, response, data as T?, onSuccess)
+ }
+
+ override fun onFailure(response: Response?, throwable: Throwable?) {
+ processError(tag, response, throwable)
+ }
+ }
+ ResponseType.ARRAY -> object : JsonArrayCallbackHandler() {
+ override fun onSuccess(data: JsonArray?, response: Response) {
+ processResponse(tag, response, data as T?, onSuccess)
+ }
+
+ override fun onFailure(response: Response?, throwable: Throwable?) {
+ processError(tag, response, throwable)
+ }
+ }
+ ResponseType.PLAIN -> object : TextCallbackHandler() {
+ override fun onSuccess(data: String?, response: Response) {
+ processResponse(tag, response, data as T?, onSuccess)
+ }
+
+ override fun onFailure(response: Response?, throwable: Throwable?) {
+ processError(tag, response, throwable)
+ }
+ }
+ }
+
+ private fun processResponse(
+ tag: String,
+ response: Response,
+ value: T?,
+ onSuccess: (data: T, response: Response?) -> Unit,
+ ) {
+ val errorCode = when {
+ response.code() == HTTP_UNAUTHORIZED -> {
+ data.oauthTokenKey = null
+ data.oauthTokenSecret = null
+ data.oauthTokenIsUser = false
+ data.oauthLoginResponse = null
+ UsosLoginApi(data) { }
+ return
+ }
+ value == null -> ERROR_USOS_API_MISSING_RESPONSE
+ response.code() == HTTP_OK -> {
+ onSuccess(value, response)
+ null
+ }
+ else -> response.toErrorCode()
+ }
+ if (errorCode != null) {
+ data.error(tag, errorCode, response, value.toString())
+ }
+ }
+
+ private fun processError(
+ tag: String,
+ response: Response?,
+ throwable: Throwable?,
+ ) {
+ data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
+ .withResponse(response)
+ .withThrowable(throwable))
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosData.kt
new file mode 100644
index 00000000..d688bebf
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/UsosData.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-13.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data
+
+import pl.szczodrzynski.edziennik.R
+import pl.szczodrzynski.edziennik.data.api.edziennik.template.data.web.TemplateWebSample
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.*
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiCourses
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTerms
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiTimetable
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api.UsosApiUser
+import pl.szczodrzynski.edziennik.utils.Utils.d
+
+class UsosData(val data: DataUsos, val onSuccess: () -> Unit) {
+ companion object {
+ private const val TAG = "UsosData"
+ }
+
+ init {
+ nextEndpoint(onSuccess)
+ }
+
+ private fun nextEndpoint(onSuccess: () -> Unit) {
+ if (data.targetEndpointIds.isEmpty()) {
+ onSuccess()
+ return
+ }
+ if (data.cancelled) {
+ onSuccess()
+ return
+ }
+ val id = data.targetEndpointIds.firstKey()
+ val lastSync = data.targetEndpointIds.remove(id)
+ useEndpoint(id, lastSync) { endpointId ->
+ data.progress(data.progressStep)
+ nextEndpoint(onSuccess)
+ }
+ }
+
+ private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
+ d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
+ when (endpointId) {
+ ENDPOINT_USOS_API_USER -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_student_info)
+ UsosApiUser(data, lastSync, onSuccess)
+ }
+ ENDPOINT_USOS_API_TERMS -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_school_info)
+ UsosApiTerms(data, lastSync, onSuccess)
+ }
+ ENDPOINT_USOS_API_COURSES -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_teams)
+ UsosApiCourses(data, lastSync, onSuccess)
+ }
+ ENDPOINT_USOS_API_TIMETABLE -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_timetable)
+ UsosApiTimetable(data, lastSync, onSuccess)
+ }
+ else -> onSuccess(endpointId)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiCourses.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiCourses.kt
new file mode 100644
index 00000000..e93c63dd
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiCourses.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-15.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api
+
+import com.google.gson.JsonObject
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_API_INCOMPLETE_RESPONSE
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.ENDPOINT_USOS_API_COURSES
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.data.db.entity.Team
+import pl.szczodrzynski.edziennik.ext.*
+
+class UsosApiCourses(
+ override val data: DataUsos,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit,
+) : UsosApi(data, lastSync) {
+ companion object {
+ const val TAG = "UsosApiCourses"
+ }
+
+ init {
+ apiRequest(
+ tag = TAG,
+ service = "courses/user",
+ fields = listOf(
+ // "terms" to listOf("id", "name", "start_date", "end_date"),
+ "course_editions" to listOf(
+ "course_id",
+ "course_name",
+ // "term_id",
+ "user_groups" to listOf(
+ "course_unit_id",
+ "group_number",
+ // "class_type",
+ "class_type_id",
+ "lecturers",
+ ),
+ ),
+ ),
+ responseType = ResponseType.OBJECT,
+ ) { json, response ->
+ if (!processResponse(json)) {
+ data.error(TAG, ERROR_USOS_API_INCOMPLETE_RESPONSE, response)
+ return@apiRequest
+ }
+
+ data.setSyncNext(ENDPOINT_USOS_API_COURSES, 2 * DAY)
+ onSuccess(ENDPOINT_USOS_API_COURSES)
+ }
+ }
+
+ private fun processResponse(json: JsonObject): Boolean {
+ // val term = json.getJsonArray("terms")?.firstOrNull() ?: return false
+ val courseEditions = json.getJsonObject("course_editions")
+ ?.entrySet()
+ ?.flatMap { it.value.asJsonArray }
+ ?.map { it.asJsonObject } ?: return false
+
+ var hasValidTeam = false
+ for (courseEdition in courseEditions) {
+ val courseId = courseEdition.getString("course_id") ?: continue
+ val courseName = courseEdition.getLangString("course_name") ?: continue
+ val userGroups = courseEdition.getJsonArray("user_groups")?.asJsonObjectList() ?: continue
+ for (userGroup in userGroups) {
+ val courseUnitId = userGroup.getLong("course_unit_id") ?: continue
+ val groupNumber = userGroup.getInt("group_number") ?: continue
+ // val classType = userGroup.getLangString("class_type") ?: continue
+ val classTypeId = userGroup.getString("class_type_id") ?: continue
+ val lecturers = userGroup.getLecturerIds("lecturers")
+
+ data.teamList.put(courseUnitId, Team(
+ profileId,
+ courseUnitId,
+ "${profile?.studentClassName} $classTypeId$groupNumber - $courseName",
+ 2,
+ "${data.schoolId}:${courseId} $classTypeId$groupNumber",
+ lecturers.firstOrNull() ?: -1L,
+ ))
+ hasValidTeam = true
+ }
+ }
+ return hasValidTeam
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTerms.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTerms.kt
new file mode 100644
index 00000000..1bf47288
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTerms.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-15.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api
+
+import com.google.gson.JsonArray
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_API_INCOMPLETE_RESPONSE
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.ENDPOINT_USOS_API_TERMS
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.ext.*
+import pl.szczodrzynski.edziennik.utils.models.Date
+
+class UsosApiTerms(
+ override val data: DataUsos,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit,
+) : UsosApi(data, lastSync) {
+ companion object {
+ const val TAG = "UsosApiTerms"
+ }
+
+ init {
+ apiRequest(
+ tag = TAG,
+ service = "terms/search",
+ params = mapOf(
+ "query" to Date.getToday().year.toString(),
+ ),
+ responseType = ResponseType.ARRAY,
+ ) { json, response ->
+ if (!processResponse(json)) {
+ data.error(TAG, ERROR_USOS_API_INCOMPLETE_RESPONSE, response)
+ return@apiRequest
+ }
+
+ data.setSyncNext(ENDPOINT_USOS_API_TERMS, 7 * DAY)
+ onSuccess(ENDPOINT_USOS_API_TERMS)
+ }
+ }
+
+ private fun processResponse(json: JsonArray): Boolean {
+ val dates = mutableSetOf()
+ for (term in json.asJsonObjectList()) {
+ if (!term.getBoolean("is_active", false))
+ continue
+ val startDate = term.getString("start_date")?.let { Date.fromY_m_d(it) }
+ val finishDate = term.getString("finish_date")?.let { Date.fromY_m_d(it) }
+ if (startDate != null)
+ dates += startDate
+ if (finishDate != null)
+ dates += finishDate
+ }
+ val datesSorted = dates.sorted()
+ if (datesSorted.size != 3)
+ return false
+ profile?.studentSchoolYearStart = datesSorted[0].year
+ profile?.dateSemester1Start = datesSorted[0]
+ profile?.dateSemester2Start = datesSorted[1]
+ profile?.dateYearEnd = datesSorted[2]
+ return true
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTimetable.kt
new file mode 100644
index 00000000..6c1acc54
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiTimetable.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api
+
+import com.google.gson.JsonArray
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_API_INCOMPLETE_RESPONSE
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.ENDPOINT_USOS_API_TIMETABLE
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
+import pl.szczodrzynski.edziennik.data.db.entity.Lesson
+import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
+import pl.szczodrzynski.edziennik.utils.models.Date
+import pl.szczodrzynski.edziennik.utils.models.Time
+import pl.szczodrzynski.edziennik.utils.models.Week
+
+class UsosApiTimetable(
+ override val data: DataUsos,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit,
+) : UsosApi(data, lastSync) {
+ companion object {
+ const val TAG = "UsosApiTimetable"
+ }
+
+ init {
+ val currentWeekStart = Week.getWeekStart()
+ if (Date.getToday().weekDay > 4)
+ currentWeekStart.stepForward(0, 0, 7)
+
+ val weekStart = data.arguments
+ ?.getString("weekStart")
+ ?.let { Date.fromY_m_d(it) }
+ ?: currentWeekStart
+ val weekEnd = weekStart.clone().stepForward(0, 0, 6)
+
+ apiRequest(
+ tag = TAG,
+ service = "tt/user",
+ params = mapOf(
+ "start" to weekStart.stringY_m_d,
+ "days" to 7,
+ ),
+ fields = listOf(
+ "type",
+ "start_time",
+ "end_time",
+ "unit_id",
+ "course_id",
+ "course_name",
+ "lecturer_ids",
+ "building_id",
+ "room_number",
+ "classtype_id",
+ "group_number",
+ ),
+ responseType = ResponseType.ARRAY,
+ ) { json, response ->
+ if (!processResponse(json, weekStart..weekEnd)) {
+ data.error(TAG, ERROR_USOS_API_INCOMPLETE_RESPONSE, response)
+ return@apiRequest
+ }
+
+ data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
+ data.setSyncNext(ENDPOINT_USOS_API_TIMETABLE, SYNC_ALWAYS)
+ onSuccess(ENDPOINT_USOS_API_TIMETABLE)
+ }
+ }
+
+ private fun processResponse(json: JsonArray, syncRange: ClosedRange): Boolean {
+ val foundDates = mutableSetOf()
+
+ for (activity in json.asJsonObjectList()) {
+ val type = activity.getString("type")
+ if (type !in listOf("classgroup", "classgroup2"))
+ continue
+
+ val startTime = activity.getString("start_time") ?: continue
+ val endTime = activity.getString("end_time") ?: continue
+ val unitId = activity.getLong("unit_id", -1)
+ val courseName = activity.getLangString("course_name") ?: continue
+ val courseId = activity.getString("course_id") ?: continue
+ val lecturerIds = activity.getJsonArray("lecturer_ids")?.map { it.asLong }
+ val buildingId = activity.getString("building_id")
+ val roomNumber = activity.getString("room_number")
+ val classTypeId = activity.getString("classtype_id")
+ val groupNumber = activity.getString("group_number")
+
+ val lesson = Lesson(profileId, -1).also {
+ it.type = Lesson.TYPE_NORMAL
+ it.date = Date.fromY_m_d(startTime)
+ it.startTime = Time.fromY_m_d_H_m_s(startTime)
+ it.endTime = Time.fromY_m_d_H_m_s(endTime)
+ it.subjectId = data.getSubject(
+ id = null,
+ name = courseName,
+ shortName = courseId,
+ ).id
+ it.teacherId = lecturerIds?.firstOrNull() ?: -1L
+ it.teamId = unitId
+ val groupName = classTypeId?.plus(groupNumber)?.let { s -> "($s)" }
+ it.classroom = "$buildingId / $roomNumber ${groupName ?: ""}"
+ it.id = it.buildId()
+
+ it.color = when (classTypeId) {
+ "WYK" -> 0xff0d6091
+ "CW" -> 0xff54306e
+ "LAB" -> 0xff772747
+ "KON" -> 0xff1e5128
+ "^P?SEM" -> 0xff1e5128 // TODO make it regex
+ else -> 0xff08534c
+ }.toInt()
+ }
+ lesson.date?.let { foundDates += it }
+
+ val seen = profile?.empty != false || lesson.date!! < Date.getToday()
+ data.lessonList.add(lesson)
+ if (lesson.type != Lesson.TYPE_NORMAL)
+ data.metadataList += Metadata(
+ profileId,
+ Metadata.TYPE_LESSON_CHANGE,
+ lesson.id,
+ seen,
+ seen,
+ )
+ }
+
+ val notFoundDates = syncRange.asSequence() - foundDates
+ for (date in notFoundDates) {
+ data.lessonList += Lesson(profileId, date.value.toLong()).also {
+ it.type = Lesson.TYPE_NO_LESSONS
+ it.date = date
+ }
+ }
+ return true
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiUser.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiUser.kt
new file mode 100644
index 00000000..29a3e22b
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiUser.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api
+
+import com.google.gson.JsonObject
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_NO_STUDENT_PROGRAMMES
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.ENDPOINT_USOS_API_USER
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
+
+class UsosApiUser(
+ override val data: DataUsos,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit,
+) : UsosApi(data, lastSync) {
+ companion object {
+ const val TAG = "UsosApiUser"
+ }
+
+ init {
+ apiRequest(
+ tag = TAG,
+ service = "users/user",
+ params = mapOf(
+ "fields" to listOf(
+ "id",
+ "first_name",
+ "last_name",
+ "student_number",
+ "student_programmes" to listOf(
+ "programme" to listOf("id"),
+ ),
+ ),
+ ),
+ responseType = ResponseType.OBJECT,
+ ) { json, response ->
+ val programmes = json.getJsonArray("student_programmes")
+ if (programmes.isNullOrEmpty()) {
+ data.error(ApiError(TAG, ERROR_USOS_NO_STUDENT_PROGRAMMES)
+ .withApiResponse(json)
+ .withResponse(response))
+ return@apiRequest
+ }
+
+ val firstName = json.getString("first_name")
+ val lastName = json.getString("last_name")
+ val studentName = buildFullName(firstName, lastName)
+
+ data.studentId = json.getInt("id") ?: data.studentId
+ profile?.studentNameLong = studentName
+ profile?.studentNameShort = studentName.getShortName()
+ profile?.studentNumber = json.getInt("student_number", -1)
+ profile?.studentClassName = programmes.getJsonObject(0).getJsonObject("programme").getString("id")
+
+ profile?.studentClassName?.let {
+ data.getTeam(
+ id = null,
+ name = it,
+ schoolCode = data.schoolId ?: "",
+ isTeamClass = true,
+ )
+ }
+
+ data.setSyncNext(ENDPOINT_USOS_API_USER, 4 * DAY)
+ onSuccess(ENDPOINT_USOS_API_USER)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt
new file mode 100644
index 00000000..4cb38cc6
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/firstlogin/UsosFirstLogin.kt
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-14.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.firstlogin
+
+import com.google.gson.JsonObject
+import org.greenrobot.eventbus.EventBus
+import pl.szczodrzynski.edziennik.data.api.ERROR_USOS_NO_STUDENT_PROGRAMMES
+import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_USOS
+import pl.szczodrzynski.edziennik.data.api.edziennik.librus.firstlogin.LibrusFirstLogin
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.login.UsosLoginApi
+import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
+import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.*
+
+class UsosFirstLogin(val data: DataUsos, val onSuccess: () -> Unit) {
+ companion object {
+ private const val TAG = "UsosFirstLogin"
+ }
+
+ private val api = UsosApi(data, null)
+
+ init {
+ val loginStoreId = data.loginStore.id
+ val loginStoreType = LOGIN_TYPE_USOS
+ var firstProfileId = loginStoreId
+
+ UsosLoginApi(data) {
+ api.apiRequest(
+ tag = TAG,
+ service = "users/user",
+ params = mapOf(
+ "fields" to listOf(
+ "id",
+ "first_name",
+ "last_name",
+ "student_number",
+ "student_programmes" to listOf(
+ "programme" to listOf("id"),
+ ),
+ ),
+ ),
+ responseType = UsosApi.ResponseType.OBJECT,
+ ) { json, response ->
+ val programmes = json.getJsonArray("student_programmes")
+ if (programmes.isNullOrEmpty()) {
+ data.error(ApiError(TAG, ERROR_USOS_NO_STUDENT_PROGRAMMES)
+ .withApiResponse(json)
+ .withResponse(response))
+ return@apiRequest
+ }
+
+ val firstName = json.getString("first_name")
+ val lastName = json.getString("last_name")
+ val studentName = buildFullName(firstName, lastName)
+
+ val profile = Profile(
+ id = firstProfileId++,
+ loginStoreId = loginStoreId, loginStoreType = loginStoreType,
+ name = studentName,
+ subname = data.schoolId,
+ studentNameLong = studentName,
+ studentNameShort = studentName.getShortName(),
+ accountName = null, // student account
+ studentData = JsonObject(
+ "studentId" to json.getInt("id"),
+ ),
+ ).also {
+ it.studentNumber = json.getInt("student_number", -1)
+ it.studentClassName = programmes.getJsonObject(0).getJsonObject("programme").getString("id")
+ }
+
+ EventBus.getDefault().postSticky(
+ FirstLoginFinishedEvent(listOf(profile), data.loginStore),
+ )
+ onSuccess()
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLogin.kt
similarity index 61%
rename from app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt
rename to app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLogin.kt
index 1cb2fd07..599b8f16 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLogin.kt
@@ -1,17 +1,17 @@
/*
- * Copyright (c) Kacper Ziubryniewicz 2019-12-22
+ * Copyright (c) Kuba Szczodrzyński 2022-10-11.
*/
-package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login
import pl.szczodrzynski.edziennik.R
-import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
-import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
-import pl.szczodrzynski.edziennik.utils.Utils
+import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_USOS_API
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.utils.Utils.d
-class EdudziennikLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
+class UsosLogin(val data: DataUsos, val onSuccess: () -> Unit) {
companion object {
- private const val TAG = "EdudziennikLogin"
+ private const val TAG = "UsosLogin"
}
private var cancelled = false
@@ -43,11 +43,11 @@ class EdudziennikLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
onSuccess(-1)
return
}
- Utils.d(TAG, "Using login method $loginMethodId")
+ d(TAG, "Using login method $loginMethodId")
when (loginMethodId) {
- LOGIN_METHOD_EDUDZIENNIK_WEB -> {
- data.startProgress(R.string.edziennik_progress_login_edudziennik_web)
- EdudziennikLoginWeb(data) { onSuccess(loginMethodId) }
+ LOGIN_METHOD_USOS_API -> {
+ data.startProgress(R.string.edziennik_progress_login_usos_api)
+ UsosLoginApi(data) { onSuccess(loginMethodId) }
}
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt
new file mode 100644
index 00000000..06651477
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/login/UsosLoginApi.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-11.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.usos.login
+
+import pl.szczodrzynski.edziennik.R
+import pl.szczodrzynski.edziennik.data.api.*
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.DataUsos
+import pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.UsosApi
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
+import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
+import pl.szczodrzynski.edziennik.utils.Utils.d
+
+class UsosLoginApi(val data: DataUsos, val onSuccess: () -> Unit) {
+ companion object {
+ private const val TAG = "UsosLoginApi"
+ }
+
+ private val api = UsosApi(data, null)
+
+ init {
+ run {
+ data.arguments?.getString("oauthLoginResponse")?.let {
+ data.oauthLoginResponse = it
+ }
+ if (data.isApiLoginValid()) {
+ onSuccess()
+ } else if (data.oauthLoginResponse != null) {
+ login()
+ } else {
+ authorize()
+ }
+ }
+ }
+
+ private fun authorize() {
+ data.oauthTokenKey = null
+ data.oauthTokenSecret = null
+ api.apiRequest(
+ tag = TAG,
+ service = "oauth/request_token",
+ params = mapOf(
+ "oauth_callback" to USOS_API_OAUTH_REDIRECT_URL,
+ "scopes" to USOS_API_SCOPES,
+ ),
+ responseType = UsosApi.ResponseType.PLAIN,
+ ) { text, _ ->
+ val authorizeData = text.fromQueryString()
+ data.oauthTokenKey = authorizeData["oauth_token"]
+ data.oauthTokenSecret = authorizeData["oauth_token_secret"]
+ data.oauthTokenIsUser = false
+
+ val authUrl = "${data.instanceUrl}services/oauth/authorize"
+ val authParams = mapOf(
+ "interactivity" to "confirm_user",
+ "oauth_token" to (data.oauthTokenKey ?: ""),
+ )
+ data.requireUserAction(
+ type = UserActionRequiredEvent.Type.OAUTH,
+ params = Bundle(
+ "authorizeUrl" to "$authUrl?${authParams.toQueryString()}",
+ "redirectUrl" to USOS_API_OAUTH_REDIRECT_URL,
+ "responseStoreKey" to "oauthLoginResponse",
+ "extras" to data.loginStore.data.toBundle(),
+ ),
+ errorText = R.string.notification_user_action_required_oauth_usos,
+ )
+ }
+ }
+
+ private fun login() {
+ d(TAG, "Login to ${data.schoolId} with ${data.oauthLoginResponse}")
+
+ val authorizeResponse = data.oauthLoginResponse?.fromQueryString()
+ ?: return // checked in init {}
+ if (authorizeResponse["oauth_token"] != data.oauthTokenKey) {
+ // got different token
+ data.error(ApiError(TAG, ERROR_USOS_OAUTH_GOT_DIFFERENT_TOKEN)
+ .withApiResponse(data.oauthLoginResponse))
+ return
+ }
+ val verifier = authorizeResponse["oauth_verifier"]
+ if (verifier.isNullOrBlank()) {
+ data.error(ApiError(TAG, ERROR_USOS_OAUTH_INCOMPLETE_RESPONSE)
+ .withApiResponse(data.oauthLoginResponse))
+ return
+ }
+
+ api.apiRequest(
+ tag = TAG,
+ service = "oauth/access_token",
+ params = mapOf(
+ "oauth_verifier" to verifier,
+ ),
+ responseType = UsosApi.ResponseType.PLAIN,
+ ) { text, response ->
+ val accessData = text.fromQueryString()
+ data.oauthTokenKey = accessData["oauth_token"]
+ data.oauthTokenSecret = accessData["oauth_token_secret"]
+ data.oauthTokenIsUser = data.oauthTokenKey != null && data.oauthTokenSecret != null
+ data.loginStore.removeLoginData("oauthLoginResponse")
+
+ if (!data.oauthTokenIsUser)
+ data.error(ApiError(TAG, ERROR_USOS_OAUTH_INCOMPLETE_RESPONSE)
+ .withApiResponse(text)
+ .withResponse(response))
+ else
+ onSuccess()
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
index 55185745..0c2bc91c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
@@ -6,14 +6,14 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.crc16
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_HEBE
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_WEB_MAIN
import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.crc16
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.fslogin.realm.RealmData
class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
@@ -222,6 +222,16 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
get() { mHebeContext = mHebeContext ?: profile?.getStudentData("hebeContext", null); return mHebeContext }
set(value) { profile?.putStudentData("hebeContext", value) ?: return; mHebeContext = value }
+ private var mMessageBoxKey: String? = null
+ var messageBoxKey: String?
+ get() { mMessageBoxKey = mMessageBoxKey ?: profile?.getStudentData("messageBoxKey", null); return mMessageBoxKey }
+ set(value) { profile?.putStudentData("messageBoxKey", value) ?: return; mMessageBoxKey = value }
+
+ private var mMessageBoxName: String? = null
+ var messageBoxName: String?
+ get() { mMessageBoxName = mMessageBoxName ?: profile?.getStudentData("messageBoxName", null); return mMessageBoxName }
+ set(value) { profile?.putStudentData("messageBoxName", value) ?: return; mMessageBoxName = value }
+
val apiUrl: String?
get() {
val url = when (apiToken[symbol]?.substring(0, 3)) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/Vulcan.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/Vulcan.kt
index d066aca0..37af4b69 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/Vulcan.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/Vulcan.kt
@@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLogin
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
import pl.szczodrzynski.edziennik.data.api.models.ApiError
@@ -164,6 +165,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
override fun getEvent(eventFull: EventFull) {
eventFull.homeworkBody = ""
+ eventFull.isDownloaded = true
EventBus.getDefault().postSticky(EventGetEvent(eventFull))
completed()
@@ -178,6 +180,7 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
return object : EdziennikCallback {
override fun onCompleted() { callback.onCompleted() }
+ override fun onRequiresUserAction(event: UserActionRequiredEvent) { callback.onRequiresUserAction(event) }
override fun onProgress(step: Float) { callback.onProgress(step) }
override fun onStartProgress(stringRes: Int) { callback.onStartProgress(stringRes) }
override fun onError(apiError: ApiError) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
index 2e239a7e..4def0214 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
@@ -12,6 +12,7 @@ const val ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS = 2010
const val ENDPOINT_VULCAN_HEBE_MAIN = 3000
const val ENDPOINT_VULCAN_HEBE_PUSH_CONFIG = 3005
const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK = 3010
+const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 = 3501 // after message boxes (3500)
const val ENDPOINT_VULCAN_HEBE_TIMETABLE = 3020
const val ENDPOINT_VULCAN_HEBE_EXAMS = 3030
const val ENDPOINT_VULCAN_HEBE_GRADES = 3040
@@ -19,9 +20,11 @@ const val ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY = 3050
const val ENDPOINT_VULCAN_HEBE_HOMEWORK = 3060
const val ENDPOINT_VULCAN_HEBE_NOTICES = 3070
const val ENDPOINT_VULCAN_HEBE_ATTENDANCE = 3080
-const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3090
-const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3100
+const val ENDPOINT_VULCAN_HEBE_TEACHERS = 3110
const val ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER = 3200
+const val ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES = 3500
+const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3510
+const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3520
val VulcanFeatures = listOf(
// timetable
@@ -83,6 +86,9 @@ val VulcanFeatures = listOf(
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
ENDPOINT_VULCAN_HEBE_MAIN to LOGIN_METHOD_VULCAN_HEBE,
- ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE,
+ ENDPOINT_VULCAN_HEBE_TEACHERS to LOGIN_METHOD_VULCAN_HEBE,
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES to LOGIN_METHOD_VULCAN_HEBE,
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 to LOGIN_METHOD_VULCAN_HEBE,
), listOf(LOGIN_METHOD_VULCAN_HEBE))
)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
index 0724ca46..4b3f961f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
@@ -21,12 +21,15 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
ENDPOINT_VULCAN_HEBE_MAIN,
ENDPOINT_VULCAN_HEBE_PUSH_CONFIG,
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK,
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2,
ENDPOINT_VULCAN_HEBE_TIMETABLE,
ENDPOINT_VULCAN_HEBE_EXAMS,
ENDPOINT_VULCAN_HEBE_HOMEWORK,
ENDPOINT_VULCAN_HEBE_NOTICES,
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES,
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX,
ENDPOINT_VULCAN_HEBE_MESSAGES_SENT,
+ ENDPOINT_VULCAN_HEBE_TEACHERS,
ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER
)
@@ -103,9 +106,17 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
VulcanHebePushConfig(data, lastSync, onSuccess)
}
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK -> {
- data.startProgress(R.string.edziennik_progress_endpoint_teachers)
+ data.startProgress(R.string.edziennik_progress_endpoint_addressbook)
VulcanHebeAddressbook(data, lastSync, onSuccess)
}
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_addressbook)
+ VulcanHebeAddressbook2(data, lastSync, onSuccess)
+ }
+ ENDPOINT_VULCAN_HEBE_TEACHERS -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_teachers)
+ VulcanHebeTeachers(data, lastSync, onSuccess)
+ }
ENDPOINT_VULCAN_HEBE_TIMETABLE -> {
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
VulcanHebeTimetable(data, lastSync, onSuccess)
@@ -134,6 +145,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
VulcanHebeAttendance(data, lastSync, onSuccess)
}
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_messages)
+ VulcanHebeMessageBoxes(data, lastSync, onSuccess)
+ }
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX -> {
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_RECEIVED)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
index a34e0a1b..a99ac7a4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
@@ -14,7 +14,6 @@ import im.wangchao.mhttp.Response
import im.wangchao.mhttp.body.MediaTypeUtils
import im.wangchao.mhttp.callback.JsonCallbackHandler
import io.github.wulkanowy.signer.hebe.getSignatureHeaders
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.HebeFilterType
@@ -22,7 +21,7 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
import pl.szczodrzynski.edziennik.data.db.entity.Subject
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
-import pl.szczodrzynski.edziennik.data.db.entity.Team
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -55,6 +54,15 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
return date.getLong("Timestamp") ?: return default
}
+ fun buildDateTime(): JsonObject {
+ return JsonObject(
+ "Timestamp" to System.currentTimeMillis(),
+ "Date" to Date.getToday().stringY_m_d,
+ "DateDisplay" to Date.getToday().stringDmy,
+ "Time" to Time.getNow().stringHMS,
+ )
+ }
+
fun getDate(json: JsonObject?, key: String): Date? {
val date = json.getJsonObject(key)
return date.getString("Date")?.let { Date.fromY_m_d(it) }
@@ -74,6 +82,22 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
return teacherId
}
+ fun getTeacherRecipient(json: JsonObject): Teacher? {
+ val globalKey = json.getString("GlobalKey") ?: return null
+ if (globalKey == data.messageBoxKey)
+ return null
+ var name = json.getString("Name") ?: return null
+ val group = json.getString("Group", "P")
+ val loginId = "${globalKey};${group};${name}"
+ val pattern = " - $group - (${data.schoolShort})"
+ if (name.endsWith(pattern))
+ name = name.substringBefore(pattern)
+ val teacher = data.getTeacherByFirstLast(name, loginId)
+ if (teacher.type == 0)
+ teacher.type = Teacher.TYPE_OTHER
+ return teacher
+ }
+
fun getSubjectId(json: JsonObject?, key: String): Long? {
val subject = json.getJsonObject(key)
val subjectId = subject.getLong("Id") ?: return null
@@ -89,42 +113,32 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
}
fun getTeamId(json: JsonObject?, key: String): Long? {
- val team = json.getJsonObject(key)
- val teamId = team.getLong("Id") ?: return null
- if (data.teamList[teamId] == null) {
- var name = team.getString("Shortcut")
- ?: team.getString("Name")
- ?: ""
- name = "${profile?.studentClassName ?: ""} $name"
- data.teamList[teamId] = Team(
- data.profileId,
- teamId,
- name,
- Team.TYPE_VIRTUAL,
- "${data.schoolCode}:$name",
- -1
- )
- }
- return teamId
+ val team = json.getJsonObject(key) ?: return null
+ val teamId = team.getLong("Id")
+ var teamName = team.getString("Shortcut")
+ ?: team.getString("Name")
+ ?: ""
+ teamName = "${profile?.studentClassName ?: ""} $teamName"
+ return data.getTeam(
+ id = teamId,
+ name = teamName,
+ schoolCode = data.schoolCode ?: "",
+ isTeamClass = false,
+ ).id
}
fun getClassId(json: JsonObject?, key: String): Long? {
- val team = json.getJsonObject(key)
- val teamId = team.getLong("Id") ?: return null
- if (data.teamList[teamId] == null) {
- val name = data.profile?.studentClassName
- ?: team.getString("Name")
- ?: ""
- data.teamList[teamId] = Team(
- data.profileId,
- teamId,
- name,
- Team.TYPE_CLASS,
- "${data.schoolCode}:$name",
- -1
- )
- }
- return teamId
+ val team = json.getJsonObject(key) ?: return null
+ val teamId = team.getLong("Id")
+ val teamName = data.profile?.studentClassName
+ ?: team.getString("Name")
+ ?: ""
+ return data.getTeam(
+ id = teamId,
+ name = teamName,
+ schoolCode = data.schoolCode ?: "",
+ isTeamClass = true,
+ ).id
}
fun getLessonRange(json: JsonObject?, key: String): LessonRange? {
@@ -158,7 +172,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
fun isCurrentYear(dateTime: Long): Boolean {
return profile?.let { profile ->
- return@let dateTime >= profile.dateSemester1Start.inMillis
+ return@let dateTime >= profile.dateSemester1Start.inMillis - WEEK * MS
} ?: false
}
@@ -365,6 +379,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
dateTo: Date? = null,
lastSync: Long? = null,
folder: Int? = null,
+ messageBox: String? = null,
params: Map = mapOf(),
includeFilterType: Boolean = true,
onSuccess: (data: List, response: Response?) -> Unit
@@ -388,6 +403,9 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
query["periodId"] = data.studentSemesterId.toString()
query["pupilId"] = data.studentId.toString()
}
+ HebeFilterType.BY_MESSAGEBOX -> {
+ query["box"] = messageBox ?: data.messageBoxKey ?: ""
+ }
}
if (dateFrom != null)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanWebMain.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanWebMain.kt
index d32161a6..e1cc52e6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanWebMain.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanWebMain.kt
@@ -11,11 +11,11 @@ import im.wangchao.mhttp.Request
import im.wangchao.mhttp.Response
import im.wangchao.mhttp.callback.TextCallbackHandler
import pl.droidsonroids.jspoon.Jspoon
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.CufsCertificate
import pl.szczodrzynski.edziennik.data.api.models.ApiError
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
import java.io.File
@@ -137,15 +137,50 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
}
}
+ val schoolSymbols = mutableListOf()
+ val clientUrl = "://uonetplus-uczen.${data.webHost}/$symbol/"
+ var clientIndex = text.indexOf(clientUrl)
+ var count = 0
+ while (clientIndex != -1 && count < 100) {
+ val startIndex = clientIndex + clientUrl.length
+ val endIndex = text.indexOfAny(charArrayOf('"', '/'), startIndex = startIndex)
+ val schoolSymbol = text.substring(startIndex, endIndex)
+ schoolSymbols += schoolSymbol
+ clientIndex = text.indexOf(clientUrl, startIndex = endIndex)
+ count++
+ }
+ schoolSymbols.removeAll {
+ it.lowercase() == "default"
+ || !it.matches(Regexes.VULCAN_WEB_SYMBOL_VALIDATE)
+ }
+
+ if (postErrors && schoolSymbols.isEmpty()) {
+ data.error(ApiError(TAG, ERROR_VULCAN_WEB_NO_SCHOOLS)
+ .withResponse(response)
+ .withApiResponse(text))
+ return
+ }
+
data.webPermissions = data.webPermissions.toMutableMap().also { map ->
val permissions = Regexes.VULCAN_WEB_PERMISSIONS.find(text)?.let { it[1] }
if (permissions?.isNotBlank() == true) {
- val studentId = permissions.split("|")
+ val json = permissions.split("|")
.getOrNull(0)
?.base64DecodeToString()
?.toJsonObject()
+ val unitIds = json
+ ?.getJsonArray("Units")
+ ?.asJsonObjectList()
+ ?.filter { unit ->
+ unit.getString("Symbol") in schoolSymbols
+ }
+ ?.mapNotNull { it.getInt("Id") } ?: emptyList()
+ val studentId = json
?.getJsonArray("AuthInfos")
?.asJsonObjectList()
+ ?.filter { authInfo ->
+ authInfo.getInt("JednostkaSprawozdawczaId") in unitIds
+ }
?.flatMap { authInfo ->
authInfo.getJsonArray("UczenIds")
?.map { it.asInt }
@@ -162,30 +197,6 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
map[symbol] = permissions
}
- val schoolSymbols = mutableListOf()
- val clientUrl = "://uonetplus-uczen.${data.webHost}/$symbol/"
- var clientIndex = text.indexOf(clientUrl)
- var count = 0
- while (clientIndex != -1 && count < 100) {
- val startIndex = clientIndex + clientUrl.length
- val endIndex = text.indexOfAny(charArrayOf('"', '/'), startIndex = startIndex)
- val schoolSymbol = text.substring(startIndex, endIndex)
- schoolSymbols += schoolSymbol
- clientIndex = text.indexOf(clientUrl, startIndex = endIndex)
- count++
- }
- schoolSymbols.removeAll {
- it.toLowerCase() == "default"
- || !it.matches(Regexes.VULCAN_WEB_SYMBOL_VALIDATE)
- }
-
- if (postErrors && schoolSymbols.isEmpty()) {
- data.error(ApiError(TAG, ERROR_VULCAN_WEB_NO_SCHOOLS)
- .withResponse(response)
- .withApiResponse(text))
- return
- }
-
onSuccess(text, schoolSymbols)
}
@@ -280,7 +291,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
return
try {
- val json = JsonParser().parse(text).asJsonObject
+ val json = JsonParser.parseString(text).asJsonObject
onSuccess(json, response)
} catch (e: Exception) {
data.error(ApiError(tag, EXCEPTION_VULCAN_WEB_REQUEST)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
index a4ea84b1..bd8b58e5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
@@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
enum class HebeFilterType(val endpoint: String) {
+ BY_MESSAGEBOX("byBox"),
BY_PUPIL("byPupil"),
BY_PERSON("byPerson"),
BY_PERIOD("byPeriod")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
index 5069838e..d7bec22b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
@@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
import androidx.core.util.set
+import androidx.room.OnConflictStrategy
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_ADDRESSBOOK
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
@@ -17,7 +18,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENT
import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENTS_COUNCIL
import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_STUDENT
import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_TEACHER
-import kotlin.text.replace
+import pl.szczodrzynski.edziennik.ext.*
class VulcanHebeAddressbook(
override val data: DataVulcan,
@@ -44,7 +45,6 @@ class VulcanHebeAddressbook(
) { list, _ ->
list.forEach { person ->
val id = person.getString("Id") ?: return@forEach
- val loginId = person.getString("LoginId") ?: return@forEach
val idType = id.split("-")
.getOrNull(0)
@@ -69,7 +69,7 @@ class VulcanHebeAddressbook(
idLong,
name,
surname,
- loginId
+ null
).also {
data.teacherList[idLong] = it
}
@@ -108,13 +108,14 @@ class VulcanHebeAddressbook(
}
teacher.setTeacherType(personType)
- teacher.typeDescription = roleText
+ if (roleText != null)
+ teacher.typeDescription = roleText
}
if (teacher.type == 0)
teacher.setTeacherType(typeBase)
}
-
+ data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK, 2 * DAY)
onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt
new file mode 100644
index 00000000..2ac843a2
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-2-21.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+
+import androidx.room.OnConflictStrategy
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_OTHER
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENT
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_STUDENT
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_TEACHER
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.MINUTE
+import pl.szczodrzynski.edziennik.ext.getString
+
+class VulcanHebeAddressbook2(
+ override val data: DataVulcan,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit
+) : VulcanHebe(data, lastSync) {
+ companion object {
+ const val TAG = "VulcanHebeAddressbook2"
+ }
+
+ init { let {
+ if (data.messageBoxKey == null) {
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2, 30 * MINUTE)
+ onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2)
+ return@let
+ }
+
+ apiGetList(
+ TAG,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK,
+ HebeFilterType.BY_MESSAGEBOX,
+ messageBox = data.messageBoxKey,
+ lastSync = lastSync,
+ includeFilterType = false
+ ) { list, _ ->
+ list.forEach { person ->
+ val teacher = getTeacherRecipient(person) ?: return@forEach
+ val group = person.getString("Group", "P")
+ if (teacher.type == TYPE_OTHER) {
+ teacher.type = when (group) {
+ "P" -> TYPE_TEACHER // Pracownik
+ "O" -> TYPE_PARENT // Opiekun
+ "U" -> TYPE_STUDENT // Uczeń
+ else -> TYPE_OTHER
+ }
+ }
+ }
+ data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2, 2 * DAY)
+ onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2)
+ }
+ }}
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAttendance.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAttendance.kt
index 9e41bb6d..9f3dcaea 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAttendance.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAttendance.kt
@@ -13,6 +13,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
class VulcanHebeAttendance(
override val data: DataVulcan,
@@ -38,7 +39,7 @@ class VulcanHebeAttendance(
lastSync = lastSync
) { list, _ ->
list.forEach { attendance ->
- val id = attendance.getLong("AuxPresenceId") ?: return@forEach
+ val id = attendance.getLong("Id") ?: return@forEach
val type = attendance.getJsonObject("PresenceType") ?: return@forEach
val baseType = getBaseType(type)
val typeName = type.getString("Name") ?: return@forEach
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeExams.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeExams.kt
index 64b52e2b..308a3e26 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeExams.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeExams.kt
@@ -12,6 +12,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
class VulcanHebeExams(
override val data: DataVulcan,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGradeSummary.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGradeSummary.kt
index e38ac393..390b0383 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGradeSummary.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGradeSummary.kt
@@ -4,14 +4,14 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils
class VulcanHebeGradeSummary(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGrades.kt
index 9c0591de..f345b9e5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGrades.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeGrades.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Grade
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import java.text.DecimalFormat
import kotlin.math.roundToInt
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeHomework.kt
index cb792e2c..06eea284 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeHomework.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeHomework.kt
@@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
-import pl.szczodrzynski.edziennik.asJsonObjectList
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_HOMEWORK
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_HOMEWORK
@@ -12,9 +11,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getJsonArray
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.asJsonObjectList
+import pl.szczodrzynski.edziennik.ext.getJsonArray
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils
class VulcanHebeHomework(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeLuckyNumber.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeLuckyNumber.kt
index 8ff1631b..bfa07399 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeLuckyNumber.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeLuckyNumber.kt
@@ -12,8 +12,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getInt
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMain.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMain.kt
index c017e3c9..ea093d14 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMain.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMain.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MAIN
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.models.Date
class VulcanHebeMain(
@@ -97,6 +98,10 @@ class VulcanHebeMain(
val studentSemesterId = period.getInt("Id") ?: return@forEach
val studentSemesterNumber = period.getInt("Number") ?: return@forEach
+ val senderEntry = student.getJsonObject("SenderEntry")
+ val senderAddressName = senderEntry.getString("Address")
+ val senderAddressHash = senderEntry.getString("AddressHash")
+
val hebeContext = student.getString("Context")
val isParent = login.getString("LoginRole").equals("opiekun", ignoreCase = true)
@@ -143,7 +148,18 @@ class VulcanHebeMain(
studentData["schoolSymbol"] = schoolSymbol
studentData["schoolShort"] = schoolShort
studentData["schoolName"] = schoolCode
+ studentData["senderAddressName"] = senderAddressName
+ studentData["senderAddressHash"] = senderAddressHash
studentData["hebeContext"] = hebeContext
+
+ // create the default TeamClass
+ data.getTeam(
+ id = null,
+ name = studentClassName,
+ schoolCode = schoolCode,
+ isTeamClass = true,
+ profileId = this.id,
+ )
}
dateSemester1Start?.let {
newProfile.dateSemester1Start = it
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt
new file mode 100644
index 00000000..df6613ba
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-9-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getString
+
+class VulcanHebeMessageBoxes(
+ override val data: DataVulcan,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit
+) : VulcanHebe(data, lastSync) {
+ companion object {
+ const val TAG = "VulcanHebeMessageBoxes"
+ }
+
+ init {
+ apiGetList(
+ TAG,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX,
+ lastSync = lastSync
+ ) { list, _ ->
+ var found = false
+ for (messageBox in list) {
+ val name = messageBox.getString("Name") ?: continue
+ val studentName = profile?.studentNameLong ?: continue
+ if (!name.contains(studentName))
+ continue
+
+ data.messageBoxKey = messageBox.getString("GlobalKey")
+ data.messageBoxName = name
+ found = true
+ break
+ }
+ if (!found && list.isNotEmpty()) {
+ list.firstOrNull()?.let { messageBox ->
+ data.messageBoxKey = messageBox.getString("GlobalKey")
+ data.messageBoxName = messageBox.getString("Name")
+ }
+ }
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES, 7 * DAY)
+ onSuccess(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
index eb4091e0..affca1e1 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
@@ -4,22 +4,21 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
-import androidx.core.util.set
-import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_SENT
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
-import pl.szczodrzynski.edziennik.data.db.entity.*
+import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
+import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
+import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
-import pl.szczodrzynski.navlib.crc16
-import kotlin.text.replace
class VulcanHebeMessages(
override val data: DataVulcan,
@@ -27,29 +26,7 @@ class VulcanHebeMessages(
val onSuccess: (endpointId: Int) -> Unit
) : VulcanHebe(data, lastSync) {
companion object {
- const val TAG = "VulcanHebeMessagesInbox"
- }
-
- private fun getPersonId(json: JsonObject): Long {
- val senderLoginId = json.getInt("LoginId") ?: return -1
- /*if (senderLoginId == data.studentLoginId)
- return -1*/
-
- val senderName = json.getString("Address") ?: return -1
- val senderNameSplit = senderName.splitName()
- val senderLoginIdStr = senderLoginId.toString()
- val teacher = data.teacherList.singleOrNull { it.loginId == senderLoginIdStr }
- ?: Teacher(
- profileId,
- -1 * crc16(senderName).toLong(),
- senderNameSplit?.second ?: "",
- senderNameSplit?.first ?: "",
- senderLoginIdStr
- ).also {
- it.setTeacherType(Teacher.TYPE_OTHER)
- data.teacherList[it.id] = it
- }
- return teacher.id
+ const val TAG = "VulcanHebeMessages"
}
fun getMessages(messageType: Int) {
@@ -64,17 +41,28 @@ class VulcanHebeMessages(
TYPE_SENT -> ENDPOINT_VULCAN_HEBE_MESSAGES_SENT
else -> ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX
}
+
+ val messageBox = data.messageBoxKey
+ if (messageBox == null) {
+ onSuccess(endpointId)
+ return
+ }
+
apiGetList(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES,
- HebeFilterType.BY_PERSON,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES,
+ HebeFilterType.BY_MESSAGEBOX,
+ messageBox = data.messageBoxKey,
folder = folder,
lastSync = lastSync
) { list, _ ->
list.forEach { message ->
- val id = message.getLong("Id") ?: return@forEach
+ val uuid = message.getString("Id") ?: return@forEach
+ val id = Utils.crc32(uuid.toByteArray())
+ val globalKey = message.getString("GlobalKey", "")
+ val threadKey = message.getString("ThreadKey", "")
val subject = message.getString("Subject") ?: return@forEach
- val body = message.getString("Content") ?: return@forEach
+ var body = message.getString("Content") ?: return@forEach
val sender = message.getJsonObject("Sender") ?: return@forEach
@@ -83,27 +71,45 @@ class VulcanHebeMessages(
if (!isCurrentYear(sentDate)) return@forEach
+ val senderId = if (messageType == TYPE_RECEIVED)
+ getTeacherRecipient(sender)?.id
+ else
+ null
+
+ val meta = mutableMapOf(
+ "uuid" to uuid,
+ "globalKey" to globalKey,
+ "threadKey" to threadKey,
+ )
+ val metaString = meta.map { "${it.key}=${it.value}" }.join("&")
+ body = "[META:${metaString}]" + body
+ body = body.replace("\n", "
")
+
val messageObject = Message(
profileId = profileId,
id = id,
type = messageType,
subject = subject,
- body = body.replace("\n", "
"),
- senderId = if (messageType == TYPE_RECEIVED) getPersonId(sender) else null,
+ body = body,
+ senderId = senderId,
addedDate = sentDate
)
val receivers = message.getJsonArray("Receiver")
?.asJsonObjectList()
?: return@forEach
- val receiverReadDate =
- if (receivers.size == 1) readDate
- else -1
for (receiver in receivers) {
+ val recipientId = if (messageType == TYPE_SENT)
+ getTeacherRecipient(receiver)?.id ?: -1
+ else
+ -1
+
+ val receiverReadDate = receiver.getLong("HasRead", -1)
+
val messageRecipientObject = MessageRecipient(
profileId,
- if (messageType == TYPE_SENT) getPersonId(receiver) else -1,
+ recipientId,
-1,
receiverReadDate,
id
@@ -115,6 +121,9 @@ class VulcanHebeMessages(
?.asJsonObjectList()
?: return@forEach
+ messageObject.attachmentIds = mutableListOf()
+ messageObject.attachmentNames = mutableListOf()
+ messageObject.attachmentSizes = mutableListOf()
for (attachment in attachments) {
val fileName = attachment.getString("Name") ?: continue
val url = attachment.getString("Link") ?: continue
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
index ff5dbe4c..2144a768 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
@@ -5,15 +5,14 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.JsonObject
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
-import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
+import pl.szczodrzynski.edziennik.ext.JsonObject
class VulcanHebeMessagesChangeStatus(
override val data: DataVulcan,
@@ -24,13 +23,19 @@ class VulcanHebeMessagesChangeStatus(
const val TAG = "VulcanHebeMessagesChangeStatus"
}
- init {
+ init { let {
+ val messageKey = messageObject.body?.let { data.parseMessageMeta(it) }?.get("uuid") ?: run {
+ EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
+ onSuccess()
+ return@let
+ }
+
apiPost(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS,
payload = JsonObject(
- "MessageId" to messageObject.id,
- "LoginId" to data.studentLoginId,
+ "BoxKey" to data.messageBoxKey,
+ "MessageKey" to messageKey,
"Status" to 1
)
) { _: Boolean, _ ->
@@ -48,7 +53,7 @@ class VulcanHebeMessagesChangeStatus(
messageObject.seen = true
}
- if (messageObject.type != Message.TYPE_SENT) {
+ if (!messageObject.isSent) {
val messageRecipientObject = MessageRecipient(
profileId,
-1,
@@ -62,5 +67,5 @@ class VulcanHebeMessagesChangeStatus(
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
onSuccess()
}
- }
+ }}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeNotices.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeNotices.kt
index 5b67b272..be1e0545 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeNotices.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeNotices.kt
@@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Notice
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.*
class VulcanHebeNotices(
override val data: DataVulcan,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
index 8f5f5afa..5e607caa 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
@@ -4,16 +4,20 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+import com.google.gson.JsonArray
import com.google.gson.JsonObject
import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.*
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_SEND
+import pl.szczodrzynski.edziennik.data.api.ERROR_MESSAGE_NOT_SENT
+import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
import pl.szczodrzynski.edziennik.data.db.entity.Message
-import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.ext.*
+import java.util.UUID
class VulcanHebeSendMessage(
override val data: DataVulcan,
@@ -27,51 +31,84 @@ class VulcanHebeSendMessage(
}
init {
+ if (data.messageBoxKey == null || data.messageBoxName == null) {
+ VulcanHebeMessageBoxes(data, 0) {
+ if (data.messageBoxKey == null || data.messageBoxName == null) {
+ data.error(TAG, ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY)
+ }
+ else {
+ sendMessage()
+ }
+ }
+ }
+ else {
+ sendMessage()
+ }
+ }
+
+ private fun sendMessage() {
+ val uuid = UUID.randomUUID().toString()
+ val globalKey = UUID.randomUUID().toString()
+ val partition = "${data.symbol}-${data.schoolSymbol}"
+
val recipientsArray = JsonArray()
recipients.forEach { teacher ->
+ val loginId = teacher.loginId?.split(";", limit = 3) ?: return@forEach
+ val key = loginId.getOrNull(0) ?: teacher.loginId
+ val group = loginId.getOrNull(1)
+ val name = loginId.getOrNull(2)
+ if (key?.toIntOrNull() != null) {
+ // raise error for old-format (non-UUID) login IDs
+ data.error(TAG, ERROR_MESSAGE_NOT_SENT)
+ return
+ }
recipientsArray += JsonObject(
- "Address" to teacher.fullNameLastFirst,
- "LoginId" to (teacher.loginId?.toIntOrNull() ?: return@forEach),
- "Initials" to teacher.initialsLastFirst,
- "AddressHash" to teacher.fullNameLastFirst.sha1Hex()
+ "Id" to "${data.messageBoxKey}-${key}",
+ "Partition" to partition,
+ "Owner" to data.messageBoxKey,
+ "GlobalKey" to key,
+ "Name" to name,
+ "Group" to group,
+ "Initials" to "",
+ "HasRead" to 0,
)
}
- val senderName = (profile?.accountName ?: profile?.studentNameLong)
- ?.swapFirstLastName() ?: ""
val sender = JsonObject(
- "Address" to senderName,
- "LoginId" to data.studentLoginId.toString(),
- "Initials" to senderName.getNameInitials(),
- "AddressHash" to senderName.sha1Hex()
+ "Id" to "0",
+ "Partition" to partition,
+ "Owner" to data.messageBoxKey,
+ "GlobalKey" to data.messageBoxKey,
+ "Name" to data.messageBoxName,
+ "Group" to "",
+ "Initials" to "",
+ "HasRead" to 0,
)
apiPost(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES_SEND,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND,
payload = JsonObject(
- "Status" to 1,
- "Sender" to sender,
- "DateSent" to null,
- "DateRead" to null,
- "Content" to text,
- "Receiver" to recipientsArray,
- "Id" to 0,
+ "Id" to uuid,
+ "GlobalKey" to globalKey,
+ "Partition" to partition,
+ "ThreadKey" to globalKey, // TODO correct threadKey for reply messages
"Subject" to subject,
- "Attachments" to null,
- "Self" to null
+ "Content" to text,
+ "Status" to 1,
+ "Owner" to data.messageBoxKey,
+ "DateSent" to buildDateTime(),
+ "DateRead" to null,
+ "Sender" to sender,
+ "Receiver" to recipientsArray,
+ "Attachments" to JsonArray(),
)
- ) { json: JsonObject, _ ->
- val messageId = json.getLong("Id")
-
- if (messageId == null) {
- // TODO error
- return@apiPost
- }
+ ) { _: JsonObject, _ ->
+ // TODO handle errors
VulcanHebeMessages(data, null) {
- val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
- val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
+ val message = data.messageList.firstOrNull { it.isSent && it.subject == subject }
+ // val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
EventBus.getDefault().postSticky(event)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt
new file mode 100644
index 00000000..7be65e34
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) Antoni Czaplicki 2021-10-15.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+
+import androidx.room.OnConflictStrategy
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_TEACHERS
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_TEACHERS
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getString
+
+class VulcanHebeTeachers(
+ override val data: DataVulcan,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit,
+) : VulcanHebe(data, lastSync) {
+ companion object {
+ const val TAG = "VulcanHebeTeachers"
+ }
+
+ init {
+ apiGetList(
+ TAG,
+ VULCAN_HEBE_ENDPOINT_TEACHERS,
+ HebeFilterType.BY_PERIOD,
+ lastSync = 0L,
+ ) { list, _ ->
+ list.forEach { person ->
+ val name = person.getString("Name")
+ val surname = person.getString("Surname")
+ val displayName = person.getString("DisplayName")
+ val subjectName = person.getString("Description") ?: return@forEach
+
+ if (subjectName.isBlank()) {
+ return@forEach
+ }
+
+ val teacher = data.getTeacherByFirstLast(
+ name?.plus(" ")?.plus(surname) ?: displayName ?: return@forEach
+ )
+
+ when (subjectName) {
+ "Pedagog" -> teacher.setTeacherType(Teacher.TYPE_PEDAGOGUE)
+ "Dyrektor" -> teacher.setTeacherType(Teacher.TYPE_PRINCIPAL)
+ else -> {
+ val subjectId = data.getSubject(null, subjectName).id
+ if (!teacher.subjects.contains(subjectId))
+ teacher.addSubject(subjectId)
+ }
+ }
+ }
+ data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_TEACHERS, 2 * DAY)
+ onSuccess(ENDPOINT_VULCAN_HEBE_TEACHERS)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTimetable.kt
index 03a28a9e..c20cf1bf 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTimetable.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTimetable.kt
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_TIMETABLE_CHANGE
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_TIMETABLE
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_CANCELLED
import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_CHANGE
@@ -19,6 +20,10 @@ import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_SHIFTED_S
import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_SHIFTED_TARGET
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
+import pl.szczodrzynski.edziennik.ext.getBoolean
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week
@@ -47,7 +52,7 @@ class VulcanHebeTimetable(
?: previousWeekStart
val dateTo = dateFrom.clone().stepForward(0, 0, 13)
- val lastSync = null
+ val lastSync = 0L
apiGetList(
TAG,
@@ -106,6 +111,8 @@ class VulcanHebeTimetable(
"Clearing lessons between ${dateFrom.stringY_m_d} and ${dateTo.stringY_m_d}"
)
+ data.toRemove.add(DataRemoveModel.Timetable.between(dateFrom, dateTo))
+
data.lessonList.addAll(lessonList)
data.setSyncNext(ENDPOINT_VULCAN_HEBE_TIMETABLE, SYNC_ALWAYS)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/web/VulcanWebLuckyNumber.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/web/VulcanWebLuckyNumber.kt
index cbf24c2a..adb4363d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/web/VulcanWebLuckyNumber.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/web/VulcanWebLuckyNumber.kt
@@ -4,7 +4,6 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.web
-import pl.szczodrzynski.edziennik.DAY
import pl.szczodrzynski.edziennik.data.api.VULCAN_WEB_ENDPOINT_LUCKY_NUMBER
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS
@@ -12,7 +11,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanWebMain
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
-import pl.szczodrzynski.edziennik.getJsonArray
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getJsonArray
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week
@@ -62,12 +62,12 @@ class VulcanWebLuckyNumber(override val data: DataVulcan,
profile?.empty ?: false
))
}
- } ?: {
+ } ?: run {
// no lucky number
if (Date.getToday().weekDay <= Week.FRIDAY && Time.getNow().hour >= 22) {
// working days, after 10PM
// consider the lucky number is disabled; sync in 4 days
- nextSync = System.currentTimeMillis() + 4*DAY*1000
+ nextSync = System.currentTimeMillis() + 4* DAY *1000
}
else if (Date.getToday().weekDay <= Week.FRIDAY && Time.getNow().hour < 22) {
// working days, before 10PM
@@ -77,7 +77,7 @@ class VulcanWebLuckyNumber(override val data: DataVulcan,
// weekends
nextSync = Week.getNearestWeekDayDate(Week.MONDAY).combineWith(Time(5, 0, 0))
}
- }()
+ }
data.setSyncNext(ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS, SYNC_ALWAYS)
onSuccess(ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/firstlogin/VulcanFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/firstlogin/VulcanFirstLogin.kt
index 2bf633f8..61502488 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/firstlogin/VulcanFirstLogin.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/firstlogin/VulcanFirstLogin.kt
@@ -17,6 +17,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWeb
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.getJsonObject
+import pl.szczodrzynski.edziennik.ext.getString
class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginHebe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginHebe.kt
index ded6e937..241f249a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginHebe.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginHebe.kt
@@ -6,7 +6,6 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
import com.google.gson.JsonObject
import io.github.wulkanowy.signer.hebe.generateKeyPair
-import pl.szczodrzynski.edziennik.JsonObject
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_DEVICE_NAME
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_REGISTER_NEW
@@ -14,8 +13,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
-import pl.szczodrzynski.edziennik.getString
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.JsonObject
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
class VulcanLoginHebe(val data: DataVulcan, val onSuccess: () -> Unit) {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginWebMain.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginWebMain.kt
index 2b62eb14..3160ceb2 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginWebMain.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/login/VulcanLoginWebMain.kt
@@ -9,8 +9,8 @@ import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanWebMain
import pl.szczodrzynski.edziennik.data.api.models.ApiError
-import pl.szczodrzynski.edziennik.getString
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.getString
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.fslogin.FSLogin
import pl.szczodrzynski.fslogin.realm.toRealm
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt
index fe66c4b3..2a3531df 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/RegisterAvailabilityEvent.kt
@@ -4,8 +4,4 @@
package pl.szczodrzynski.edziennik.data.api.events
-import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
-
-data class RegisterAvailabilityEvent(
- val data: Map< String, RegisterAvailabilityStatus>
-)
+class RegisterAvailabilityEvent()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt
index d88fa652..3995842a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt
@@ -4,13 +4,16 @@
package pl.szczodrzynski.edziennik.data.api.events
-data class UserActionRequiredEvent(val profileId: Int, val type: Int) {
- companion object {
- const val LOGIN_DATA_MOBIDZIENNIK = 101
- const val LOGIN_DATA_LIBRUS = 102
- const val LOGIN_DATA_IDZIENNIK = 103
- const val LOGIN_DATA_VULCAN = 104
- const val LOGIN_DATA_EDUDZIENNIK = 105
- const val CAPTCHA_LIBRUS = 202
+import android.os.Bundle
+
+data class UserActionRequiredEvent(
+ val profileId: Int?,
+ val type: Type,
+ val params: Bundle,
+ val errorText: Int,
+) {
+ enum class Type {
+ RECAPTCHA,
+ OAUTH,
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/interfaces/EdziennikCallback.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/interfaces/EdziennikCallback.kt
index c1c878b4..4943ff1e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/interfaces/EdziennikCallback.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/interfaces/EdziennikCallback.kt
@@ -4,6 +4,7 @@
package pl.szczodrzynski.edziennik.data.api.interfaces
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
import pl.szczodrzynski.edziennik.data.api.models.Feature
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
@@ -14,4 +15,5 @@ import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
*/
interface EdziennikCallback : EndpointCallback {
fun onCompleted()
+ fun onRequiresUserAction(event: UserActionRequiredEvent)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/ApiError.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/ApiError.kt
index d99e16a2..b631ed7d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/ApiError.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/ApiError.kt
@@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.models
import android.content.Context
+import android.os.Bundle
import com.google.gson.JsonObject
import im.wangchao.mhttp.Request
import im.wangchao.mhttp.Response
@@ -13,8 +14,8 @@ import pl.szczodrzynski.edziennik.data.api.ERROR_API_EXCEPTION
import pl.szczodrzynski.edziennik.data.api.ERROR_EXCEPTION
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApiException
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ErrorReportRequest
-import pl.szczodrzynski.edziennik.stackTraceString
-import pl.szczodrzynski.edziennik.toErrorCode
+import pl.szczodrzynski.edziennik.ext.stackTraceString
+import pl.szczodrzynski.edziennik.ext.toErrorCode
class ApiError(val tag: String, var errorCode: Int) {
companion object {
@@ -30,6 +31,7 @@ class ApiError(val tag: String, var errorCode: Int) {
var request: Request? = null
var response: Response? = null
var isCritical = true
+ var params: Bundle? = null
fun withThrowable(throwable: Throwable?): ApiError {
this.throwable = throwable
@@ -58,6 +60,11 @@ class ApiError(val tag: String, var errorCode: Int) {
return this
}
+ fun withParams(bundle: Bundle): ApiError {
+ this.params = bundle
+ return this
+ }
+
fun getStringText(context: Context): String {
return context.resources.getIdentifier("error_${errorCode}", "string", context.packageName).let {
if (it != 0)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt
index 8dda9543..9b7137fc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt
@@ -1,16 +1,23 @@
package pl.szczodrzynski.edziennik.data.api.models
+import android.os.Bundle
import android.util.LongSparseArray
import android.util.SparseArray
+import androidx.core.util.set
import androidx.core.util.size
import androidx.room.OnConflictStrategy
import com.google.gson.JsonObject
import im.wangchao.mhttp.Response
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.BuildConfig
+import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
-import pl.szczodrzynski.edziennik.data.api.interfaces.EndpointCallback
+import pl.szczodrzynski.edziennik.data.api.Regexes.MESSAGE_META
+import pl.szczodrzynski.edziennik.data.api.events.UserActionRequiredEvent
+import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.*
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date
@@ -32,7 +39,7 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
/**
* A callback passed to all [Feature]s and [LoginMethod]s
*/
- lateinit var callback: EndpointCallback
+ lateinit var callback: EdziennikCallback
/**
* A list of [LoginMethod]s *already fulfilled* during this sync.
@@ -369,6 +376,15 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
callback.onError(apiError)
}
+ fun requireUserAction(type: UserActionRequiredEvent.Type, params: Bundle, errorText: Int) {
+ callback.onRequiresUserAction(UserActionRequiredEvent(
+ profileId = profile?.id,
+ type = type,
+ params = params,
+ errorText = errorText,
+ ))
+ }
+
fun progress(step: Float) {
callback.onProgress(step)
}
@@ -376,4 +392,134 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
fun startProgress(stringRes: Int) {
callback.onStartProgress(stringRes)
}
+
+ /* _ _ _ _ _
+ | | | | | (_) |
+ | | | | |_ _| |___
+ | | | | __| | / __|
+ | |__| | |_| | \__ \
+ \____/ \__|_|_|__*/
+ fun getSubject(id: Long?, name: String, shortName: String = name): Subject {
+ var subject = subjectList.singleOrNull { it.id == id }
+ if (subject == null)
+ subject = subjectList.singleOrNull { it.longName == name }
+ if (subject == null)
+ subject = subjectList.singleOrNull { it.shortName == name }
+
+ if (subject == null) {
+ subject = Subject(
+ profileId,
+ id ?: name.crc32(),
+ name,
+ shortName
+ )
+ subjectList[subject.id] = subject
+ }
+ return subject
+ }
+
+ fun getTeam(
+ id: Long?,
+ name: String,
+ schoolCode: String,
+ isTeamClass: Boolean = false,
+ profileId: Int? = null,
+ ): Team {
+ if (isTeamClass && teamClass != null)
+ return teamClass as Team
+ var team = teamList.singleOrNull { it.id == id }
+
+ val namePlain = name.replace(" ", "")
+ if (team == null)
+ team = teamList.singleOrNull { it.name.replace(" ", "") == namePlain }
+
+ if (team == null) {
+ team = Team(
+ profileId ?: this.profileId,
+ id ?: name.crc32(),
+ name,
+ if (isTeamClass) Team.TYPE_CLASS else Team.TYPE_VIRTUAL,
+ "$schoolCode:$name",
+ -1
+ )
+ teamList[team.id] = team
+ } else if (id != null) {
+ team.id = id
+ }
+ return team
+ }
+
+ fun getTeacher(firstName: String, lastName: String, loginId: String? = null, id: Long? = null): Teacher {
+ val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" }
+ return validateTeacher(teacher, firstName, lastName, loginId, id)
+ }
+
+ fun getTeacher(firstNameChar: Char, lastName: String, loginId: String? = null): Teacher {
+ val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" }
+ return validateTeacher(teacher, firstNameChar.toString(), lastName, loginId, null)
+ }
+
+ fun getTeacherByLastFirst(nameLastFirst: String, loginId: String? = null): Teacher {
+ // comparing full name is safer than splitting and swapping
+ val teacher = teacherList.singleOrNull { it.fullNameLastFirst == nameLastFirst }
+ val nameParts = nameLastFirst.split(" ", limit = 2)
+ return if (nameParts.size == 1)
+ validateTeacher(teacher, nameParts[0], "", loginId, null)
+ else
+ validateTeacher(teacher, nameParts[1], nameParts[0], loginId, null)
+ }
+
+ fun getTeacherByFirstLast(nameFirstLast: String, loginId: String? = null): Teacher {
+ // comparing full name is safer than splitting and swapping
+ val teacher = teacherList.singleOrNull { it.fullName == nameFirstLast }
+ val nameParts = nameFirstLast.split(" ", limit = 2)
+ return if (nameParts.size == 1)
+ validateTeacher(teacher, nameParts[0], "", loginId, null)
+ else
+ validateTeacher(teacher, nameParts[0], nameParts[1], loginId, null)
+ }
+
+ fun getTeacherByFDotLast(nameFDotLast: String, loginId: String? = null): Teacher {
+ val nameParts = nameFDotLast.split(".")
+ return if (nameParts.size == 1)
+ getTeacher(nameParts[0], "", loginId)
+ else
+ getTeacher(nameParts[0][0], nameParts[1], loginId)
+ }
+
+ fun getTeacherByFDotSpaceLast(nameFDotSpaceLast: String, loginId: String? = null): Teacher {
+ val nameParts = nameFDotSpaceLast.split(".")
+ return if (nameParts.size == 1)
+ getTeacher(nameParts[0], "", loginId)
+ else
+ getTeacher(nameParts[0][0], nameParts[1], loginId)
+ }
+
+ private fun validateTeacher(
+ teacher: Teacher?,
+ firstName: String,
+ lastName: String,
+ loginId: String?,
+ id: Long?
+ ): Teacher {
+ val obj = teacher ?: Teacher(profileId, -1, firstName, lastName, loginId).also {
+ it.id = id ?: it.fullName.crc32()
+ teacherList[it.id] = it
+ }
+ return obj.also {
+ if (loginId != null)
+ it.loginId = loginId
+ if (firstName.length > 1)
+ it.name = firstName
+ it.surname = lastName
+ }
+ }
+
+ fun parseMessageMeta(body: String): Map? {
+ val match = MESSAGE_META.find(body) ?: return null
+ return match[1].split("&").associateBy(
+ { it.substringBefore("=") },
+ { it.substringAfter("=") },
+ )
+ }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/DataRemoveModel.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/DataRemoveModel.kt
index 49b57999..73096f28 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/DataRemoveModel.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/DataRemoveModel.kt
@@ -11,19 +11,19 @@ import pl.szczodrzynski.edziennik.data.db.dao.TimetableDao
import pl.szczodrzynski.edziennik.utils.models.Date
open class DataRemoveModel {
- data class Timetable(private val dateFrom: Date?, private val dateTo: Date?) : DataRemoveModel() {
+ data class Timetable(private val dateFrom: Date?, private val dateTo: Date?, private val isExtra: Boolean?) : DataRemoveModel() {
companion object {
- fun from(dateFrom: Date) = Timetable(dateFrom, null)
- fun to(dateTo: Date) = Timetable(null, dateTo)
- fun between(dateFrom: Date, dateTo: Date) = Timetable(dateFrom, dateTo)
+ fun from(dateFrom: Date, isExtra: Boolean? = null) = Timetable(dateFrom, null, isExtra)
+ fun to(dateTo: Date, isExtra: Boolean? = null) = Timetable(null, dateTo, isExtra)
+ fun between(dateFrom: Date, dateTo: Date, isExtra: Boolean? = null) = Timetable(dateFrom, dateTo, isExtra)
}
fun commit(profileId: Int, dao: TimetableDao) {
if (dateFrom != null && dateTo != null) {
- dao.dontKeepBetweenDates(profileId, dateFrom, dateTo)
+ dao.dontKeepBetweenDates(profileId, dateFrom, dateTo, isExtra ?: false)
} else {
- dateFrom?.let { dateFrom -> dao.dontKeepFromDate(profileId, dateFrom) }
- dateTo?.let { dateTo -> dao.dontKeepToDate(profileId, dateTo) }
+ dateFrom?.let { dateFrom -> dao.dontKeepFromDate(profileId, dateFrom, isExtra ?: false) }
+ dateTo?.let { dateTo -> dao.dontKeepToDate(profileId, dateTo, isExtra ?: false) }
}
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt
index 95d61224..a9f6a69f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyApi.kt
@@ -22,18 +22,16 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.ApiCacheIntercept
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.SignatureInterceptor
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
-import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
-import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
-import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
-import pl.szczodrzynski.edziennik.data.api.szkolny.response.WebPushResponse
-import pl.szczodrzynski.edziennik.data.db.entity.Event
-import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
-import pl.szczodrzynski.edziennik.data.db.entity.Notification
-import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.data.api.szkolny.response.*
+import pl.szczodrzynski.edziennik.data.db.entity.*
import pl.szczodrzynski.edziennik.data.db.full.EventFull
-import pl.szczodrzynski.edziennik.ui.modules.error.ErrorDetailsDialog
-import pl.szczodrzynski.edziennik.ui.modules.error.ErrorSnackbar
-import pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo
+import pl.szczodrzynski.edziennik.ext.keys
+import pl.szczodrzynski.edziennik.ext.md5
+import pl.szczodrzynski.edziennik.ext.toApiError
+import pl.szczodrzynski.edziennik.ext.toErrorCode
+import pl.szczodrzynski.edziennik.ui.error.ErrorDetailsDialog
+import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar
+import pl.szczodrzynski.edziennik.ui.login.LoginInfo
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import retrofit2.Response
@@ -103,7 +101,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
activity,
listOf(apiError),
R.string.error_occured
- )
+ ).show()
null
}
null
@@ -126,7 +124,10 @@ class SzkolnyApi(val app: App) : CoroutineScope {
* or null if it's a HTTP call error.
*/
@Throws(Exception::class)
- private inline fun parseResponse(response: Response>): T {
+ private inline fun parseResponse(
+ response: Response>,
+ updateDeviceHash: Boolean = false,
+ ): T {
app.config.update = response.body()?.update?.let { update ->
if (update.versionCode > BuildConfig.VERSION_CODE) {
if (update.updateMandatory
@@ -144,6 +145,14 @@ class SzkolnyApi(val app: App) : CoroutineScope {
}
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) {
return Unit
}
@@ -168,7 +177,6 @@ class SzkolnyApi(val app: App) : CoroutineScope {
throw SzkolnyApiException(body?.errors?.firstOrNull())
}
- @Throws(Exception::class)
private fun getDevice() = run {
val config = app.config
val device = Device(
@@ -181,52 +189,57 @@ class SzkolnyApi(val app: App) : CoroutineScope {
appVersionCode = BuildConfig.VERSION_CODE,
syncInterval = app.config.sync.interval
)
- device.toString().md5().let {
- if (it == config.hash)
- null
- else {
- config.hash = it
- device
- }
- }
+ val hash = device.toString().md5()
+ if (hash == config.hash)
+ return@run null
+ return@run device
}
@Throws(Exception::class)
- fun getEvents(profiles: List, notifications: List, blacklistedIds: List, lastSyncTime: Long): List {
+ fun getEvents(
+ profiles: List,
+ notifications: List,
+ blacklistedIds: List,
+ lastSyncTime: Long,
+ ): Pair, List> {
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(
deviceId = app.deviceId,
device = getDevice(),
userCodes = profiles.map { it.userCode },
- 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 }
- )
- user.toString().md5().let {
- if (it == config.hash)
- null
- else {
- config.hash = it
- user
- }
- }
- },
+ users = users.keys(),
lastSync = lastSyncTime,
notifications = notifications.map { ServerSyncRequest.Notification(it.profileName ?: "", it.type, it.text) }
)).execute()
- val (events, hasBrowsers) = parseResponse(response)
+ val (events, notes, hasBrowsers) = parseResponse(response, updateDeviceHash = true)
hasBrowsers?.let {
app.config.sync.webPushEnabled = it
}
+ // update users' hashes on success
+ users.forEach { (user, config) ->
+ config.hash = user.toString().md5()
+ }
+
val eventList = mutableListOf()
+ val noteList = mutableListOf()
events.forEach { event ->
// skip blacklisted events
@@ -237,9 +250,13 @@ class SzkolnyApi(val app: App) : CoroutineScope {
if (event.color == -1)
event.color = null
+ val eventSharedBy = event.sharedBy
+
// create the event for every matching team and profile
teams.filter { it.code == event.teamCode }.onEach { team ->
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@onEach
+ if (!profile.canShare)
+ return@forEach
eventList += EventFull(event).apply {
profileId = team.profileId
@@ -248,38 +265,106 @@ class SzkolnyApi(val app: App) : CoroutineScope {
seen = profile.empty
notified = profile.empty
- if (profile.userCode == event.sharedBy) sharedBy = "self"
+ if (profile.userCode == event.sharedBy) {
+ sharedBy = "self"
+ addedManually = true
+ } else {
+ sharedBy = eventSharedBy
+ }
}
}
}
- return eventList
+ notes.forEach { note ->
+ val noteSharedBy = note.sharedBy
+
+ // create the note for every matching team and profile
+ teams.filter { it.code == note.teamCode }.onEach { team ->
+ val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@onEach
+ if (!profile.canShare)
+ return@forEach
+ note.profileId = team.profileId
+ if (profile.userCode == note.sharedBy) {
+ note.sharedBy = "self"
+ } else {
+ note.sharedBy = noteSharedBy
+ }
+
+ if (app.noteManager.hasValidOwner(note))
+ noteList += note
+ }
+ }
+ return eventList to noteList
}
@Throws(Exception::class)
fun shareEvent(event: EventFull) {
+ val profile = app.db.profileDao().getByIdNow(event.profileId)
+ ?: throw NullPointerException("Profile is not found")
val team = app.db.teamDao().getByIdNow(event.profileId, event.teamId)
+ ?: throw NullPointerException("Team is not found")
val response = api.shareEvent(EventShareRequest(
- deviceId = app.deviceId,
- device = getDevice(),
- sharedByName = event.sharedByName,
- shareTeamCode = team.code,
- event = event
+ deviceId = app.deviceId,
+ device = getDevice(),
+ userCode = profile.userCode,
+ studentNameLong = profile.studentNameLong,
+ shareTeamCode = team.code,
+ event = event
+ )).execute()
+ parseResponse(response, updateDeviceHash = true)
+ }
+
+ @Throws(Exception::class)
+ fun unshareEvent(event: Event) {
+ val profile = app.db.profileDao().getByIdNow(event.profileId)
+ ?: throw NullPointerException("Profile is not found")
+ val team = app.db.teamDao().getByIdNow(event.profileId, event.teamId)
+ ?: throw NullPointerException("Team is not found")
+
+ val response = api.shareEvent(EventShareRequest(
+ deviceId = app.deviceId,
+ device = getDevice(),
+ userCode = profile.userCode,
+ studentNameLong = profile.studentNameLong,
+ unshareTeamCode = team.code,
+ eventId = event.id
+ )).execute()
+ parseResponse(response, updateDeviceHash = true)
+ }
+
+ @Throws(Exception::class)
+ fun shareNote(note: Note) {
+ val profile = app.db.profileDao().getByIdNow(note.profileId)
+ ?: throw NullPointerException("Profile is not found")
+ val team = app.db.teamDao().getClassNow(note.profileId)
+ ?: throw NullPointerException("TeamClass is not found")
+
+ val response = api.shareNote(NoteShareRequest(
+ deviceId = app.deviceId,
+ device = getDevice(),
+ userCode = profile.userCode,
+ studentNameLong = profile.studentNameLong,
+ shareTeamCode = team.code,
+ note = note,
)).execute()
parseResponse(response)
}
@Throws(Exception::class)
- fun unshareEvent(event: Event) {
- val team = app.db.teamDao().getByIdNow(event.profileId, event.teamId)
+ fun unshareNote(note: Note) {
+ val profile = app.db.profileDao().getByIdNow(note.profileId)
+ ?: throw NullPointerException("Profile is not found")
+ val team = app.db.teamDao().getClassNow(note.profileId)
+ ?: throw NullPointerException("TeamClass is not found")
- val response = api.shareEvent(EventShareRequest(
- deviceId = app.deviceId,
- device = getDevice(),
- sharedByName = event.sharedByName,
- unshareTeamCode = team.code,
- eventId = event.id
+ val response = api.shareNote(NoteShareRequest(
+ deviceId = app.deviceId,
+ device = getDevice(),
+ userCode = profile.userCode,
+ studentNameLong = profile.studentNameLong,
+ unshareTeamCode = team.code,
+ noteId = note.id,
)).execute()
parseResponse(response)
}
@@ -298,7 +383,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
pairToken = pairToken
)).execute()
- return parseResponse(response).browsers
+ return parseResponse(response, updateDeviceHash = true).browsers
}
@Throws(Exception::class)
@@ -309,7 +394,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
action = "listBrowsers"
)).execute()
- return parseResponse(response).browsers
+ return parseResponse(response, updateDeviceHash = true).browsers
}
@Throws(Exception::class)
@@ -321,7 +406,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
browserId = browserId
)).execute()
- return parseResponse(response).browsers
+ return parseResponse(response, updateDeviceHash = true).browsers
}
@Throws(Exception::class)
@@ -332,7 +417,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
appVersion = BuildConfig.VERSION_NAME,
errors = errors
)).execute()
- parseResponse(response)
+ parseResponse(response, updateDeviceHash = true)
}
@Throws(Exception::class)
@@ -342,7 +427,7 @@ class SzkolnyApi(val app: App) : CoroutineScope {
device = getDevice(),
userCode = userCode
)).execute()
- parseResponse(response)
+ parseResponse(response, updateDeviceHash = true)
}
@Throws(Exception::class)
@@ -361,14 +446,23 @@ class SzkolnyApi(val app: App) : CoroutineScope {
text = text
)).execute()
- return parseResponse(response).message
+ return parseResponse(response, updateDeviceHash = true).message
}
@Throws(Exception::class)
fun getRealms(registerName: String): List {
- val response = api.fsLoginRealms(registerName).execute()
+ val response = api.platforms(registerName).execute()
if (response.isSuccessful && response.body() != null) {
- return response.body()!!
+ return parseResponse(response)
+ }
+ throw SzkolnyApiException(null)
+ }
+
+ @Throws(Exception::class)
+ fun getContributors(): ContributorsResponse {
+ val response = api.contributors().execute()
+ if (response.isSuccessful && response.body() != null) {
+ return parseResponse(response)
}
throw SzkolnyApiException(null)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyService.kt
index c4198130..cca9475a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyService.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/SzkolnyService.kt
@@ -6,7 +6,7 @@ package pl.szczodrzynski.edziennik.data.api.szkolny
import pl.szczodrzynski.edziennik.data.api.szkolny.request.*
import pl.szczodrzynski.edziennik.data.api.szkolny.response.*
-import pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo
+import pl.szczodrzynski.edziennik.ui.login.LoginInfo
import retrofit2.Call
import retrofit2.http.*
@@ -18,6 +18,9 @@ interface SzkolnyService {
@POST("share")
fun shareEvent(@Body request: EventShareRequest): Call>
+ @POST("share")
+ fun shareNote(@Body request: NoteShareRequest): Call>
+
@POST("webPush")
fun webPush(@Body request: WebPushRequest): Call>
@@ -27,6 +30,9 @@ interface SzkolnyService {
@POST("appUser")
fun appUser(@Body request: AppUserRequest): Call>
+ @GET("contributors/android")
+ fun contributors(): Call>
+
@GET("updates/app")
fun updates(@Query("channel") channel: String = "release"): Call>>
@@ -39,6 +45,6 @@ interface SzkolnyService {
@GET("registerAvailability")
fun registerAvailability(): Call>>
- @GET("https://szkolny-eu.github.io/FSLogin/realms/{registerName}.json")
- fun fsLoginRealms(@Path("registerName") registerName: String): Call>
+ @GET("platforms/{registerName}")
+ fun platforms(@Path("registerName") registerName: String): Call>>
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/ApiCacheInterceptor.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/ApiCacheInterceptor.kt
index 19a84546..f1f8e341 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/ApiCacheInterceptor.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/ApiCacheInterceptor.kt
@@ -7,7 +7,7 @@ package pl.szczodrzynski.edziennik.data.api.szkolny.interceptor
import okhttp3.*
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
-import pl.szczodrzynski.edziennik.md5
+import pl.szczodrzynski.edziennik.ext.md5
class ApiCacheInterceptor(val app: App) : Interceptor {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/SignatureInterceptor.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/SignatureInterceptor.kt
index 30d0ec7e..b766cea5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/SignatureInterceptor.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/SignatureInterceptor.kt
@@ -6,7 +6,12 @@ package pl.szczodrzynski.edziennik.data.api.szkolny.interceptor
import okhttp3.Interceptor
import okhttp3.Response
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.BuildConfig
+import pl.szczodrzynski.edziennik.ext.bodyToString
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.hmacSHA1
+import pl.szczodrzynski.edziennik.ext.md5
class SignatureInterceptor(val app: App) : Interceptor {
companion object {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt
index 819194d8..068268ca 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt
@@ -9,7 +9,7 @@ import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.util.Base64
import pl.szczodrzynski.edziennik.BuildConfig
-import pl.szczodrzynski.edziennik.sha256
+import pl.szczodrzynski.edziennik.ext.sha256
import java.security.MessageDigest
object Signing {
@@ -39,13 +39,13 @@ object Signing {
val appPassword by lazy {
iLoveApple(
"ThisIsOurHardWorkPleaseDoNotCopyOrSteal(c)2019.KubaSz".sha256(),
- BuildConfig.VERSION_NAME.substringBeforeLast('+'),
+ BuildConfig.VERSION_BASE.substringBeforeLast('+'),
BuildConfig.VERSION_CODE.toLong()
)
}
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
- return "$param1.MTIzNDU2Nzg5MDLPrcQX7M===.$param2".sha256()
+ return "$param1.MTIzNDU2Nzg5MD5fPgIjyZ===.$param2".sha256()
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/EventShareRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/EventShareRequest.kt
index 1977d1b2..aba026a4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/EventShareRequest.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/EventShareRequest.kt
@@ -12,8 +12,9 @@ data class EventShareRequest (
val action: String = "event",
- /* If null, the server shows an error */
- val sharedByName: String?,
+ val userCode: String,
+ val studentNameLong: String,
+
val shareTeamCode: String? = null,
val unshareTeamCode: String? = null,
val requesterName: String? = null,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/NoteShareRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/NoteShareRequest.kt
new file mode 100644
index 00000000..122ea542
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/request/NoteShareRequest.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-26.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.szkolny.request
+
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+
+data class NoteShareRequest (
+ val deviceId: String,
+ val device: Device? = null,
+
+ val action: String = "note",
+
+ val userCode: String,
+ val studentNameLong: String,
+
+ val shareTeamCode: String? = null,
+ val unshareTeamCode: String? = null,
+ val requesterName: String? = null,
+
+ val noteId: Long? = null,
+ val note: Note? = null
+)
+
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ContributorsResponse.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ContributorsResponse.kt
new file mode 100644
index 00000000..f824280a
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ContributorsResponse.kt
@@ -0,0 +1,20 @@
+package pl.szczodrzynski.edziennik.data.api.szkolny.response
+
+import android.os.Parcelable
+import kotlinx.parcelize.Parcelize
+
+data class ContributorsResponse(
+ val contributors: List- ,
+ val translators: List
-
+) {
+
+ @Parcelize
+ data class Item(
+ val login: String,
+ val name: String?,
+ val avatarUrl: String,
+ val profileUrl: String,
+ val itemUrl: String,
+ val contributions: Int?
+ ) : Parcelable
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/RegisterAvailabilityStatus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/RegisterAvailabilityStatus.kt
index 82f2e050..617a7167 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/RegisterAvailabilityStatus.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/RegisterAvailabilityStatus.kt
@@ -5,15 +5,15 @@
package pl.szczodrzynski.edziennik.data.api.szkolny.response
import pl.szczodrzynski.edziennik.BuildConfig
-import pl.szczodrzynski.edziennik.DAY
-import pl.szczodrzynski.edziennik.currentTimeUnix
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.currentTimeUnix
data class RegisterAvailabilityStatus(
- val available: Boolean,
- val name: String?,
- val userMessage: Message?,
- val nextCheckAt: Long = currentTimeUnix() + 7 * DAY,
- val minVersionCode: Int = BuildConfig.VERSION_CODE
+ val available: Boolean,
+ val name: String?,
+ val userMessage: Message?,
+ val nextCheckAt: Long = currentTimeUnix() + 7 * DAY,
+ val minVersionCode: Int = BuildConfig.VERSION_CODE
) {
data class Message(
val title: String,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ServerSyncResponse.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ServerSyncResponse.kt
index 0ed11f9c..e7158754 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ServerSyncResponse.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/response/ServerSyncResponse.kt
@@ -4,9 +4,11 @@
package pl.szczodrzynski.edziennik.data.api.szkolny.response
+import pl.szczodrzynski.edziennik.data.db.entity.Note
import pl.szczodrzynski.edziennik.data.db.full.EventFull
data class ServerSyncResponse(
val events: List,
+ val notes: List,
val hasBrowsers: Boolean? = null
)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/AppSync.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/AppSync.kt
index 15482c53..0b13c867 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/AppSync.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/AppSync.kt
@@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApiException
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
import pl.szczodrzynski.edziennik.data.db.entity.Notification
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.toErrorCode
+import pl.szczodrzynski.edziennik.ext.toErrorCode
import pl.szczodrzynski.edziennik.utils.models.Date
class AppSync(val app: App, val notifications: MutableList, val profiles: List, val api: SzkolnyApi) {
@@ -30,7 +30,7 @@ class AppSync(val app: App, val notifications: MutableList, val pr
*/
fun run(lastSyncTime: Long, markAsSeen: Boolean = false): Int {
val blacklistedIds = app.db.eventDao().blacklistedIds
- val events = try {
+ val (events, notes) = try {
api.getEvents(profiles, notifications, blacklistedIds, lastSyncTime)
} catch (e: SzkolnyApiException) {
if (e.toErrorCode() == ERROR_API_INVALID_SIGNATURE)
@@ -40,6 +40,10 @@ class AppSync(val app: App, val notifications: MutableList, val pr
app.config.sync.lastAppSync = System.currentTimeMillis()
+ if (notes.isNotEmpty()) {
+ app.db.noteDao().addAll(notes)
+ }
+
if (events.isNotEmpty()) {
val today = Date.getToday()
app.db.metadataDao().addAllIgnore(events.map { event ->
@@ -54,6 +58,6 @@ class AppSync(val app: App, val notifications: MutableList, val pr
})
return app.db.eventDao().upsertAll(events).size
}
- return 0;
+ return 0
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/Notifications.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/Notifications.kt
index 21a5c112..3913709a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/Notifications.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/Notifications.kt
@@ -8,8 +8,9 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.*
-import pl.szczodrzynski.edziennik.getNotificationTitle
+import pl.szczodrzynski.edziennik.ext.getNotificationTitle
import pl.szczodrzynski.edziennik.utils.models.Date
+import pl.szczodrzynski.edziennik.utils.models.Week
class Notifications(val app: App, val notifications: MutableList, val profiles: List) {
companion object {
@@ -42,13 +43,22 @@ class Notifications(val app: App, val notifications: MutableList,
val text = app.getString(
R.string.notification_lesson_change_format,
lesson.getDisplayChangeType(app),
- if (lesson.displayDate == null) "" else lesson.displayDate!!.formattedString,
+ lesson.displayDate?.formattedString ?: "",
lesson.changeSubjectName
)
+ val textLong = app.getString(
+ R.string.notification_lesson_change_long_format,
+ lesson.getDisplayChangeType(app),
+ lesson.displayDate?.formattedString ?: "-",
+ lesson.displayDate?.weekDay?.let { Week.getFullDayName(it) } ?: "-",
+ lesson.changeSubjectName,
+ lesson.changeTeacherName
+ )
notifications += Notification(
id = Notification.buildId(lesson.profileId, Notification.TYPE_TIMETABLE_LESSON_CHANGE, lesson.id),
title = app.getNotificationTitle(Notification.TYPE_TIMETABLE_LESSON_CHANGE),
text = text,
+ textLong = textLong,
type = Notification.TYPE_TIMETABLE_LESSON_CHANGE,
profileId = lesson.profileId,
profileName = profiles.singleOrNull { it.id == lesson.profileId }?.name,
@@ -59,59 +69,90 @@ class Notifications(val app: App, val notifications: MutableList,
}
private fun eventNotifications() {
- for (event in app.db.eventDao().getNotNotifiedNow().filter { it.date >= today }) {
- val text = if (event.type == Event.TYPE_HOMEWORK)
+ app.db.eventDao().getNotNotifiedNow().filter {
+ it.date >= today
+ }.forEach { event ->
+ val text = if (event.isHomework)
app.getString(
- if (event.subjectLongName.isNullOrEmpty())
- R.string.notification_homework_no_subject_format
- else
- R.string.notification_homework_format,
- event.subjectLongName,
- event.date.formattedString
+ if (event.subjectLongName.isNullOrEmpty())
+ R.string.notification_homework_no_subject_format
+ else
+ R.string.notification_homework_format,
+ event.subjectLongName,
+ event.date.formattedString
)
else
app.getString(
- if (event.subjectLongName.isNullOrEmpty())
- R.string.notification_event_no_subject_format
- else
- R.string.notification_event_format,
- event.typeName ?: "wydarzenie",
- event.date.formattedString,
- event.subjectLongName
+ if (event.subjectLongName.isNullOrEmpty())
+ R.string.notification_event_no_subject_format
+ else
+ R.string.notification_event_format,
+ event.typeName ?: "wydarzenie",
+ event.date.formattedString,
+ event.subjectLongName
)
- val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
+ val textLong = app.getString(
+ R.string.notification_event_long_format,
+ event.typeName ?: "-",
+ event.subjectLongName ?: "-",
+ event.date.formattedString,
+ Week.getFullDayName(event.date.weekDay),
+ event.time?.stringHM ?: app.getString(R.string.event_all_day),
+ event.topic.take(200)
+ )
+ val type = if (event.isHomework)
+ Notification.TYPE_NEW_HOMEWORK
+ else
+ Notification.TYPE_NEW_EVENT
notifications += Notification(
- id = Notification.buildId(event.profileId, type, event.id),
- title = app.getNotificationTitle(type),
- text = text,
- type = type,
- profileId = event.profileId,
- profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
- viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
- addedDate = event.addedDate
+ id = Notification.buildId(event.profileId, type, event.id),
+ title = app.getNotificationTitle(type),
+ text = text,
+ textLong = textLong,
+ type = type,
+ profileId = event.profileId,
+ profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
+ viewId = if (event.isHomework) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
+ addedDate = event.addedDate
).addExtra("eventId", event.id).addExtra("eventDate", event.date.value.toLong())
}
}
fun sharedEventNotifications() {
- for (event in app.db.eventDao().getNotNotifiedNow().filter { it.date >= today && it.sharedBy != null }) {
+ app.db.eventDao().getNotNotifiedNow().filter {
+ it.date >= today && it.sharedBy != null && it.sharedBy != "self"
+ }.forEach { event ->
val text = app.getString(
- R.string.notification_shared_event_format,
- event.sharedByName,
- event.typeName ?: "wydarzenie",
- event.date.formattedString,
- event.topic
+ R.string.notification_shared_event_format,
+ event.sharedByName,
+ event.typeName ?: "wydarzenie",
+ event.date.formattedString,
+ event.topicHtml
)
- val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_HOMEWORK else Notification.TYPE_NEW_EVENT
+ val textLong = app.getString(
+ R.string.notification_shared_event_long_format,
+ event.sharedByName,
+ event.typeName ?: "-",
+ event.subjectLongName ?: "-",
+ event.date.formattedString,
+ Week.getFullDayName(event.date.weekDay),
+ event.time?.stringHM ?: app.getString(R.string.event_all_day),
+ event.topicHtml.take(200)
+ )
+ val type = if (event.isHomework)
+ Notification.TYPE_NEW_HOMEWORK
+ else
+ Notification.TYPE_NEW_EVENT
notifications += Notification(
- id = Notification.buildId(event.profileId, type, event.id),
- title = app.getNotificationTitle(type),
- text = text,
- type = type,
- profileId = event.profileId,
- profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
- viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
- addedDate = event.addedDate
+ id = Notification.buildId(event.profileId, type, event.id),
+ title = app.getNotificationTitle(type),
+ text = text,
+ textLong = textLong,
+ type = type,
+ profileId = event.profileId,
+ profileName = profiles.singleOrNull { it.id == event.profileId }?.name,
+ viewId = if (event.isHomework) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
+ addedDate = event.addedDate
).addExtra("eventId", event.id).addExtra("eventDate", event.date.value.toLong())
}
}
@@ -130,10 +171,20 @@ class Notifications(val app: App, val notifications: MutableList,
gradeName,
grade.subjectLongName
)
+ val textLong = app.getString(
+ R.string.notification_grade_long_format,
+ gradeName,
+ grade.weight.toString(),
+ grade.subjectLongName ?: "-",
+ grade.category ?: "-",
+ grade.description ?: "-",
+ grade.teacherName ?: "-"
+ )
notifications += Notification(
id = Notification.buildId(grade.profileId, Notification.TYPE_NEW_GRADE, grade.id),
title = app.getNotificationTitle(Notification.TYPE_NEW_GRADE),
text = text,
+ textLong = textLong,
type = Notification.TYPE_NEW_GRADE,
profileId = grade.profileId,
profileName = profiles.singleOrNull { it.id == grade.profileId }?.name,
@@ -158,10 +209,17 @@ class Notifications(val app: App, val notifications: MutableList,
notice.teacherName,
Date.fromMillis(notice.addedDate).formattedString
)
+ val textLong = app.getString(
+ R.string.notification_notice_long_format,
+ noticeTypeStr,
+ notice.teacherName ?: "-",
+ notice.text.take(200)
+ )
notifications += Notification(
id = Notification.buildId(notice.profileId, Notification.TYPE_NEW_NOTICE, notice.id),
title = app.getNotificationTitle(Notification.TYPE_NEW_NOTICE),
text = text,
+ textLong = textLong,
type = Notification.TYPE_NEW_NOTICE,
profileId = notice.profileId,
profileName = profiles.singleOrNull { it.id == notice.profileId }?.name,
@@ -193,10 +251,21 @@ class Notifications(val app: App, val notifications: MutableList,
attendance.subjectLongName,
attendance.date.formattedString
)
+ val textLong = app.getString(
+ R.string.notification_attendance_long_format,
+ attendanceTypeStr,
+ attendance.date.formattedString,
+ attendance.startTime?.stringHM ?: "-",
+ attendance.lessonNumber ?: "-",
+ attendance.subjectLongName ?: "-",
+ attendance.teacherName ?: "-",
+ attendance.lessonTopic ?: "-"
+ )
notifications += Notification(
id = Notification.buildId(attendance.profileId, Notification.TYPE_NEW_ATTENDANCE, attendance.id),
title = app.getNotificationTitle(Notification.TYPE_NEW_ATTENDANCE),
text = text,
+ textLong = textLong,
type = Notification.TYPE_NEW_ATTENDANCE,
profileId = attendance.profileId,
profileName = profiles.singleOrNull { it.id == attendance.profileId }?.name,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt
index 843f2174..41614394 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt
@@ -8,8 +8,15 @@ import android.util.SparseIntArray
import androidx.core.app.NotificationCompat
import androidx.core.util.forEach
import androidx.core.util.set
+import com.mikepenz.iconics.IconicsDrawable
+import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
+import com.mikepenz.iconics.utils.*
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SERVER_MESSAGE
+import pl.szczodrzynski.edziennik.ext.Intent
+import pl.szczodrzynski.edziennik.ext.asBoldSpannable
+import pl.szczodrzynski.edziennik.ext.concat
+import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification
@@ -86,7 +93,7 @@ class PostNotifications(val app: App, nList: List) {
MainActivity::class.java,
"fragmentId" to MainActivity.DRAWER_ITEM_NOTIFICATIONS
)
- val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT)
+ val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
// On Nougat or newer - show maximum 8 notifications
// On Marshmallow or older - show maximum 4 notifications
@@ -107,6 +114,10 @@ class PostNotifications(val app: App, nList: List) {
.setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText)
.setSmallIcon(R.drawable.ic_notification)
+ .setLargeIcon(IconicsDrawable(app).apply {
+ icon = CommunityMaterial.Icon.cmd_bell_ring_outline
+ colorRes = R.color.colorPrimary
+ }.toBitmap())
.setStyle(NotificationCompat.InboxStyle()
.also {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
@@ -137,8 +148,11 @@ class PostNotifications(val app: App, nList: List) {
.setSubText(if (it.type == TYPE_SERVER_MESSAGE) null else it.title)
.setTicker("${it.profileName}: ${it.title}")
.setSmallIcon(R.drawable.ic_notification)
+ .setLargeIcon(IconicsDrawable(app, it.getLargeIcon()).apply {
+ colorRes = R.color.colorPrimary
+ }.toBitmap())
.setStyle(NotificationCompat.BigTextStyle()
- .bigText(it.text))
+ .bigText(it.textLong ?: it.text))
.setWhen(it.addedDate)
.addDefaults()
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
@@ -160,6 +174,10 @@ class PostNotifications(val app: App, nList: List) {
.setContentText(buildSummaryText(summaryCounts))
.setTicker(newNotificationsText)
.setSmallIcon(R.drawable.ic_notification)
+ .setLargeIcon(IconicsDrawable(app).apply {
+ icon = CommunityMaterial.Icon.cmd_bell_ring_outline
+ colorRes = R.color.colorPrimary
+ }.toBitmap())
.addDefaults()
.setGroupSummary(true)
.setContentIntent(summaryIntent)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/SzkolnyTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/SzkolnyTask.kt
index 3ac80495..39dd7e15 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/SzkolnyTask.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/SzkolnyTask.kt
@@ -5,12 +5,12 @@
package pl.szczodrzynski.edziennik.data.api.task
import pl.szczodrzynski.edziennik.App
-import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
import pl.szczodrzynski.edziennik.data.db.entity.Notification
import pl.szczodrzynski.edziennik.data.db.entity.Profile
+import pl.szczodrzynski.edziennik.ext.HOUR
import pl.szczodrzynski.edziennik.utils.Utils.d
class SzkolnyTask(val app: App, val syncingProfiles: List) : IApiTask(-1) {
@@ -31,12 +31,12 @@ class SzkolnyTask(val app: App, val syncingProfiles: List) : IApiTask(-
val notifications = Notifications(app, notificationList, profiles)
notifications.run()
- val appSyncProfiles = profiles.filter { it.registration == Profile.REGISTRATION_ENABLED && !it.archived }
+ val appSyncProfiles = profiles.filter { it.canShare }
// App Sync conditions:
// - every 24 hours && any profile is registered
// - if there are new notifications && any browser is paired
val shouldAppSync =
- System.currentTimeMillis() - app.config.sync.lastAppSync > 24*HOUR*1000
+ System.currentTimeMillis() - app.config.sync.lastAppSync > 24* HOUR *1000
&& appSyncProfiles.isNotEmpty()
|| notificationList.isNotEmpty()
&& app.config.sync.webPushEnabled
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt
index e6d7e40e..b7f6ccf2 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/AppDb.kt
@@ -42,8 +42,9 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
ConfigEntry::class,
LibrusLesson::class,
TimetableManual::class,
+ Note::class,
Metadata::class
-], version = 91)
+], version = 98)
@TypeConverters(
ConverterTime::class,
ConverterDate::class,
@@ -82,6 +83,7 @@ abstract class AppDb : RoomDatabase() {
abstract fun configDao(): ConfigDao
abstract fun librusLessonDao(): LibrusLessonDao
abstract fun timetableManualDao(): TimetableManualDao
+ abstract fun noteDao(): NoteDao
abstract fun metadataDao(): MetadataDao
companion object {
@@ -176,7 +178,14 @@ abstract class AppDb : RoomDatabase() {
Migration88(),
Migration89(),
Migration90(),
- Migration91()
+ Migration91(),
+ Migration92(),
+ Migration93(),
+ Migration94(),
+ Migration95(),
+ Migration96(),
+ Migration97(),
+ Migration98(),
).allowMainThreadQueries().build()
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/AttendanceDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/AttendanceDao.kt
index 3ffdc1b8..94be0c34 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/AttendanceDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/AttendanceDao.kt
@@ -64,6 +64,8 @@ abstract class AttendanceDao : BaseDao {
getRawNow("$QUERY WHERE notified = 0 $ORDER_BY")
fun getNotNotifiedNow(profileId: Int) =
getRawNow("$QUERY WHERE attendances.profileId = $profileId AND notified = 0 $ORDER_BY")
+ fun getAllByDateNow(profileId: Int, date: Date) =
+ getRawNow("$QUERY WHERE attendances.profileId = $profileId AND attendanceDate = '${date.stringY_m_d}' $ORDER_BY")
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/BaseDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/BaseDao.kt
index 0ae961db..60089423 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/BaseDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/BaseDao.kt
@@ -12,15 +12,19 @@ import pl.szczodrzynski.edziennik.data.db.entity.Keepable
@Dao
interface BaseDao {
+ @Transaction
@RawQuery
fun getRaw(query: SupportSQLiteQuery): LiveData
>
fun getRaw(query: String) = getRaw(SimpleSQLiteQuery(query))
+ @Transaction
@RawQuery
fun getOne(query: SupportSQLiteQuery): LiveData
fun getOne(query: String) = getOne(SimpleSQLiteQuery(query))
+ @Transaction
@RawQuery
fun getRawNow(query: SupportSQLiteQuery): List
fun getRawNow(query: String) = getRawNow(SimpleSQLiteQuery(query))
+ @Transaction
@RawQuery
fun getOneNow(query: SupportSQLiteQuery): F?
fun getOneNow(query: String) = getOneNow(SimpleSQLiteQuery(query))
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt
index 897d53ff..24e58d02 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt
@@ -84,6 +84,10 @@ abstract class EventDao : BaseDao {
fun getAllByDateNow(profileId: Int, date: Date) =
getRawNow("$QUERY WHERE $NOT_BLACKLISTED AND events.profileId = $profileId AND eventDate = '${date.stringY_m_d}' $ORDER_BY")
+ // GET ONE - LIVE DATA
+ fun getById(profileId: Int, id: Long) =
+ getOne("$QUERY WHERE events.profileId = $profileId AND eventId = $id")
+
// GET ONE - NOW
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE events.profileId = $profileId AND eventId = $id")
@@ -105,7 +109,7 @@ abstract class EventDao : BaseDao {
abstract fun removeNotManual(profileId: Int)*/
@RawQuery
- abstract fun dontKeepFuture(query: SupportSQLiteQuery?): Long
+ abstract fun dontKeepFuture(query: SupportSQLiteQuery): Long
@Transaction
open fun dontKeepFuture(profileId: Int, todayDate: Date, filter: String) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventTypeDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventTypeDao.kt
index 28be6d65..d5006970 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventTypeDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventTypeDao.kt
@@ -9,30 +9,9 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
-import pl.szczodrzynski.edziennik.R
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_CLASS_EVENT
import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_DEFAULT
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_ESSAY
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXAM
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXCURSION
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_HOMEWORK
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_INFORMATION
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PROJECT
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PT_MEETING
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_READING
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_SHORT_QUIZ
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_CLASS_EVENT
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_DEFAULT
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_ESSAY
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXAM
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXCURSION
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_HOMEWORK
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_INFORMATION
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PROJECT
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PT_MEETING
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_READING
-import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_SHORT_QUIZ
import pl.szczodrzynski.edziennik.data.db.entity.EventType
+import pl.szczodrzynski.edziennik.data.db.entity.EventType.Companion.SOURCE_DEFAULT
@Dao
abstract class EventTypeDao {
@@ -58,19 +37,18 @@ abstract class EventTypeDao {
abstract val allNow: List
fun addDefaultTypes(context: Context, profileId: Int): List {
- val typeList = listOf(
- EventType(profileId, TYPE_HOMEWORK, context.getString(R.string.event_type_homework), COLOR_HOMEWORK),
- EventType(profileId, TYPE_DEFAULT, context.getString(R.string.event_other), COLOR_DEFAULT),
- EventType(profileId, TYPE_EXAM, context.getString(R.string.event_exam), COLOR_EXAM),
- EventType(profileId, TYPE_SHORT_QUIZ, context.getString(R.string.event_short_quiz), COLOR_SHORT_QUIZ),
- EventType(profileId, TYPE_ESSAY, context.getString(R.string.event_essay), COLOR_ESSAY),
- EventType(profileId, TYPE_PROJECT, context.getString(R.string.event_project), COLOR_PROJECT),
- EventType(profileId, TYPE_PT_MEETING, context.getString(R.string.event_pt_meeting), COLOR_PT_MEETING),
- EventType(profileId, TYPE_EXCURSION, context.getString(R.string.event_excursion), COLOR_EXCURSION),
- EventType(profileId, TYPE_READING, context.getString(R.string.event_reading), COLOR_READING),
- EventType(profileId, TYPE_CLASS_EVENT, context.getString(R.string.event_class_event), COLOR_CLASS_EVENT),
- EventType(profileId, TYPE_INFORMATION, context.getString(R.string.event_information), COLOR_INFORMATION)
- )
+ var order = 100
+ val colorMap = EventType.getTypeColorMap()
+ val typeList = EventType.getTypeNameMap().map { (id, name) ->
+ EventType(
+ profileId = profileId,
+ id = id,
+ name = context.getString(name),
+ color = colorMap[id] ?: COLOR_DEFAULT,
+ order = order++,
+ source = SOURCE_DEFAULT
+ )
+ }
addAll(typeList)
return typeList
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageDao.kt
index 51d56854..af4e608e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageDao.kt
@@ -29,7 +29,7 @@ abstract class MessageDao : BaseDao {
LEFT JOIN metadata ON messageId = thingId AND thingType = ${Metadata.TYPE_MESSAGE} AND metadata.profileId = messages.profileId
"""
- private const val ORDER_BY = """ORDER BY messageIsPinned, addedDate DESC"""
+ private const val ORDER_BY = """ORDER BY messageIsPinned DESC, addedDate DESC"""
}
private val selective by lazy { MessageDaoSelective(App.db) }
@@ -51,6 +51,9 @@ abstract class MessageDao : BaseDao {
@Query("DELETE FROM messages WHERE keep = 0")
abstract override fun removeNotKept()
+ @Query("DELETE FROM messages WHERE profileId = :profileId AND messageId = :messageId")
+ abstract fun delete(profileId: Int, messageId: Long)
+
// GET ALL - LIVE DATA
fun getAll(profileId: Int) =
getRaw("$QUERY WHERE messages.profileId = $profileId $ORDER_BY")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageRecipientDao.java b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageRecipientDao.java
index 20e6fe90..b33adbff 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageRecipientDao.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MessageRecipientDao.java
@@ -4,8 +4,6 @@
package pl.szczodrzynski.edziennik.data.db.dao;
-import java.util.List;
-
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
@@ -14,6 +12,8 @@ import androidx.room.RawQuery;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
+import java.util.List;
+
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient;
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull;
@@ -22,6 +22,9 @@ public abstract class MessageRecipientDao {
@Query("DELETE FROM messageRecipients WHERE profileId = :profileId")
public abstract void clear(int profileId);
+ @Query("DELETE FROM messageRecipients WHERE profileId = :profileId AND messageId = :messageId")
+ public abstract void clearFor(int profileId, long messageId);
+
@Insert(onConflict = OnConflictStrategy.REPLACE)
public abstract long add(MessageRecipient messageRecipient);
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MetadataDao.java b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MetadataDao.java
index eac92f21..ab694702 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MetadataDao.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/MetadataDao.java
@@ -4,6 +4,15 @@
package pl.szczodrzynski.edziennik.data.db.dao;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ANNOUNCEMENT;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_EVENT;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_GRADE;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_HOMEWORK;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LESSON_CHANGE;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_MESSAGE;
+import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_NOTICE;
+
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
@@ -23,15 +32,6 @@ import pl.szczodrzynski.edziennik.data.db.entity.Notice;
import pl.szczodrzynski.edziennik.data.db.full.LessonFull;
import pl.szczodrzynski.edziennik.utils.models.UnreadCounter;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ANNOUNCEMENT;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_ATTENDANCE;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_EVENT;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_GRADE;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_HOMEWORK;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_LESSON_CHANGE;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_MESSAGE;
-import static pl.szczodrzynski.edziennik.data.db.entity.Metadata.TYPE_NOTICE;
-
@Dao
public abstract class MetadataDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
@@ -78,8 +78,8 @@ public abstract class MetadataDao {
}
}
if (o instanceof Event) {
- if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen, false)) == -1) {
- updateSeen(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen);
+ if (add(new Metadata(profileId, ((Event) o).isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen, false)) == -1) {
+ updateSeen(profileId, ((Event) o).isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), seen);
}
}
if (o instanceof LessonFull) {
@@ -117,8 +117,8 @@ public abstract class MetadataDao {
}
}
if (o instanceof Event) {
- if (add(new Metadata(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), false, notified)) == -1) {
- updateNotified(profileId, ((Event) o).getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), notified);
+ if (add(new Metadata(profileId, ((Event) o).isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), false, notified)) == -1) {
+ updateNotified(profileId, ((Event) o).isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, ((Event) o).getId(), notified);
}
}
if (o instanceof LessonFull) {
@@ -141,9 +141,9 @@ public abstract class MetadataDao {
@Transaction
public void setBoth(int profileId, Event o, boolean seen, boolean notified, long addedDate) {
if (o != null) {
- if (add(new Metadata(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen, notified)) == -1) {
- updateSeen(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen);
- updateNotified(profileId, o.getType() == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), notified);
+ if (add(new Metadata(profileId, o.isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen, notified)) == -1) {
+ updateSeen(profileId, o.isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), seen);
+ updateNotified(profileId, o.isHomework() ? TYPE_HOMEWORK : TYPE_EVENT, o.getId(), notified);
}
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NoteDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NoteDao.kt
new file mode 100644
index 00000000..4ad421bc
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/NoteDao.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-23.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.dao
+
+import androidx.lifecycle.LiveData
+import androidx.room.*
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+
+@Dao
+interface NoteDao {
+ companion object {
+ private const val ORDER_BY = "ORDER BY addedDate DESC"
+ }
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun add(note: Note)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun addAll(noteList: List)
+
+ @Delete
+ fun delete(note: Note)
+
+ @Query("DELETE FROM notes WHERE profileId = :profileId AND noteId = :noteId")
+ fun remove(profileId: Int, noteId: Long)
+
+ @Query("SELECT * FROM notes WHERE profileId = :profileId AND noteId = :noteId $ORDER_BY")
+ fun get(profileId: Int, noteId: Long): LiveData
+
+ @Query("SELECT * FROM notes WHERE profileId = :profileId AND noteId = :noteId $ORDER_BY")
+ fun getNow(profileId: Int, noteId: Long): Note?
+
+ @Query("SELECT * FROM notes WHERE profileId = :profileId $ORDER_BY")
+ fun getAll(profileId: Int): LiveData>
+
+ @Query("SELECT * FROM notes WHERE profileId = :profileId AND noteOwnerType = :ownerType AND noteOwnerId = :ownerId $ORDER_BY")
+ fun getAllFor(profileId: Int, ownerType: Note.OwnerType, ownerId: Long): LiveData>
+
+ @Query("SELECT * FROM notes WHERE profileId = :profileId AND noteOwnerType IS NULL $ORDER_BY")
+ fun getAllNoOwner(profileId: Int): LiveData>
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TimetableDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TimetableDao.kt
index c7cbee12..4201a51d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TimetableDao.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/TimetableDao.kt
@@ -84,6 +84,8 @@ abstract class TimetableDao : BaseDao {
"LIMIT 1")
fun getBetweenDates(dateFrom: Date, dateTo: Date) =
getRaw("$QUERY WHERE (type != 3 AND date >= '${dateFrom.stringY_m_d}' AND date <= '${dateTo.stringY_m_d}') OR ((type = 3 OR type = 1) AND oldDate >= '${dateFrom.stringY_m_d}' AND oldDate <= '${dateTo.stringY_m_d}') $ORDER_BY")
+ fun getChanges(profileId: Int) =
+ getRaw("$QUERY WHERE timetable.profileId = $profileId AND $IS_CHANGED $ORDER_BY")
// GET ALL - NOW
fun getAllNow(profileId: Int) =
@@ -105,12 +107,12 @@ abstract class TimetableDao : BaseDao {
fun getByIdNow(profileId: Int, id: Long) =
getOneNow("$QUERY WHERE timetable.profileId = $profileId AND timetable.id = $id")
- @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom))")
- abstract fun dontKeepFromDate(profileId: Int, dateFrom: Date)
+ @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND isExtra = :isExtra AND type != -1 AND ((type != 3 AND date >= :dateFrom) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom))")
+ abstract fun dontKeepFromDate(profileId: Int, dateFrom: Date, isExtra: Boolean)
- @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate <= :dateTo))")
- abstract fun dontKeepToDate(profileId: Int, dateTo: Date)
+ @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND isExtra = :isExtra AND type != -1 AND ((type != 3 AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate <= :dateTo))")
+ abstract fun dontKeepToDate(profileId: Int, dateTo: Date, isExtra: Boolean)
- @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))")
- abstract fun dontKeepBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date)
+ @Query("UPDATE timetable SET keep = 0 WHERE profileId = :profileId AND isExtra = :isExtra AND type != -1 AND ((type != 3 AND date >= :dateFrom AND date <= :dateTo) OR ((type = 3 OR type = 1) AND oldDate >= :dateFrom AND oldDate <= :dateTo))")
+ abstract fun dontKeepBetweenDates(profileId: Int, dateFrom: Date, dateTo: Date, isExtra: Boolean)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt
index 0dcaa83e..795bad85 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Event.kt
@@ -8,8 +8,9 @@ import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import com.google.gson.annotations.SerializedName
-import pl.szczodrzynski.edziennik.MINUTE
import pl.szczodrzynski.edziennik.data.db.full.EventFull
+import pl.szczodrzynski.edziennik.ext.MINUTE
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import java.util.*
@@ -45,6 +46,7 @@ open class Event(
var addedDate: Long = System.currentTimeMillis()
) : Keepable() {
companion object {
+ const val TYPE_ELEARNING = -5L
const val TYPE_UNDEFINED = -2L
const val TYPE_HOMEWORK = -1L
const val TYPE_DEFAULT = 0L
@@ -57,7 +59,7 @@ open class Event(
const val TYPE_READING = 7L
const val TYPE_CLASS_EVENT = 8L
const val TYPE_INFORMATION = 9L
- const val TYPE_TEACHER_ABSENCE = 10L
+ const val COLOR_ELEARNING = 0xfff57f17.toInt()
const val COLOR_HOMEWORK = 0xff795548.toInt()
const val COLOR_DEFAULT = 0xffffc107.toInt()
const val COLOR_EXAM = 0xfff44336.toInt()
@@ -69,11 +71,11 @@ open class Event(
const val COLOR_READING = 0xFFFFEB3B.toInt()
const val COLOR_CLASS_EVENT = 0xff388e3c.toInt()
const val COLOR_INFORMATION = 0xff039be5.toInt()
- const val COLOR_TEACHER_ABSENCE = 0xff039be5.toInt()
}
@ColumnInfo(name = "eventAddedManually")
var addedManually: Boolean = false
+ get() = field || sharedBy == "self"
@ColumnInfo(name = "eventSharedBy")
var sharedBy: String? = null
@ColumnInfo(name = "eventSharedByName")
@@ -83,6 +85,13 @@ open class Event(
@ColumnInfo(name = "eventIsDone")
var isDone: Boolean = false
+ /**
+ * Whether the full contents of the event are already stored locally.
+ * There may be a need to download the full topic or body.
+ */
+ @ColumnInfo(name = "eventIsDownloaded")
+ var isDownloaded: Boolean = true
+
/**
* Body/text of the event, if this is a [TYPE_HOMEWORK].
* May be null if the body is not downloaded yet, or the type is not [TYPE_HOMEWORK].
@@ -90,6 +99,8 @@ open class Event(
* or the topic contains the body already.
*/
var homeworkBody: String? = null
+ val hasAttachments
+ get() = attachmentIds.isNotNullNorEmpty()
var attachmentIds: MutableList? = null
var attachmentNames: MutableList? = null
@@ -116,20 +127,16 @@ open class Event(
var showAsUnseen: Boolean? = null
val startTimeCalendar: Calendar
- get() = Calendar.getInstance().also { it.set(
- date.year,
- date.month - 1,
- date.day,
- time?.hour ?: 0,
- time?.minute ?: 0,
- time?.second ?: 0
- ) }
+ get() = date.getAsCalendar(time)
val endTimeCalendar: Calendar
get() = startTimeCalendar.also {
it.timeInMillis += 45 * MINUTE * 1000
}
+ val isHomework
+ get() = type == TYPE_HOMEWORK
+
@Ignore
fun withMetadata(metadata: Metadata) = EventFull(this, metadata)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.java b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.java
deleted file mode 100644
index bf981e84..00000000
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) Kacper Ziubryniewicz 2020-1-6
- */
-
-package pl.szczodrzynski.edziennik.data.db.entity;
-
-import android.graphics.Color;
-
-import androidx.room.ColumnInfo;
-import androidx.room.Entity;
-
-@Entity(tableName = "eventTypes",
- primaryKeys = {"profileId", "eventType"})
-public class EventType {
- public int profileId;
-
- @ColumnInfo(name = "eventType")
- public long id;
-
- @ColumnInfo(name = "eventTypeName")
- public String name;
- @ColumnInfo(name = "eventTypeColor")
- public int color;
-
- public EventType(int profileId, long id, String name, int color) {
- this.profileId = profileId;
- this.id = id;
- this.name = name;
- this.color = color;
- }
-
- public EventType(int profileId, int id, String name, String color) {
- this(profileId, id, name, Color.parseColor(color));
- }
-}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.kt
new file mode 100644
index 00000000..7753b38a
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/EventType.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-4-19.
+ */
+package pl.szczodrzynski.edziennik.data.db.entity
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import pl.szczodrzynski.edziennik.R
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_CLASS_EVENT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_DEFAULT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_ELEARNING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_ESSAY
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXAM
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_EXCURSION
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_HOMEWORK
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_INFORMATION
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PROJECT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_PT_MEETING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_READING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_SHORT_QUIZ
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_CLASS_EVENT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_DEFAULT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_ELEARNING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_ESSAY
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXAM
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_EXCURSION
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_HOMEWORK
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_INFORMATION
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PROJECT
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_PT_MEETING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_READING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_SHORT_QUIZ
+
+@Entity(
+ tableName = "eventTypes",
+ primaryKeys = ["profileId", "eventType"]
+)
+class EventType(
+ val profileId: Int,
+
+ @ColumnInfo(name = "eventType")
+ val id: Long,
+
+ @ColumnInfo(name = "eventTypeName")
+ val name: String,
+ @ColumnInfo(name = "eventTypeColor")
+ val color: Int,
+ @ColumnInfo(name = "eventTypeOrder")
+ var order: Int = id.toInt(),
+ @ColumnInfo(name = "eventTypeSource")
+ val source: Int = SOURCE_REGISTER
+) {
+ companion object {
+ const val SOURCE_DEFAULT = 0
+ const val SOURCE_REGISTER = 1
+ const val SOURCE_CUSTOM = 2
+ const val SOURCE_SHARED = 3
+
+ fun getTypeColorMap() = mapOf(
+ TYPE_ELEARNING to COLOR_ELEARNING,
+ TYPE_HOMEWORK to COLOR_HOMEWORK,
+ TYPE_DEFAULT to COLOR_DEFAULT,
+ TYPE_EXAM to COLOR_EXAM,
+ TYPE_SHORT_QUIZ to COLOR_SHORT_QUIZ,
+ TYPE_ESSAY to COLOR_ESSAY,
+ TYPE_PROJECT to COLOR_PROJECT,
+ TYPE_PT_MEETING to COLOR_PT_MEETING,
+ TYPE_EXCURSION to COLOR_EXCURSION,
+ TYPE_READING to COLOR_READING,
+ TYPE_CLASS_EVENT to COLOR_CLASS_EVENT,
+ TYPE_INFORMATION to COLOR_INFORMATION
+ )
+
+ fun getTypeNameMap() = mapOf(
+ TYPE_ELEARNING to R.string.event_type_elearning,
+ TYPE_HOMEWORK to R.string.event_type_homework,
+ TYPE_DEFAULT to R.string.event_other,
+ TYPE_EXAM to R.string.event_exam,
+ TYPE_SHORT_QUIZ to R.string.event_short_quiz,
+ TYPE_ESSAY to R.string.event_essay,
+ TYPE_PROJECT to R.string.event_project,
+ TYPE_PT_MEETING to R.string.event_pt_meeting,
+ TYPE_EXCURSION to R.string.event_excursion,
+ TYPE_READING to R.string.event_reading,
+ TYPE_CLASS_EVENT to R.string.event_class_event,
+ TYPE_INFORMATION to R.string.event_information
+ )
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Lesson.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Lesson.kt
index 0c97ba24..37b7f6f3 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Lesson.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Lesson.kt
@@ -48,6 +48,8 @@ open class Lesson(
var oldTeamId: Long? = null
var oldClassroom: String? = null
+ var isExtra: Boolean = false
+
val displayDate: Date?
get() {
if (type == TYPE_SHIFTED_SOURCE)
@@ -72,6 +74,8 @@ open class Lesson(
@Ignore
var showAsUnseen = false
+ var color: Int? = null
+
override fun toString(): String {
return "Lesson(profileId=$profileId, " +
"id=$id, " +
@@ -121,11 +125,13 @@ open class Lesson(
return true
}
- override fun hashCode(): Int { // intentionally ignoring ID and display* here
+ override fun hashCode(): Int { // intentionally ignoring ID, display* and isExtra here
var result = profileId
result = 31 * result + type
result = 31 * result + (date?.hashCode() ?: 0)
- result = 31 * result + (lessonNumber ?: 0)
+ // this creates problems in Mobidziennik with extra lessons
+ // ... and is not generally useful anyway
+ // result = 31 * result + (lessonNumber ?: 0)
result = 31 * result + (startTime?.hashCode() ?: 0)
result = 31 * result + (endTime?.hashCode() ?: 0)
result = 31 * result + (subjectId?.hashCode() ?: 0)
@@ -133,7 +139,7 @@ open class Lesson(
result = 31 * result + (teamId?.hashCode() ?: 0)
result = 31 * result + (classroom?.hashCode() ?: 0)
result = 31 * result + (oldDate?.hashCode() ?: 0)
- result = 31 * result + (oldLessonNumber ?: 0)
+ // result = 31 * result + (oldLessonNumber ?: 0)
result = 31 * result + (oldStartTime?.hashCode() ?: 0)
result = 31 * result + (oldEndTime?.hashCode() ?: 0)
result = 31 * result + (oldSubjectId?.hashCode() ?: 0)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/LoginStore.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/LoginStore.kt
index 192bd1f6..32c0d7e7 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/LoginStore.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/LoginStore.kt
@@ -8,7 +8,7 @@ import android.os.Bundle
import androidx.room.ColumnInfo
import androidx.room.Entity
import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.ext.*
@Entity(tableName = "loginStores", primaryKeys = ["loginStoreId"])
class LoginStore(
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Message.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Message.kt
index 98105057..18a87df7 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Message.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Message.kt
@@ -7,7 +7,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
@Entity(tableName = "messages",
primaryKeys = ["profileId", "messageId"],
@@ -41,7 +41,16 @@ open class Message(
}
@ColumnInfo(name = "messageIsPinned")
- var isPinned: Boolean = false
+ var isStarred: Boolean = false
+
+ val isReceived
+ get() = type == TYPE_RECEIVED
+ val isSent
+ get() = type == TYPE_SENT
+ val isDeleted
+ get() = type == TYPE_DELETED
+ val isDraft
+ get() = type == TYPE_DRAFT
var hasAttachments = false // if the attachments are not yet downloaded but we already know there are some
get() = field || attachmentIds.isNotNullNorEmpty()
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Note.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Note.kt
new file mode 100644
index 00000000..9b6ad908
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Note.kt
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.entity
+
+import androidx.room.*
+import pl.szczodrzynski.edziennik.R
+import pl.szczodrzynski.edziennik.ui.search.Searchable
+import pl.szczodrzynski.edziennik.utils.html.BetterHtml
+
+@Entity(
+ tableName = "notes",
+ indices = [
+ Index(value = ["profileId", "noteOwnerType", "noteOwnerId"]),
+ ],
+)
+data class Note(
+ var profileId: Int,
+
+ @PrimaryKey
+ @ColumnInfo(name = "noteId")
+ val id: Long,
+
+ @ColumnInfo(name = "noteOwnerType")
+ val ownerType: OwnerType?,
+ @ColumnInfo(name = "noteOwnerId")
+ val ownerId: Long?,
+ @ColumnInfo(name = "noteReplacesOriginal")
+ val replacesOriginal: Boolean = false,
+
+ @ColumnInfo(name = "noteTopic")
+ val topic: String?,
+ @ColumnInfo(name = "noteBody")
+ val body: String,
+ @ColumnInfo(name = "noteColor")
+ val color: Long?,
+
+ @ColumnInfo(name = "noteSharedBy")
+ var sharedBy: String? = null,
+ @ColumnInfo(name = "noteSharedByName")
+ val sharedByName: String? = null,
+
+ val addedDate: Long = System.currentTimeMillis(),
+) : Searchable {
+ enum class OwnerType(
+ val isShareable: Boolean,
+ val canReplace: Boolean,
+ ) {
+ /**
+ * The [NONE] type is only for usage in the UI and should not be saved.
+ */
+ NONE(isShareable = true, canReplace = false),
+ EVENT(isShareable = true, canReplace = true),
+ DAY(isShareable = true, canReplace = false),
+ LESSON(isShareable = true, canReplace = true),
+ MESSAGE(isShareable = true, canReplace = false),
+ EVENT_SUBJECT(isShareable = true, canReplace = false),
+ LESSON_SUBJECT(isShareable = true, canReplace = false),
+ GRADE(isShareable = false, canReplace = true),
+ ATTENDANCE(isShareable = false, canReplace = true),
+ BEHAVIOR(isShareable = false, canReplace = false),
+ ANNOUNCEMENT(isShareable = true, canReplace = false),
+ }
+
+ enum class Color(val value: Long?, val stringRes: Int) {
+ NONE(null, R.string.color_none),
+ RED(0xffff1744, R.string.color_red),
+ ORANGE(0xffff9100, R.string.color_orange),
+ YELLOW(0xffffea00, R.string.color_yellow),
+ GREEN(0xff00c853, R.string.color_green),
+ TEAL(0xff00bfa5, R.string.color_teal),
+ BLUE(0xff0091ea, R.string.color_blue),
+ DARK_BLUE(0xff304ffe, R.string.color_dark_blue),
+ PURPLE(0xff6200ea, R.string.color_purple),
+ PINK(0xffd500f9, R.string.color_pink),
+ BROWN(0xff795548, R.string.color_brown),
+ GREY(0xff9e9e9e, R.string.color_grey),
+ BLACK(0xff000000, R.string.color_black),
+ }
+
+ val isShared
+ get() = sharedBy != null && sharedByName != null
+ val canEdit
+ get() = !isShared || sharedBy == "self"
+
+ // used when receiving notes
+ @Ignore
+ var teamCode: String? = null
+
+ @delegate:Ignore
+ @delegate:Transient
+ val topicHtml by lazy {
+ topic?.let {
+ BetterHtml.fromHtml(context = null, it, nl2br = true)
+ }
+ }
+
+ @delegate:Ignore
+ @delegate:Transient
+ val bodyHtml by lazy {
+ BetterHtml.fromHtml(context = null, body, nl2br = true)
+ }
+
+ @Ignore
+ @Transient
+ var isCategoryItem = false
+
+ @Ignore
+ @Transient
+ override var searchPriority = 0
+
+ @Ignore
+ @Transient
+ override var searchHighlightText: String? = null
+
+ @delegate:Ignore
+ @delegate:Transient
+ override val searchKeywords by lazy {
+ if (isCategoryItem)
+ return@lazy emptyList()
+ listOf(
+ listOf(topicHtml?.toString(), bodyHtml.toString()),
+ listOf(sharedByName),
+ )
+ }
+
+ override fun compareTo(other: Searchable<*>): Int {
+ if (other !is Note)
+ return 0
+ val order = ownerType?.ordinal ?: -1
+ val otherOrder = other.ownerType?.ordinal ?: -1
+ return when {
+ // custom ascending sorting
+ order > otherOrder -> 1
+ order < otherOrder -> -1
+ // all category elements stay at their original position
+ isCategoryItem -> 0
+ other.isCategoryItem -> 0
+ // ascending sorting
+ searchPriority > other.searchPriority -> 1
+ searchPriority < other.searchPriority -> -1
+ // descending sorting
+ addedDate > other.addedDate -> -1
+ addedDate < other.addedDate -> 1
+ else -> 0
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Noteable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Noteable.kt
new file mode 100644
index 00000000..052596b3
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Noteable.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-17.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.entity
+
+interface Noteable {
+
+ fun getNoteType(): Note.OwnerType
+ fun getNoteOwnerProfileId(): Int
+ fun getNoteOwnerId(): Long
+
+ var notes: MutableList
+
+ fun filterNotes() {
+ val type = getNoteType()
+ val profileId = getNoteOwnerProfileId()
+ notes.removeAll {
+ it.profileId != profileId || it.ownerType != type
+ }
+ }
+
+ fun hasNotes() = notes.isNotEmpty()
+ fun hasReplacingNotes() = notes.any { it.replacesOriginal }
+
+ fun getNoteSubstituteText(showNotes: Boolean): CharSequence? {
+ if (!showNotes)
+ return null
+ val note = notes.firstOrNull {
+ it.replacesOriginal
+ }
+ return note?.topicHtml ?: note?.bodyHtml
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt
index 1e8b8e0e..35208927 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt
@@ -10,7 +10,10 @@ import android.content.Intent
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.google.gson.JsonObject
+import com.mikepenz.iconics.typeface.IIcon
+import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import pl.szczodrzynski.edziennik.MainActivity
+import pl.szczodrzynski.edziennik.ext.pendingIntentFlag
@Entity(tableName = "notifications")
data class Notification(
@@ -19,6 +22,7 @@ data class Notification(
val title: String,
val text: String,
+ val textLong: String? = null,
val type: Int,
@@ -53,6 +57,7 @@ data class Notification(
const val TYPE_FEEDBACK_MESSAGE = 16
const val TYPE_AUTO_ARCHIVING = 17
const val TYPE_TEACHER_ABSENCE = 19
+ const val TYPE_NEW_SHARED_NOTE = 20
fun buildId(profileId: Int, type: Int, itemId: Long): Long {
return 1000000000000 + profileId*10000000000 + type*100000000 + itemId;
@@ -94,6 +99,22 @@ data class Notification(
fun getPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, MainActivity::class.java)
fillIntent(intent)
- return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT)
+ return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag())
+ }
+
+ fun getLargeIcon(): IIcon = when (type) {
+ TYPE_TIMETABLE_LESSON_CHANGE -> CommunityMaterial.Icon3.cmd_timetable
+ TYPE_NEW_GRADE -> CommunityMaterial.Icon3.cmd_numeric_5_box_outline
+ TYPE_NEW_EVENT -> CommunityMaterial.Icon.cmd_calendar_outline
+ TYPE_NEW_HOMEWORK -> CommunityMaterial.Icon3.cmd_notebook_outline
+ TYPE_NEW_SHARED_EVENT -> CommunityMaterial.Icon.cmd_calendar_outline
+ TYPE_NEW_SHARED_HOMEWORK -> CommunityMaterial.Icon3.cmd_notebook_outline
+ TYPE_NEW_MESSAGE -> CommunityMaterial.Icon.cmd_email_outline
+ TYPE_NEW_NOTICE -> CommunityMaterial.Icon.cmd_emoticon_outline
+ TYPE_NEW_ATTENDANCE -> CommunityMaterial.Icon.cmd_calendar_remove_outline
+ TYPE_LUCKY_NUMBER -> CommunityMaterial.Icon.cmd_emoticon_excited_outline
+ TYPE_NEW_ANNOUNCEMENT -> CommunityMaterial.Icon.cmd_bullhorn_outline
+ TYPE_NEW_SHARED_NOTE -> CommunityMaterial.Icon3.cmd_playlist_edit
+ else -> CommunityMaterial.Icon.cmd_bell_ring_outline
}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt
index 9e52dc81..b1615fbc 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Profile.kt
@@ -15,8 +15,10 @@ import androidx.room.Entity
import androidx.room.Ignore
import com.google.gson.JsonObject
import pl.droidsonroids.gif.GifDrawable
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.data.api.*
+import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.ProfileImageHolder
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.navlib.ImageHolder
@@ -129,6 +131,9 @@ open class Profile(
val isParent
get() = accountName != null
+ val accountOwnerName
+ get() = accountName ?: studentNameLong
+
val registerName
get() = when (loginStoreType) {
LOGIN_TYPE_LIBRUS -> "librus"
@@ -137,9 +142,12 @@ open class Profile(
LOGIN_TYPE_MOBIDZIENNIK -> "mobidziennik"
LOGIN_TYPE_PODLASIE -> "podlasie"
LOGIN_TYPE_EDUDZIENNIK -> "edudziennik"
- else -> null
+ else -> "unknown"
}
+ val canShare
+ get() = registration == REGISTRATION_ENABLED && !archived
+
override fun getImageDrawable(context: Context): Drawable {
if (archived) {
return context.getDrawableFromRes(pl.szczodrzynski.edziennik.R.drawable.profile_archived).also {
@@ -225,6 +233,10 @@ open class Profile(
MainActivity.DRAWER_ITEM_GRADES,
MainActivity.DRAWER_ITEM_HOMEWORK
)
+ LOGIN_TYPE_USOS -> listOf(
+ MainActivity.DRAWER_ITEM_TIMETABLE,
+ MainActivity.DRAWER_ITEM_AGENDA
+ )
else -> listOf(
MainActivity.DRAWER_ITEM_TIMETABLE,
MainActivity.DRAWER_ITEM_AGENDA,
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Subject.java b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Subject.java
index a034c785..1a4c46e4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Subject.java
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Subject.java
@@ -9,7 +9,7 @@ import androidx.room.Entity;
import java.util.List;
-import pl.szczodrzynski.edziennik.ExtensionsKt;
+import pl.szczodrzynski.edziennik.ext.GraphicsExtensionsKt;
@Entity(tableName = "subjects",
primaryKeys = {"profileId", "subjectId"})
@@ -31,7 +31,7 @@ public class Subject {
this.id = id;
this.longName = longName;
this.shortName = shortName;
- this.color = ExtensionsKt.colorFromName(longName);
+ this.color = GraphicsExtensionsKt.colorFromName(longName);
}
@Override
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Teacher.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Teacher.kt
index c41b8a7a..b192bc1d 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Teacher.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Teacher.kt
@@ -10,13 +10,14 @@ import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import pl.szczodrzynski.edziennik.R
-import pl.szczodrzynski.edziennik.fixName
-import pl.szczodrzynski.edziennik.getNameInitials
-import pl.szczodrzynski.edziennik.join
+import pl.szczodrzynski.edziennik.ext.fixName
+import pl.szczodrzynski.edziennik.ext.getNameInitials
+import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.ext.join
import java.util.*
@Entity(tableName = "teachers",
- primaryKeys = ["profileId", "teacherId"])
+ primaryKeys = ["profileId", "teacherId"])
open class Teacher {
companion object {
const val TYPE_TEACHER = 0 // 1
@@ -26,6 +27,7 @@ open class Teacher {
const val TYPE_SECRETARIAT = 4 // 16
const val TYPE_PRINCIPAL = 5 // 32
const val TYPE_SCHOOL_ADMIN = 6 // 64
+
// not teachers
const val TYPE_SPECIALIST = 7 // 128
const val TYPE_SUPER_ADMIN = 10 // 1024
@@ -36,7 +38,8 @@ open class Teacher {
const val TYPE_OTHER = 24 // 16777216
const val IS_TEACHER_MASK = 127
- val types: List by lazy { listOf(
+ val types: List by lazy {
+ listOf(
TYPE_TEACHER,
TYPE_EDUCATOR,
TYPE_PEDAGOGUE,
@@ -51,7 +54,8 @@ open class Teacher {
TYPE_PARENTS_COUNCIL,
TYPE_SCHOOL_PARENTS_COUNCIL,
TYPE_OTHER
- ) }
+ )
+ }
fun typeName(c: Context, type: Int, typeDescription: String? = null): String {
val suffix = typeDescription?.let { " ($typeDescription)" } ?: ""
@@ -94,6 +98,9 @@ open class Teacher {
@ColumnInfo(name = "teacherTypeDescription")
var typeDescription: String? = null
+ @ColumnInfo(name = "teacherSubjects")
+ var subjects = mutableListOf()
+
fun isType(checkingType: Int): Boolean {
return type and (1 shl checkingType) >= 1
}
@@ -105,19 +112,29 @@ open class Teacher {
type = type or (1 shl i)
}
+ fun addSubject(subjectId: Long) = subjects.add(subjectId)
+
fun unsetTeacherType(i: Int) {
type = type and (1 shl i).inv()
}
- fun getTypeText(c: Context): String {
- val list = mutableListOf()
+ fun getTypeText(c: Context, subjectList: List? = null): String {
+ val roles = mutableListOf()
types.forEach {
if (isType(it))
- list += typeName(c, it, typeDescription)
+ roles += typeName(c, it, typeDescription)
}
- return list.join(", ")
- }
+ if (subjectList != null && subjects.isNotEmpty()) {
+ return subjects.joinToString(
+ prefix = if (roles.isNotEmpty()) roles.joinToString(postfix = ": ") else "",
+ transform = { subjectId ->
+ subjectList.firstOrNull { it.id == subjectId }?.longName ?: ""
+ },
+ )
+ }
+ return roles.joinToString()
+ }
@Ignore
var image: Bitmap? = null
@@ -128,6 +145,7 @@ open class Teacher {
*/
@Ignore
var recipientDisplayName: CharSequence? = null
+
/**
* Used in Message composing - determining the priority
* of search result, based on the search phrase match
@@ -142,8 +160,6 @@ open class Teacher {
this.id = id
}
-
-
@Ignore
constructor(profileId: Int, id: Long, name: String, surname: String) {
this.profileId = profileId
@@ -170,6 +186,7 @@ open class Teacher {
this.surname = it.surname
this.type = it.type
this.typeDescription = it.typeDescription
+ this.subjects = it.subjects
this.image = it.image
this.recipientDisplayName = it.recipientDisplayName
}
@@ -195,6 +212,7 @@ open class Teacher {
", name='" + name + '\'' +
", surname='" + surname + '\'' +
", type=" + dumpType() +
+ ", subjects=" + subjects.joinToString() +
", typeDescription='" + typeDescription + '\'' +
'}'
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AnnouncementFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AnnouncementFull.kt
index 5b4cb711..f82213dd 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AnnouncementFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AnnouncementFull.kt
@@ -3,7 +3,10 @@
*/
package pl.szczodrzynski.edziennik.data.db.full
+import androidx.room.Relation
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
import pl.szczodrzynski.edziennik.utils.models.Date
class AnnouncementFull(
@@ -16,10 +19,16 @@ class AnnouncementFull(
subject, text,
startDate, endDate,
teacherId, addedDate
-) {
+), Noteable {
var teacherName: String? = null
// metadata
var seen = false
var notified = false
+
+ @Relation(parentColumn = "announcementId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.ANNOUNCEMENT
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AttendanceFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AttendanceFull.kt
index f235fafd..c1440ab5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AttendanceFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/AttendanceFull.kt
@@ -3,7 +3,10 @@
*/
package pl.szczodrzynski.edziennik.data.db.full
+import androidx.room.Relation
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -17,7 +20,7 @@ class AttendanceFull(
baseType, typeName, typeShort, typeSymbol, typeColor,
date, startTime, semester,
teacherId, subjectId, addedDate
-) {
+), Noteable {
var teacherName: String? = null
var subjectLongName: String? = null
var subjectShortName: String? = null
@@ -26,4 +29,10 @@ class AttendanceFull(
var seen = false
get() = field || baseType == TYPE_PRESENT
var notified = false
+
+ @Relation(parentColumn = "attendanceId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.ATTENDANCE
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/EventFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/EventFull.kt
index 01e85395..3eb681f2 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/EventFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/EventFull.kt
@@ -3,8 +3,14 @@
*/
package pl.szczodrzynski.edziennik.data.db.full
+import androidx.room.Ignore
+import androidx.room.Relation
import pl.szczodrzynski.edziennik.data.db.entity.Event
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
+import pl.szczodrzynski.edziennik.ui.search.Searchable
+import pl.szczodrzynski.edziennik.utils.html.BetterHtml
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -16,7 +22,7 @@ class EventFull(
profileId, id, date, time,
topic, color, type,
teacherId, subjectId, teamId, addedDate
-) {
+), Searchable, Noteable {
constructor(event: Event, metadata: Metadata? = null) : this(
event.profileId, event.id, event.date, event.time,
event.topic, event.color, event.type,
@@ -26,6 +32,7 @@ class EventFull(
sharedBy = it.sharedBy
sharedByName = it.sharedByName
blacklisted = it.blacklisted
+ isDownloaded = it.isDownloaded
homeworkBody = it.homeworkBody
attachmentIds = it.attachmentIds
attachmentNames = it.attachmentNames
@@ -45,10 +52,70 @@ class EventFull(
var teamName: String? = null
var teamCode: String? = null
+ @delegate:Ignore
+ @delegate:Transient
+ val topicHtml by lazy {
+ BetterHtml.fromHtml(context = null, topic, nl2br = true)
+ }
+
+ @delegate:Ignore
+ @delegate:Transient
+ val bodyHtml by lazy {
+ homeworkBody?.let {
+ BetterHtml.fromHtml(context = null, it, nl2br = true)
+ }
+ }
+
+ @Ignore
+ @Transient
+ override var searchPriority = 0
+
+ @Ignore
+ @Transient
+ override var searchHighlightText: String? = null
+
+ @delegate:Ignore
+ @delegate:Transient
+ override val searchKeywords by lazy {
+ listOf(
+ listOf(topicHtml.toString(), bodyHtml?.toString()),
+ attachmentNames,
+ listOf(subjectLongName),
+ listOf(teacherName),
+ listOf(sharedByName),
+ )
+ }
+
+ override fun compareTo(other: Searchable<*>): Int {
+ if (other !is EventFull)
+ return 0
+ return when {
+ // ascending sorting
+ searchPriority > other.searchPriority -> 1
+ searchPriority < other.searchPriority -> -1
+ // ascending sorting
+ date > other.date -> 1
+ date < other.date -> -1
+ // ascending sorting
+ (time?.value ?: 0) > (other.time?.value ?: 0) -> 1
+ (time?.value ?: 0) < (other.time?.value ?: 0) -> -1
+ // ascending sorting
+ addedDate > other.addedDate -> 1
+ addedDate < other.addedDate -> -1
+ else -> 0
+ }
+ }
+
// metadata
var seen = false
var notified = false
val eventColor
get() = color ?: typeColor ?: 0xff2196f3.toInt()
+
+ @Relation(parentColumn = "eventId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.EVENT
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/GradeFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/GradeFull.kt
index f8d90c05..fc6e7f19 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/GradeFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/GradeFull.kt
@@ -3,7 +3,10 @@
*/
package pl.szczodrzynski.edziennik.data.db.full
+import androidx.room.Relation
import pl.szczodrzynski.edziennik.data.db.entity.Grade
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
class GradeFull(
profileId: Int, id: Long, name: String, type: Int,
@@ -15,7 +18,7 @@ class GradeFull(
value, weight, color,
category, description, comment,
semester, teacherId, subjectId, addedDate
-) {
+), Noteable {
var teacherName: String? = null
var subjectLongName: String? = null
var subjectShortName: String? = null
@@ -23,4 +26,10 @@ class GradeFull(
// metadata
var seen = false
var notified = false
+
+ @Relation(parentColumn = "gradeId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.GRADE
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/LessonFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/LessonFull.kt
index 0e9542b6..a2982a30 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/LessonFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/LessonFull.kt
@@ -4,15 +4,18 @@
package pl.szczodrzynski.edziennik.data.db.full
import android.content.Context
+import androidx.room.Relation
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
import pl.szczodrzynski.edziennik.utils.models.Time
class LessonFull(
profileId: Int, id: Long
) : Lesson(
profileId, id
-) {
+), Noteable {
var subjectName: String? = null
var teacherName: String? = null
var teamName: String? = null
@@ -133,4 +136,10 @@ class LessonFull(
// metadata
var seen: Boolean = false
var notified: Boolean = false
+
+ @Relation(parentColumn = "id", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.LESSON
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/MessageFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/MessageFull.kt
index 3fdcdd0d..232095d8 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/MessageFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/MessageFull.kt
@@ -7,6 +7,10 @@ import androidx.room.Ignore
import androidx.room.Relation
import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
+import pl.szczodrzynski.edziennik.ui.search.Searchable
+import pl.szczodrzynski.edziennik.utils.html.BetterHtml
class MessageFull(
profileId: Int, id: Long, type: Int,
@@ -16,7 +20,7 @@ class MessageFull(
profileId, id, type,
subject, body, senderId,
addedDate
-) {
+), Searchable, Noteable {
var senderName: String? = null
@Relation(parentColumn = "messageId", entityColumn = "messageId", entity = MessageRecipient::class)
var recipients: MutableList? = null
@@ -27,12 +31,64 @@ class MessageFull(
return this
}
+ @delegate:Ignore
+ @delegate:Transient
+ val bodyHtml by lazy {
+ body?.let {
+ BetterHtml.fromHtml(context = null, it)
+ }
+ }
+
@Ignore
- var filterWeight = 0
+ @Transient
+ override var searchPriority = 0
+
@Ignore
- var searchHighlightText: String? = null
+ @Transient
+ override var searchHighlightText: String? = null
+
+ @delegate:Ignore
+ @delegate:Transient
+ override val searchKeywords by lazy {
+ listOf(
+ when {
+ isSent -> recipients?.map { it.fullName }
+ else -> listOf(senderName)
+ },
+ listOf(subject),
+ listOf(bodyHtml?.toString()),
+ attachmentNames,
+ )
+ }
+
+ override fun compareTo(other: Searchable<*>): Int {
+ if (other !is MessageFull)
+ return 0
+ return when {
+ // ascending sorting
+ searchPriority > other.searchPriority -> 1
+ searchPriority < other.searchPriority -> -1
+ // descending sorting (1. true, 2. false)
+ isStarred && !other.isStarred -> -1
+ !isStarred && other.isStarred -> 1
+ // descending sorting
+ addedDate > other.addedDate -> -1
+ addedDate < other.addedDate -> 1
+ else -> 0
+ }
+ }
+
+ @Ignore
+ @Transient
+ var readByEveryone = true
// metadata
var seen = false
var notified = false
+
+ @Relation(parentColumn = "messageId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.MESSAGE
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/NoticeFull.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/NoticeFull.kt
index 25aee14d..6f8d6fb0 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/NoticeFull.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/full/NoticeFull.kt
@@ -3,6 +3,9 @@
*/
package pl.szczodrzynski.edziennik.data.db.full
+import androidx.room.Relation
+import pl.szczodrzynski.edziennik.data.db.entity.Note
+import pl.szczodrzynski.edziennik.data.db.entity.Noteable
import pl.szczodrzynski.edziennik.data.db.entity.Notice
class NoticeFull(
@@ -13,10 +16,16 @@ class NoticeFull(
profileId, id, type, semester,
text, category, points,
teacherId, addedDate
-) {
+), Noteable {
var teacherName: String? = null
// metadata
var seen = false
var notified = false
+
+ @Relation(parentColumn = "noticeId", entityColumn = "noteOwnerId", entity = Note::class)
+ override lateinit var notes: MutableList
+ override fun getNoteType() = Note.OwnerType.BEHAVIOR
+ override fun getNoteOwnerProfileId() = profileId
+ override fun getNoteOwnerId() = id
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration72.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration72.kt
index 88567b47..65f9c4ce 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration72.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration72.kt
@@ -6,7 +6,7 @@ package pl.szczodrzynski.edziennik.data.db.migration
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
-import pl.szczodrzynski.edziennik.crc32
+import pl.szczodrzynski.edziennik.ext.crc32
class Migration72 : Migration(71, 72) {
override fun migrate(database: SupportSQLiteDatabase) {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration92.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration92.kt
new file mode 100644
index 00000000..3010a371
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration92.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-4-15.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import android.content.ContentValues
+import android.database.sqlite.SQLiteDatabase
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.COLOR_ELEARNING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_ELEARNING
+import pl.szczodrzynski.edziennik.data.db.entity.Event.Companion.TYPE_INFORMATION
+import pl.szczodrzynski.edziennik.data.db.entity.EventType.Companion.SOURCE_DEFAULT
+import pl.szczodrzynski.edziennik.data.db.entity.EventType.Companion.SOURCE_REGISTER
+import pl.szczodrzynski.edziennik.ext.getInt
+
+class Migration92 : Migration(91, 92) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // make eventTypeName not nullable
+ database.execSQL("ALTER TABLE eventTypes RENAME TO _eventTypes;")
+ database.execSQL("CREATE TABLE eventTypes (" +
+ "profileId INTEGER NOT NULL, " +
+ "eventType INTEGER NOT NULL, " +
+ "eventTypeName TEXT NOT NULL, " +
+ "eventTypeColor INTEGER NOT NULL, " +
+ "PRIMARY KEY(profileId,eventType)" +
+ ");")
+ database.execSQL("INSERT INTO eventTypes " +
+ "(profileId, eventType, eventTypeName, eventTypeColor) " +
+ "SELECT profileId, eventType, eventTypeName, eventTypeColor " +
+ "FROM _eventTypes;")
+ database.execSQL("DROP TABLE _eventTypes;")
+
+ // add columns for order and source
+ database.execSQL("ALTER TABLE eventTypes ADD COLUMN eventTypeOrder INTEGER NOT NULL DEFAULT 0;")
+ database.execSQL("ALTER TABLE eventTypes ADD COLUMN eventTypeSource INTEGER NOT NULL DEFAULT 0;")
+
+ // migrate existing types to show correct order and source
+ database.execSQL("UPDATE eventTypes SET eventTypeOrder = eventType + 102;")
+ database.execSQL("UPDATE eventTypes SET eventTypeSource = $SOURCE_REGISTER WHERE eventType > $TYPE_INFORMATION;")
+
+ // add new e-learning type
+ val cursor = database.query("SELECT profileId FROM profiles;")
+ cursor.use {
+ while (it.moveToNext()) {
+ val values = ContentValues().apply {
+ put("profileId", it.getInt("profileId"))
+ put("eventType", TYPE_ELEARNING)
+ put("eventTypeName", "lekcja online")
+ put("eventTypeColor", COLOR_ELEARNING)
+ put("eventTypeOrder", 100)
+ put("eventTypeSource", SOURCE_DEFAULT)
+ }
+
+ database.insert("eventTypes", SQLiteDatabase.CONFLICT_REPLACE, values)
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration93.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration93.kt
new file mode 100644
index 00000000..9d5df5b3
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration93.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-5-26.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration93 : Migration(92, 93) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // notifications - long text
+ database.execSQL("ALTER TABLE notifications ADD COLUMN textLong TEXT DEFAULT NULL;")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration94.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration94.kt
new file mode 100644
index 00000000..84df9c59
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration94.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-1.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+import pl.szczodrzynski.edziennik.data.db.entity.Event
+import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
+
+class Migration94 : Migration(93, 94) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // events - is downloaded flag
+
+ // get all profiles using Mobidziennik
+ database.execSQL("CREATE TABLE _94_ids (id INTEGER NOT NULL);")
+ database.execSQL("INSERT INTO _94_ids SELECT profileId FROM profiles JOIN loginStores USING(loginStoreId) WHERE loginStores.loginStoreType = ${LoginStore.LOGIN_TYPE_MOBIDZIENNIK};")
+
+ database.execSQL("ALTER TABLE events ADD COLUMN eventIsDownloaded INT NOT NULL DEFAULT 1;")
+ // set isDownloaded = 0 for information events in Mobidziennik
+ database.execSQL("UPDATE events SET eventIsDownloaded = 0 WHERE profileId IN (SELECT id FROM _94_ids) AND eventType = ${Event.TYPE_INFORMATION};")
+
+ database.execSQL("DROP TABLE _94_ids;")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration95.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration95.kt
new file mode 100644
index 00000000..0281de6b
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration95.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-1.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration95 : Migration(94, 95) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // timetable - is extra flag
+ database.execSQL("ALTER TABLE timetable ADD COLUMN isExtra INT NOT NULL DEFAULT 0;")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration96.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration96.kt
new file mode 100644
index 00000000..e8315aa3
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration96.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Antoni Czaplicki 2021-10-17.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration96 : Migration(95, 96) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // teachers - associated subjects list
+ database.execSQL("ALTER TABLE teachers ADD COLUMN teacherSubjects TEXT NOT NULL DEFAULT '[]';")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration97.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration97.kt
new file mode 100644
index 00000000..13014ecb
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration97.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-10-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration97 : Migration(96, 97) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // notes
+ database.execSQL("""CREATE TABLE notes (
+ profileId INTEGER NOT NULL,
+ noteId INTEGER NOT NULL,
+ noteOwnerType TEXT,
+ noteOwnerId INTEGER,
+ noteReplacesOriginal INTEGER NOT NULL,
+ noteTopic TEXT,
+ noteBody TEXT NOT NULL,
+ noteColor INTEGER,
+ noteSharedBy TEXT,
+ noteSharedByName TEXT,
+ addedDate INTEGER NOT NULL,
+ PRIMARY KEY(noteId)
+ );""")
+ database.execSQL("CREATE INDEX IF NOT EXISTS index_notes_profileId_noteOwnerType_noteOwnerId ON notes (profileId, noteOwnerType, noteOwnerId);")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration98.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration98.kt
new file mode 100644
index 00000000..91003fd9
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/migration/Migration98.kt
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-10-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.db.migration
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration98 : Migration(97, 98) {
+ override fun migrate(database: SupportSQLiteDatabase) {
+ // timetable colors - override color in lesson object
+ database.execSQL("ALTER TABLE timetable ADD COLUMN color INT DEFAULT NULL;")
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseService.kt
index 6396a87c..80dcd4ea 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseService.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/FirebaseService.kt
@@ -13,7 +13,7 @@ import com.google.firebase.iid.zzad
import com.google.firebase.iid.zzaz
import com.google.firebase.messaging.zzc
import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.ext.*
import java.util.*
import com.google.firebase.messaging.zzo.zza as logNotificationOpen
import com.google.firebase.messaging.zzo.zza as logNotificationReceived
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt
index 1d563c34..4f90ac67 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyAppFirebase.kt
@@ -15,6 +15,10 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailability
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
import pl.szczodrzynski.edziennik.data.api.task.PostNotifications
import pl.szczodrzynski.edziennik.data.db.entity.*
+import pl.szczodrzynski.edziennik.ext.getInt
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getNotificationTitle
+import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.sync.UpdateWorker
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
@@ -43,6 +47,15 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
message.data.getLong("eventId") ?: return@run,
message.data.getString("message") ?: return@run
)
+ "sharedNote" -> sharedNote(
+ message.data.getString("shareTeamCode") ?: return@run,
+ message.data.getString("note") ?: return@run,
+ message.data.getString("message") ?: return@run,
+ )
+ "unsharedNote" -> unsharedNote(
+ message.data.getString("unshareTeamCode") ?: return@run,
+ message.data.getLong("noteId") ?: return@run,
+ )
"serverMessage",
"unpairedBrowser" -> serverMessage(
message.data.getString("title") ?: "",
@@ -60,7 +73,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
) ?: return@launch
app.config.sync.registerAvailability = data
if (EventBus.getDefault().hasSubscriberForEvent(RegisterAvailabilityEvent::class.java)) {
- EventBus.getDefault().postSticky(RegisterAvailabilityEvent(data))
+ EventBus.getDefault().postSticky(RegisterAvailabilityEvent())
}
}
}
@@ -104,7 +117,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
}
private fun sharedEvent(teamCode: String, jsonStr: String, message: String) {
- val json = JsonParser().parse(jsonStr).asJsonObject
+ val json = JsonParser.parseString(jsonStr).asJsonObject
val teams = app.db.teamDao().allNow
// not used, as the server provides a sharing message
//val eventTypes = app.db.eventTypeDao().allNow
@@ -115,14 +128,14 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@forEach
- if (profile.registration != Profile.REGISTRATION_ENABLED)
+ if (!profile.canShare)
return@forEach
val event = Event(
profileId = team.profileId,
id = json.getLong("id") ?: return,
date = json.getInt("eventDate")?.let { Date.fromValue(it) } ?: return,
time = json.getInt("startTime")?.let { Time.fromValue(it) },
- topic = json.getString("topic") ?: "",
+ topic = json.getString("topicHtml") ?: json.getString("topic") ?: "",
color = json.getInt("color"),
type = json.getLong("type") ?: 0,
teacherId = json.getLong("teacherId") ?: -1,
@@ -135,20 +148,23 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
event.sharedBy = json.getString("sharedBy")
event.sharedByName = json.getString("sharedByName")
- if (profile.userCode == event.sharedBy) event.sharedBy = "self"
+ if (profile.userCode == event.sharedBy) {
+ event.sharedBy = "self"
+ event.addedManually = true
+ }
val metadata = Metadata(
event.profileId,
- if (event.type == Event.TYPE_HOMEWORK) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT,
+ if (event.isHomework) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT,
event.id,
false,
true
)
- val type = if (event.type == Event.TYPE_HOMEWORK) Notification.TYPE_NEW_SHARED_HOMEWORK else Notification.TYPE_NEW_SHARED_EVENT
+ val type = if (event.isHomework) Notification.TYPE_NEW_SHARED_HOMEWORK else Notification.TYPE_NEW_SHARED_EVENT
val notificationFilter = app.config.getFor(event.profileId).sync.notificationFilter
- if (!notificationFilter.contains(type)) {
+ if (!notificationFilter.contains(type) && event.sharedBy != "self" && event.date >= Date.getToday()) {
val notification = Notification(
id = Notification.buildId(event.profileId, type, event.id),
title = app.getNotificationTitle(type),
@@ -156,7 +172,7 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
type = type,
profileId = profile.id,
profileName = profile.name,
- viewId = if (event.type == Event.TYPE_HOMEWORK) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
+ viewId = if (event.isHomework) MainActivity.DRAWER_ITEM_HOMEWORK else MainActivity.DRAWER_ITEM_AGENDA,
addedDate = event.addedDate
).addExtra("eventId", event.id).addExtra("eventDate", event.date.value.toLong())
notificationList += notification
@@ -179,14 +195,13 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@forEach
- if (profile.registration != Profile.REGISTRATION_ENABLED)
+ if (!profile.canShare)
return@forEach
val notificationFilter = app.config.getFor(team.profileId).sync.notificationFilter
if (!notificationFilter.contains(Notification.TYPE_REMOVED_SHARED_EVENT)) {
val notification = Notification(
- id = Notification.buildId(profile.id
- ?: 0, Notification.TYPE_REMOVED_SHARED_EVENT, eventId),
+ id = Notification.buildId(profile.id, Notification.TYPE_REMOVED_SHARED_EVENT, eventId),
title = app.getNotificationTitle(Notification.TYPE_REMOVED_SHARED_EVENT),
text = message,
type = Notification.TYPE_REMOVED_SHARED_EVENT,
@@ -203,4 +218,71 @@ class SzkolnyAppFirebase(val app: App, val profiles: List, val message:
PostNotifications(app, notificationList)
}
}
+
+ private fun sharedNote(teamCode: String, jsonStr: String, message: String) {
+ val note = app.gson.fromJson(jsonStr, Note::class.java)
+ val noteSharedBy = note.sharedBy
+ val teams = app.db.teamDao().allNow
+ // not used, as the server provides a sharing message
+ //val eventTypes = app.db.eventTypeDao().allNow
+
+ val notes = mutableListOf()
+ val notificationList = mutableListOf()
+
+ teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
+ val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@forEach
+ if (!profile.canShare)
+ return@forEach
+ note.profileId = team.profileId
+ if (profile.userCode == note.sharedBy) {
+ note.sharedBy = "self"
+ } else {
+ note.sharedBy = noteSharedBy
+ }
+
+ if (!app.noteManager.hasValidOwner(note))
+ return@forEach
+
+ notes += note
+
+ val hadNote = app.db.noteDao().getNow(note.profileId, note.id) != null
+ // skip creating notifications
+ if (hadNote)
+ return@forEach
+
+ val type = Notification.TYPE_NEW_SHARED_NOTE
+ val notificationFilter = app.config.getFor(note.profileId).sync.notificationFilter
+
+ if (!notificationFilter.contains(type) && note.sharedBy != "self") {
+ val notification = Notification(
+ id = Notification.buildId(note.profileId, type, note.id),
+ title = app.getNotificationTitle(type),
+ text = message,
+ type = type,
+ profileId = profile.id,
+ profileName = profile.name,
+ viewId = MainActivity.DRAWER_ITEM_HOME,
+ addedDate = note.addedDate
+ ).addExtra("noteId", note.id)
+ notificationList += notification
+ }
+ }
+ app.db.noteDao().addAll(notes)
+ if (notificationList.isNotEmpty()) {
+ app.db.notificationDao().addAll(notificationList)
+ PostNotifications(app, notificationList)
+ }
+ }
+
+ private fun unsharedNote(teamCode: String, noteId: Long) {
+ val teams = app.db.teamDao().allNow
+
+ teams.filter { it.code == teamCode }.distinctBy { it.profileId }.forEach { team ->
+ val profile = profiles.firstOrNull { it.id == team.profileId } ?: return@forEach
+ if (!profile.canShare)
+ return@forEach
+
+ app.db.noteDao().remove(team.profileId, noteId)
+ }
+ }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyLibrusFirebase.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyLibrusFirebase.kt
index cc59faf4..a9a183e5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyLibrusFirebase.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyLibrusFirebase.kt
@@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.*
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getString
class SzkolnyLibrusFirebase(val app: App, val profiles: List, val message: FirebaseService.Message) {
/*{
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyMobidziennikFirebase.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyMobidziennikFirebase.kt
index b097dbed..d5b6c077 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyMobidziennikFirebase.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/firebase/SzkolnyMobidziennikFirebase.kt
@@ -14,8 +14,8 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
import pl.szczodrzynski.edziennik.data.db.entity.Profile
-import pl.szczodrzynski.edziennik.getLong
-import pl.szczodrzynski.edziennik.getString
+import pl.szczodrzynski.edziennik.ext.getLong
+import pl.szczodrzynski.edziennik.ext.getString
class SzkolnyMobidziennikFirebase(val app: App, val profiles: List