From ae10b8abbdc821f155bb501c095c9eec35a90068 Mon Sep 17 00:00:00 2001 From: Kacper Ziubryniewicz Date: Sat, 23 Nov 2019 19:40:32 +0100 Subject: [PATCH] [APIv2/Idziennik] Add new timetable getting and fix week start --- .../api/v2/idziennik/DataIdziennik.kt | 2 + .../data/web/IdziennikWebTimetable.kt | 159 ++++++++++++------ .../v2/librus/data/api/LibrusApiTimetables.kt | 16 +- .../v2/vulcan/data/api/VulcanApiTimetable.kt | 12 +- 4 files changed, 133 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/DataIdziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/DataIdziennik.kt index a774129d..3db12ef9 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/DataIdziennik.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/DataIdziennik.kt @@ -138,10 +138,12 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data( val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" } return validateTeacher(teacher, firstName, lastName) } + fun getTeacher(firstNameChar: Char, lastName: String): Teacher { val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" } return validateTeacher(teacher, firstNameChar.toString(), lastName) } + fun getTeacherByLastFirst(nameLastFirst: String): Teacher { val nameParts = nameLastFirst.split(" ") return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[1], nameParts[0]) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt index c9cf7f5f..4bff77e8 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) Kuba SzczodrzyƄski 2019-10-27. + * Copyright (c) Kacper Ziubryniewicz 2019-11-22 */ package pl.szczodrzynski.edziennik.api.v2.idziennik.data.web @@ -12,33 +12,38 @@ import pl.szczodrzynski.edziennik.api.v2.idziennik.DataIdziennik import pl.szczodrzynski.edziennik.api.v2.idziennik.ENDPOINT_IDZIENNIK_WEB_TIMETABLE import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikWeb import pl.szczodrzynski.edziennik.api.v2.models.ApiError +import pl.szczodrzynski.edziennik.api.v2.models.DataRemoveModel import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS -import pl.szczodrzynski.edziennik.data.db.modules.lessons.Lesson -import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange -import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange.TYPE_CANCELLED -import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange.TYPE_CHANGE import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonRange import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata +import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson +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 IdziennikWebTimetable(override val data: DataIdziennik, - val onSuccess: () -> Unit) : IdziennikWeb(data) { + val onSuccess: () -> Unit) : IdziennikWeb(data) { companion object { private const val TAG = "IdziennikWebTimetable" } init { - val weekStart = Week.getWeekStart() + val currentWeekStart = Week.getWeekStart() + if (Date.getToday().weekDay > 4) { - weekStart.stepForward(0, 0, 7) + 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) + webApiGet(TAG, IDZIENNIK_WEB_TIMETABLE, mapOf( "idPozDziennika" to data.registerId, "pidRokSzkolny" to data.schoolYearId, - "data" to weekStart.stringY_m_d+"T10:00:00.000Z" + "data" to "${weekStart.stringY_m_d}T10:00:00.000Z" )) { result -> val json = result.getJsonObject("d") ?: run { data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA) @@ -56,64 +61,103 @@ class IdziennikWebTimetable(override val data: DataIdziennik, data.lessonRanges[lessonRange.lessonNumber] = lessonRange } + val dates = mutableSetOf() + val lessons = mutableListOf() + json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { lesson -> val subject = data.getSubject( lesson.getString("Nazwa") ?: return@forEach, lesson.getLong("Id"), lesson.getString("Skrot") ?: "" ) - val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel") ?: return@forEach) - val weekDay = lesson.getInt("DzienTygodnia")?.minus(1) ?: return@forEach - val lessonRange = data.lessonRanges[lesson.getInt("Godzina")?.plus(1) ?: return@forEach] + val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel") + ?: return@forEach) - val lessonObject = Lesson( - profileId, - weekDay, - lessonRange.startTime, - lessonRange.endTime - ).apply { - subjectId = subject.id - teacherId = teacher.id - teamId = data.teamClass?.id ?: -1 - classroomName = lesson.getString("NazwaSali") ?: "" + val newSubjectName = lesson.getString("PrzedmiotZastepujacy") + val newSubject = when (newSubjectName.isNullOrBlank()) { + true -> null + else -> data.getSubject(newSubjectName, null, newSubjectName) } - data.lessonList.add(lessonObject) + val newTeacherName = lesson.getString("NauZastepujacy") + val newTeacher = when (newTeacherName.isNullOrBlank()) { + true -> null + else -> data.getTeacherByFDotLast(newTeacherName) + } + val weekDay = lesson.getInt("DzienTygodnia")?.minus(1) ?: return@forEach + val lessonRange = data.lessonRanges[lesson.getInt("Godzina")?.plus(1) + ?: return@forEach] + val lessonDate = weekStart.clone().stepForward(0, 0, weekDay) + val classroom = lesson.getString("NazwaSali") + + val id = lessonDate.combineWith(lessonRange.startTime) / 6L * 10L + (lesson.hashCode() and 0xFFFF) val type = lesson.getInt("TypZastepstwa") ?: -1 - if (type != -1) { - // we have a lesson change to process - val lessonChangeObject = LessonChange( - profileId, - weekStart.clone().stepForward(0, 0, weekDay), - lessonObject.startTime, - lessonObject.endTime - ) - lessonChangeObject.teamId = lessonObject.teamId - lessonChangeObject.teacherId = lessonObject.teacherId - lessonChangeObject.subjectId = lessonObject.subjectId - lessonChangeObject.classroomName = lessonObject.classroomName - when (type) { - 0 -> lessonChangeObject.type = TYPE_CANCELLED - 1, 2, 3, 4, 5 -> { - lessonChangeObject.type = TYPE_CHANGE - val newTeacher = lesson.getString("NauZastepujacy") - val newSubject = lesson.getString("PrzedmiotZastepujacy") - if (newTeacher != null) { - lessonChangeObject.teacherId = data.getTeacherByFDotLast(newTeacher).id - } - if (newSubject != null) { - lessonChangeObject.subjectId = data.getSubject(newSubject, null, "").id - } + val lessonObject = Lesson(profileId, id) + + when (type) { + 1, 2, 3, 4, 5 -> { + lessonObject.apply { + this.type = Lesson.TYPE_CHANGE + + this.date = lessonDate + this.lessonNumber = lessonRange.lessonNumber + this.startTime = lessonRange.startTime + this.endTime = lessonRange.endTime + this.subjectId = newSubject?.id + this.teacherId = newTeacher?.id + this.teamId = data.teamClass?.id + this.classroom = classroom + + this.oldDate = lessonDate + this.oldLessonNumber = lessonRange.lessonNumber + this.oldStartTime = lessonRange.startTime + this.oldEndTime = lessonRange.endTime + this.oldSubjectId = subject.id + this.oldTeacherId = teacher.id + this.oldTeamId = data.teamClass?.id + this.oldClassroom = classroom } } + 0 -> { + lessonObject.apply { + this.type = Lesson.TYPE_CANCELLED - data.lessonChangeList.add(lessonChangeObject) + this.oldDate = lessonDate + this.oldLessonNumber = lessonRange.lessonNumber + this.oldStartTime = lessonRange.startTime + this.oldEndTime = lessonRange.endTime + this.oldSubjectId = subject.id + this.oldTeacherId = teacher.id + this.oldTeamId = data.teamClass?.id + this.oldClassroom = classroom + } + } + else -> { + lessonObject.apply { + this.type = Lesson.TYPE_NORMAL + + this.date = lessonDate + this.lessonNumber = lessonRange.lessonNumber + this.startTime = lessonRange.startTime + this.endTime = lessonRange.endTime + this.subjectId = subject.id + this.teacherId = teacher.id + this.teamId = data.teamClass?.id + this.classroom = classroom + } + } + } + + dates.add(lessonDate.value) + lessons.add(lessonObject) + + if (lessonObject.type != Lesson.TYPE_NORMAL) { data.metadataList.add(Metadata( profileId, Metadata.TYPE_LESSON_CHANGE, - lessonChangeObject.id, + lessonObject.id, profile?.empty ?: false, profile?.empty ?: false, System.currentTimeMillis() @@ -121,6 +165,23 @@ class IdziennikWebTimetable(override val data: DataIdziennik, } } + val date: Date = weekStart.clone() + while (date <= weekEnd) { + if (!dates.contains(date.value)) { + lessons.add(Lesson(profileId, date.value.toLong()).apply { + this.type = Lesson.TYPE_NO_LESSONS + this.date = date.clone() + }) + } + + date.stepForward(0, 0, 1) + } + + d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate") + + data.lessonNewList.addAll(lessons) + data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd)) + data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS) onSuccess() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt index 15865a2f..f8cb37a8 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/api/LibrusApiTimetables.kt @@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson 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 LibrusApiTimetables(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusApi(data) { @@ -29,9 +30,18 @@ class LibrusApiTimetables(override val data: DataLibrus, data.db.classroomDao().getAllNow(profileId).toSparseArray(data.classrooms) { it.id } } - val currentWeekStart = Date.getToday().let { it.stepForward(0, 0, -it.weekDay) } + val currentWeekStart = Week.getWeekStart() + + if (Date.getToday().weekDay > 4) { + currentWeekStart.stepForward(0, 0, 7) + } + val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d - apiGet(TAG, "Timetables?weekStart=$getDate") { json -> + + val weekStart = Date.fromY_m_d(getDate) + val weekEnd = weekStart.clone().stepForward(0, 0, 6) + + apiGet(TAG, "Timetables?weekStart=${weekStart.stringY_m_d}") { json -> val days = json.getJsonObject("Timetable") days?.entrySet()?.forEach { (dateString, dayEl) -> @@ -57,8 +67,6 @@ class LibrusApiTimetables(override val data: DataLibrus, } } - val weekStart = Date.fromY_m_d(getDate) - val weekEnd = weekStart.clone().stepForward(0, 0, 6) 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)) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt index 1dcd65aa..18c2c4d0 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/vulcan/data/api/VulcanApiTimetable.kt @@ -20,6 +20,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson import pl.szczodrzynski.edziennik.utils.Utils.crc16 import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.models.Date +import pl.szczodrzynski.edziennik.utils.models.Week class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Unit) : VulcanApi(data) { companion object { @@ -27,10 +28,15 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni } init { data.profile?.also { profile -> - val currentWeekStart = Date.getToday().let { it.stepForward(0, 0, -it.weekDay) } + val currentWeekStart = Week.getWeekStart() val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d val weekStart = Date.fromY_m_d(getDate) + + if (Date.getToday().weekDay > 4 && weekStart == currentWeekStart) { + weekStart.stepForward(0, 0, 7) + } + val weekEnd = weekStart.clone().stepForward(0, 0, 6) apiGet(TAG, VULCAN_API_ENDPOINT_TIMETABLE, parameters = mapOf( @@ -40,8 +46,8 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni "IdOddzial" to data.studentClassId, "IdOkresKlasyfikacyjny" to data.studentSemesterId )) { json, _ -> - val dates: MutableSet = mutableSetOf() - val lessons: MutableList = mutableListOf() + val dates = mutableSetOf() + val lessons = mutableListOf() json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson -> if (lesson.getBoolean("PlanUcznia") != true)