diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt
index cc4709ce..ae9db1e7 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt
@@ -145,6 +145,7 @@ const val ERROR_IDZIENNIK_WEB_MAINTENANCE = 432
const val ERROR_IDZIENNIK_WEB_SERVER_ERROR = 433
const val ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED = 434
const val ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR = 440
+const val ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA = 441
const val ERROR_TEMPLATE_WEB_OTHER = 801
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 faa2f517..61629c3d 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
@@ -4,15 +4,16 @@
package pl.szczodrzynski.edziennik.api.v2.idziennik
+import androidx.core.util.set
import okhttp3.Cookie
-import pl.szczodrzynski.edziennik.App
+import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_IDZIENNIK_API
import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_IDZIENNIK_WEB
import pl.szczodrzynski.edziennik.api.v2.models.Data
-import pl.szczodrzynski.edziennik.currentTimeUnix
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
-import pl.szczodrzynski.edziennik.isNotNullNorEmpty
+import pl.szczodrzynski.edziennik.data.db.modules.subjects.Subject
+import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
@@ -106,4 +107,65 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
var schoolYearId: Int
get() { mSchoolYearId = mSchoolYearId ?: profile?.getStudentData("schoolYearId", 0); return mSchoolYearId ?: 0 }
set(value) { profile?.putStudentData("schoolYearId", value) ?: return; mSchoolYearId = value }
+
+
+
+ /* _ _ _ _ _
+ | | | | | (_) |
+ | | | | |_ _| |___
+ | | | | __| | / __|
+ | |__| | |_| | \__ \
+ \____/ \__|_|_|__*/
+ fun getSubject(name: String, id: Long?, shortName: String): Subject {
+ var subject = if (id == null)
+ subjectList.singleOrNull { it.longName == name }
+ else
+ subjectList.singleOrNull { it.id == id }
+
+ if (subject == null) {
+ subject = Subject(profileId, id ?: name.crc16().toLong(), name, shortName)
+ subjectList[subject.id] = subject
+ }
+ return subject
+ }
+
+ fun getTeacher(firstName: String, lastName: String): Teacher {
+ 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])
+ }
+
+ fun getTeacherByFirstLast(nameFirstLast: String): Teacher {
+ val nameParts = nameFirstLast.split(" ")
+ return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[0], nameParts[1])
+ }
+
+ fun getTeacherByFDotLast(nameFDotLast: String): Teacher {
+ val nameParts = nameFDotLast.split(".")
+ return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[0][0], nameParts[1])
+ }
+
+ fun getTeacherByFDotSpaceLast(nameFDotSpaceLast: String): Teacher {
+ val nameParts = nameFDotSpaceLast.split(".")
+ return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[0][0], nameParts[1])
+ }
+
+ private fun validateTeacher(teacher: Teacher?, firstName: String, lastName: String): Teacher {
+ (teacher ?: Teacher(profileId, -1, firstName, lastName).apply {
+ id = shortName.crc16().toLong()
+ teacherList[id] = this
+ }).apply {
+ if (firstName.length > 1)
+ name = firstName
+ surname = lastName
+ return this
+ }
+ }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/IdziennikFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/IdziennikFeatures.kt
index c3a01ea1..eac360e4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/IdziennikFeatures.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/IdziennikFeatures.kt
@@ -7,18 +7,60 @@ package pl.szczodrzynski.edziennik.api.v2.idziennik
import pl.szczodrzynski.edziennik.api.v2.*
import pl.szczodrzynski.edziennik.api.v2.models.Feature
-const val ENDPOINT_IDZIENNIK_WEB_SAMPLE = 9991
-const val ENDPOINT_IDZIENNIK_WEB_SAMPLE_2 = 9992
-const val ENDPOINT_IDZIENNIK_API_SAMPLE = 9993
+const val ENDPOINT_IDZIENNIK_WEB_TIMETABLE = 1030
+const val ENDPOINT_IDZIENNIK_WEB_GRADES = 1040
+const val ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES = 1050
+const val ENDPOINT_IDZIENNIK_WEB_EXAMS = 1060
+const val ENDPOINT_IDZIENNIK_WEB_NOTICES = 1070
+const val ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS = 1080
+const val ENDPOINT_IDZIENNIK_WEB_ATTENDANCE = 1090
+const val ENDPOINT_IDZIENNIK_WEB_MESSAGES_INBOX = 1110
+const val ENDPOINT_IDZIENNIK_WEB_MESSAGES_SENT = 1120
+const val ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER = 2010
+const val ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX = 2110
+const val ENDPOINT_IDZIENNIK_API_MESSAGES_SENT = 2120
val IdziennikFeatures = listOf(
- Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_STUDENT_INFO, listOf(
- ENDPOINT_IDZIENNIK_WEB_SAMPLE to LOGIN_METHOD_IDZIENNIK_WEB
- ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
- Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_SCHOOL_INFO, listOf(
- ENDPOINT_IDZIENNIK_WEB_SAMPLE_2 to LOGIN_METHOD_IDZIENNIK_WEB
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_TIMETABLE, listOf(
+ ENDPOINT_IDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_IDZIENNIK_WEB
), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_GRADES, listOf(
- ENDPOINT_IDZIENNIK_API_SAMPLE to LOGIN_METHOD_IDZIENNIK_API
+ ENDPOINT_IDZIENNIK_WEB_GRADES to LOGIN_METHOD_IDZIENNIK_WEB,
+ ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_AGENDA, listOf(
+ ENDPOINT_IDZIENNIK_WEB_EXAMS to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_BEHAVIOUR, listOf(
+ ENDPOINT_IDZIENNIK_WEB_NOTICES to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_ATTENDANCE, listOf(
+ ENDPOINT_IDZIENNIK_WEB_ATTENDANCE to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_ANNOUNCEMENTS, listOf(
+ ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_INBOX, listOf(
+ ENDPOINT_IDZIENNIK_WEB_MESSAGES_INBOX to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_SENT, listOf(
+ ENDPOINT_IDZIENNIK_WEB_MESSAGES_SENT to LOGIN_METHOD_IDZIENNIK_WEB
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_INBOX, listOf(
+ ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX to LOGIN_METHOD_IDZIENNIK_API
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_SENT, listOf(
+ ENDPOINT_IDZIENNIK_API_MESSAGES_SENT to LOGIN_METHOD_IDZIENNIK_API
+ ), listOf(LOGIN_METHOD_IDZIENNIK_WEB)),
+
+ Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
+ ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER to LOGIN_METHOD_IDZIENNIK_API
), listOf(LOGIN_METHOD_IDZIENNIK_API))
)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/IdziennikData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/IdziennikData.kt
index 4873a275..84d93d37 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/IdziennikData.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/IdziennikData.kt
@@ -4,7 +4,10 @@
package pl.szczodrzynski.edziennik.api.v2.idziennik.data
+import pl.szczodrzynski.edziennik.R
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.web.IdziennikWebTimetable
import pl.szczodrzynski.edziennik.utils.Utils
class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
@@ -35,10 +38,10 @@ class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
Utils.d(TAG, "Using endpoint $endpointId")
when (endpointId) {
- /*ENDPOINT_IDZIENNIK_WEB_SAMPLE -> {
- data.startProgress(R.string.edziennik_progress_endpoint_student_info)
- IdziennikWebSample(data) { onSuccess() }
- }*/
+ ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_timetable)
+ IdziennikWebTimetable(data) { onSuccess() }
+ }
else -> onSuccess()
}
}
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
new file mode 100644
index 00000000..c9cf7f5f
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/data/web/IdziennikWebTimetable.kt
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2019-10-27.
+ */
+
+package pl.szczodrzynski.edziennik.api.v2.idziennik.data.web
+
+import androidx.core.util.set
+import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.api.v2.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
+import pl.szczodrzynski.edziennik.api.v2.IDZIENNIK_WEB_TIMETABLE
+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.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.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) {
+ companion object {
+ private const val TAG = "IdziennikWebTimetable"
+ }
+
+ init {
+ val weekStart = Week.getWeekStart()
+ if (Date.getToday().weekDay > 4) {
+ weekStart.stepForward(0, 0, 7)
+ }
+
+ webApiGet(TAG, IDZIENNIK_WEB_TIMETABLE, mapOf(
+ "idPozDziennika" to data.registerId,
+ "pidRokSzkolny" to data.schoolYearId,
+ "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)
+ .withApiResponse(result))
+ return@webApiGet
+ }
+
+ json.getJsonArray("GodzinyLekcyjne")?.asJsonObjectList()?.forEach { range ->
+ val lessonRange = LessonRange(
+ profileId,
+ range.getInt("LiczbaP") ?: return@forEach,
+ range.getString("Poczatek")?.let { Time.fromH_m(it) } ?: return@forEach,
+ range.getString("Koniec")?.let { Time.fromH_m(it) } ?: return@forEach
+ )
+ data.lessonRanges[lessonRange.lessonNumber] = lessonRange
+ }
+
+ 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 lessonObject = Lesson(
+ profileId,
+ weekDay,
+ lessonRange.startTime,
+ lessonRange.endTime
+ ).apply {
+ subjectId = subject.id
+ teacherId = teacher.id
+ teamId = data.teamClass?.id ?: -1
+ classroomName = lesson.getString("NazwaSali") ?: ""
+ }
+
+ data.lessonList.add(lessonObject)
+
+ 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
+ }
+ }
+ }
+
+ data.lessonChangeList.add(lessonChangeObject)
+ data.metadataList.add(Metadata(
+ profileId,
+ Metadata.TYPE_LESSON_CHANGE,
+ lessonChangeObject.id,
+ profile?.empty ?: false,
+ profile?.empty ?: false,
+ System.currentTimeMillis()
+ ))
+ }
+ }
+
+ data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
+ onSuccess()
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/login/IdziennikLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/login/IdziennikLoginWeb.kt
index d03c254e..775200c6 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/login/IdziennikLoginWeb.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/idziennik/login/IdziennikLoginWeb.kt
@@ -62,9 +62,9 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
if (text.contains("czyWyswietlicDostepMobilny")) {
val cookies = data.app.cookieJar.getForDomain("iuczniowie.progman.pl")
run {
- data.webSessionId = cookies.singleOrNull { it.name() == "ASP.NET_SessionId_iDziennik" }?.name() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
- data.webAuth = cookies.singleOrNull { it.name() == ".ASPXAUTH" }?.name() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
- data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.name() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
+ data.webSessionId = cookies.singleOrNull { it.name() == "ASP.NET_SessionId_iDziennik" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
+ data.webAuth = cookies.singleOrNull { it.name() == ".ASPXAUTH" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
+ data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
data.loginExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
return@run null
}?.let { errorCode ->
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 05e64564..10533021 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -975,4 +975,5 @@
Według systemu
Polski
English
+ Pobieranie planu lekcji...