[API/Usos] Store term names, add term ID to grades

This commit is contained in:
Kuba Szczodrzyński 2025-01-31 21:31:02 +01:00
parent d44b85073a
commit 6de7ee9cee
No known key found for this signature in database
GPG Key ID: 43037AC62A600562
3 changed files with 62 additions and 21 deletions

View File

@ -4,6 +4,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.usos
import com.google.gson.JsonObject
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.api.models.Data
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
@ -73,4 +74,9 @@ class DataUsos(
get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", 0); return mStudentId ?: 0 }
set(value) { profile["studentId"] = value; mStudentId = value }
private var mStudentId: Int? = null
var termNames: Map<String, String> = mapOf()
get() { mTermNames = mTermNames ?: profile?.getStudentData("termNames", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mTermNames ?: mapOf() }
set(value) { profile["termNames"] = app.gson.toJson(value); mTermNames = value }
private var mTermNames: Map<String, String>? = null
}

View File

@ -33,6 +33,8 @@ class UsosApiExamReports(
const val TAG = "UsosApiExamReports"
}
private val missingTermNames = mutableSetOf<String>()
init {
apiRequest<JsonObject>(
tag = TAG,
@ -64,12 +66,16 @@ class UsosApiExamReports(
data.toRemove.add(DataRemoveModel.Grades.all())
data.setSyncNext(ENDPOINT_USOS_API_EXAM_REPORTS, SYNC_ALWAYS)
onSuccess(ENDPOINT_USOS_API_EXAM_REPORTS)
if (missingTermNames.isEmpty())
onSuccess(ENDPOINT_USOS_API_EXAM_REPORTS)
else
UsosApiTerms(data, lastSync, onSuccess, missingTermNames)
}
}
private fun processResponse(json: JsonObject): Boolean {
for ((_, courseEditionEl) in json.entrySet()) {
for ((termId, courseEditionEl) in json.entrySet()) {
if (!courseEditionEl.isJsonObject)
continue
for ((courseId, examReportsEl) in courseEditionEl.asJsonObject.entrySet()) {
@ -79,14 +85,14 @@ class UsosApiExamReports(
if (!examReportEl.isJsonObject)
continue
val examReport = examReportEl.asJsonObject
processExamReport(courseId, examReport)
processExamReport(termId, courseId, examReport)
}
}
}
return true
}
private fun processExamReport(courseId: String, examReport: JsonObject) {
private fun processExamReport(termId: String, courseId: String, examReport: JsonObject) {
val typeDescription = examReport.getLangString("type_description")
val courseUnit = examReport.getJsonObject("course_unit")
?: return
@ -119,6 +125,10 @@ class UsosApiExamReports(
val classType = gradeCategory?.columns?.get(0)
val value = valueSymbol.toFloatOrNull() ?: 0.0f
if (termId !in data.termNames) {
missingTermNames.add(termId)
}
val gradeObject = Grade(
profileId = profileId,
id = examId * 10L + sessionNumber,
@ -127,7 +137,7 @@ class UsosApiExamReports(
value = value,
weight = if (countsIntoAverage == "T") gradeCategory?.weight ?: 0.0f else 0.0f,
color = (if (passes == true) 0xFF465FB3 else 0xFFB71C1C).toInt(),
category = typeDescription,
category = "$termId$$typeDescription",
description = listOfNotNull(classType, sessionDescription).join(" - "),
comment = comment,
semester = 1,

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.usos.data.api
import com.google.gson.JsonArray
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_TERMS
@ -16,34 +17,57 @@ class UsosApiTerms(
override val data: DataUsos,
override val lastSync: Long?,
val onSuccess: (endpointId: Int) -> Unit,
names: Set<String>? = null,
) : UsosApi(data, lastSync) {
companion object {
const val TAG = "UsosApiTerms"
}
init {
apiRequest<JsonArray>(
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
}
if (names != null) {
apiRequest<JsonObject>(
tag = TAG,
service = "terms/terms",
params = mapOf("term_ids" to names.joinToString("|")),
responseType = ResponseType.OBJECT,
) { json, response ->
if (!processResponse(json.entrySet().map { it.value.asJsonObject })) {
data.error(TAG, ERROR_USOS_API_INCOMPLETE_RESPONSE, response)
return@apiRequest
}
data.setSyncNext(ENDPOINT_USOS_API_TERMS, 2 * DAY)
onSuccess(ENDPOINT_USOS_API_TERMS)
data.setSyncNext(ENDPOINT_USOS_API_TERMS, 2 * DAY)
onSuccess(ENDPOINT_USOS_API_TERMS)
}
} else {
apiRequest<JsonArray>(
tag = TAG,
service = "terms/search",
params = mapOf("query" to Date.getToday().year.toString()),
responseType = ResponseType.ARRAY,
) { json, response ->
if (!processResponse(json.asJsonObjectList())) {
data.error(TAG, ERROR_USOS_API_INCOMPLETE_RESPONSE, response)
return@apiRequest
}
data.setSyncNext(ENDPOINT_USOS_API_TERMS, 2 * DAY)
onSuccess(ENDPOINT_USOS_API_TERMS)
}
}
}
private fun processResponse(json: JsonArray): Boolean {
private fun processResponse(terms: List<JsonObject>): Boolean {
val profile = profile ?: return false
val termNames = data.termNames.toMutableMap()
val today = Date.getToday()
for (term in json.asJsonObjectList()) {
for (term in terms) {
val id = term.getString("id")
val name = term.getLangString("name")
val orderKey = term.getInt("order_key")
if (id != null && name != null)
termNames[id] = "$orderKey$$name"
if (!term.getBoolean("is_active", false))
continue
val startDate = term.getString("start_date")?.let { Date.fromY_m_d(it) } ?: continue
@ -67,6 +91,7 @@ class UsosApiTerms(
if (profile.dateYearEnd <= profile.dateSemester1Start)
profile.dateYearEnd =
profile.dateSemester1Start.clone().setYear(profile.dateSemester1Start.year + 1)
data.termNames = termNames
return true
}
}