From cf255078509be3b28a6f529e2cb68dcb8d370c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sun, 16 Oct 2022 18:41:37 +0200 Subject: [PATCH] [API/Usos] Save lecturers as teachers. Add team class. --- .../data/api/edziennik/usos/data/UsosApi.kt | 8 +++ .../data/api/edziennik/usos/data/UsosData.kt | 7 +- .../edziennik/usos/data/api/UsosApiCourses.kt | 5 +- .../edziennik/usos/data/api/UsosApiUser.kt | 72 +++++++++++++++++++ .../edziennik/data/api/models/Data.kt | 28 +++++--- 5 files changed, 104 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/usos/data/api/UsosApiUser.kt 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 index 829fefa4..d81eff58 100644 --- 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 @@ -41,6 +41,14 @@ open class UsosApi(open val data: DataUsos, open val lastSync: Long?) { 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() 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 index 6f3b6039..d688bebf 100644 --- 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 @@ -10,6 +10,7 @@ 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) { @@ -41,10 +42,10 @@ class UsosData(val data: DataUsos, val onSuccess: () -> Unit) { 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 -> { + ENDPOINT_USOS_API_USER -> { data.startProgress(R.string.edziennik_progress_endpoint_student_info) -// TemplateWebSample(data, lastSync, onSuccess) - }*/ + UsosApiUser(data, lastSync, onSuccess) + } ENDPOINT_USOS_API_TERMS -> { data.startProgress(R.string.edziennik_progress_endpoint_school_info) UsosApiTerms(data, lastSync, onSuccess) 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 index 613d9f08..e93c63dd 100644 --- 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 @@ -36,7 +36,7 @@ class UsosApiCourses( "group_number", // "class_type", "class_type_id", - // "lecturers", + "lecturers", ), ), ), @@ -69,6 +69,7 @@ class UsosApiCourses( 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, @@ -76,7 +77,7 @@ class UsosApiCourses( "${profile?.studentClassName} $classTypeId$groupNumber - $courseName", 2, "${data.schoolId}:${courseId} $classTypeId$groupNumber", - -1, + lecturers.firstOrNull() ?: -1L, )) hasValidTeam = 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/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt index c02c666a..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 @@ -449,14 +449,14 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt return team } - fun getTeacher(firstName: String, lastName: String, loginId: String? = null): Teacher { + 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) + 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) + return validateTeacher(teacher, firstNameChar.toString(), lastName, loginId, null) } fun getTeacherByLastFirst(nameLastFirst: String, loginId: String? = null): Teacher { @@ -464,9 +464,9 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt val teacher = teacherList.singleOrNull { it.fullNameLastFirst == nameLastFirst } val nameParts = nameLastFirst.split(" ", limit = 2) return if (nameParts.size == 1) - validateTeacher(teacher, nameParts[0], "", loginId) + validateTeacher(teacher, nameParts[0], "", loginId, null) else - validateTeacher(teacher, nameParts[1], nameParts[0], loginId) + validateTeacher(teacher, nameParts[1], nameParts[0], loginId, null) } fun getTeacherByFirstLast(nameFirstLast: String, loginId: String? = null): Teacher { @@ -474,9 +474,9 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt val teacher = teacherList.singleOrNull { it.fullName == nameFirstLast } val nameParts = nameFirstLast.split(" ", limit = 2) return if (nameParts.size == 1) - validateTeacher(teacher, nameParts[0], "", loginId) + validateTeacher(teacher, nameParts[0], "", loginId, null) else - validateTeacher(teacher, nameParts[0], nameParts[1], loginId) + validateTeacher(teacher, nameParts[0], nameParts[1], loginId, null) } fun getTeacherByFDotLast(nameFDotLast: String, loginId: String? = null): Teacher { @@ -495,10 +495,16 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt getTeacher(nameParts[0][0], nameParts[1], loginId) } - private fun validateTeacher(teacher: Teacher?, firstName: String, lastName: String, loginId: String?): Teacher { - val obj = teacher ?: Teacher(profileId, -1, firstName, lastName, loginId).apply { - id = fullName.crc32() - teacherList[id] = this + 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)