[APIv2/Idziennik] Add new timetable getting and fix week start

This commit is contained in:
Kacper Ziubryniewicz 2019-11-23 19:40:32 +01:00
parent db2ebab879
commit ae10b8abbd
4 changed files with 133 additions and 56 deletions

View File

@ -138,10 +138,12 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" } val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" }
return validateTeacher(teacher, firstName, lastName) return validateTeacher(teacher, firstName, lastName)
} }
fun getTeacher(firstNameChar: Char, lastName: String): Teacher { fun getTeacher(firstNameChar: Char, lastName: String): Teacher {
val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" } val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" }
return validateTeacher(teacher, firstNameChar.toString(), lastName) return validateTeacher(teacher, firstNameChar.toString(), lastName)
} }
fun getTeacherByLastFirst(nameLastFirst: String): Teacher { fun getTeacherByLastFirst(nameLastFirst: String): Teacher {
val nameParts = nameLastFirst.split(" ") val nameParts = nameLastFirst.split(" ")
return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[1], nameParts[0]) return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[1], nameParts[0])

View File

@ -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 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.ENDPOINT_IDZIENNIK_WEB_TIMETABLE
import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikWeb import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikWeb
import pl.szczodrzynski.edziennik.api.v2.models.ApiError 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.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.lessons.LessonRange
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata 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.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
class IdziennikWebTimetable(override val data: DataIdziennik, class IdziennikWebTimetable(override val data: DataIdziennik,
val onSuccess: () -> Unit) : IdziennikWeb(data) { val onSuccess: () -> Unit) : IdziennikWeb(data) {
companion object { companion object {
private const val TAG = "IdziennikWebTimetable" private const val TAG = "IdziennikWebTimetable"
} }
init { init {
val weekStart = Week.getWeekStart() val currentWeekStart = Week.getWeekStart()
if (Date.getToday().weekDay > 4) { 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( webApiGet(TAG, IDZIENNIK_WEB_TIMETABLE, mapOf(
"idPozDziennika" to data.registerId, "idPozDziennika" to data.registerId,
"pidRokSzkolny" to data.schoolYearId, "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 -> )) { result ->
val json = result.getJsonObject("d") ?: run { val json = result.getJsonObject("d") ?: run {
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA) 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 data.lessonRanges[lessonRange.lessonNumber] = lessonRange
} }
val dates = mutableSetOf<Int>()
val lessons = mutableListOf<Lesson>()
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { lesson -> json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { lesson ->
val subject = data.getSubject( val subject = data.getSubject(
lesson.getString("Nazwa") ?: return@forEach, lesson.getString("Nazwa") ?: return@forEach,
lesson.getLong("Id"), lesson.getLong("Id"),
lesson.getString("Skrot") ?: "" lesson.getString("Skrot") ?: ""
) )
val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel") ?: return@forEach) val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel")
val weekDay = lesson.getInt("DzienTygodnia")?.minus(1) ?: return@forEach ?: return@forEach)
val lessonRange = data.lessonRanges[lesson.getInt("Godzina")?.plus(1) ?: return@forEach]
val lessonObject = Lesson( val newSubjectName = lesson.getString("PrzedmiotZastepujacy")
profileId, val newSubject = when (newSubjectName.isNullOrBlank()) {
weekDay, true -> null
lessonRange.startTime, else -> data.getSubject(newSubjectName, null, newSubjectName)
lessonRange.endTime
).apply {
subjectId = subject.id
teacherId = teacher.id
teamId = data.teamClass?.id ?: -1
classroomName = lesson.getString("NazwaSali") ?: ""
} }
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 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 val lessonObject = Lesson(profileId, id)
lessonChangeObject.teacherId = lessonObject.teacherId
lessonChangeObject.subjectId = lessonObject.subjectId when (type) {
lessonChangeObject.classroomName = lessonObject.classroomName 1, 2, 3, 4, 5 -> {
when (type) { lessonObject.apply {
0 -> lessonChangeObject.type = TYPE_CANCELLED this.type = Lesson.TYPE_CHANGE
1, 2, 3, 4, 5 -> {
lessonChangeObject.type = TYPE_CHANGE this.date = lessonDate
val newTeacher = lesson.getString("NauZastepujacy") this.lessonNumber = lessonRange.lessonNumber
val newSubject = lesson.getString("PrzedmiotZastepujacy") this.startTime = lessonRange.startTime
if (newTeacher != null) { this.endTime = lessonRange.endTime
lessonChangeObject.teacherId = data.getTeacherByFDotLast(newTeacher).id this.subjectId = newSubject?.id
} this.teacherId = newTeacher?.id
if (newSubject != null) { this.teamId = data.teamClass?.id
lessonChangeObject.subjectId = data.getSubject(newSubject, null, "").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( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonChangeObject.id, lessonObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false,
System.currentTimeMillis() 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) data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
onSuccess() onSuccess()
} }

View File

@ -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.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week
class LibrusApiTimetables(override val data: DataLibrus, class LibrusApiTimetables(override val data: DataLibrus,
val onSuccess: () -> Unit) : LibrusApi(data) { 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 } 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 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") val days = json.getJsonObject("Timetable")
days?.entrySet()?.forEach { (dateString, dayEl) -> 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") 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.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))

View File

@ -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.crc16
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date 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) { class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Unit) : VulcanApi(data) {
companion object { companion object {
@ -27,10 +28,15 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
} }
init { data.profile?.also { profile -> 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 getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
val weekStart = Date.fromY_m_d(getDate) 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) val weekEnd = weekStart.clone().stepForward(0, 0, 6)
apiGet(TAG, VULCAN_API_ENDPOINT_TIMETABLE, parameters = mapOf( 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, "IdOddzial" to data.studentClassId,
"IdOkresKlasyfikacyjny" to data.studentSemesterId "IdOkresKlasyfikacyjny" to data.studentSemesterId
)) { json, _ -> )) { json, _ ->
val dates: MutableSet<Int> = mutableSetOf() val dates = mutableSetOf<Int>()
val lessons: MutableList<Lesson> = mutableListOf() val lessons = mutableListOf<Lesson>()
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson -> json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson ->
if (lesson.getBoolean("PlanUcznia") != true) if (lesson.getBoolean("PlanUcznia") != true)