diff --git a/app/build.gradle b/app/build.gradle
index 76b01ea8..2c525d23 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -142,6 +142,7 @@ dependencies {
// Language cores
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation "androidx.multidex:multidex:2.0.1"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5"
// Android Jetpack
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt
index 1cb7587a..888b183a 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt
@@ -92,7 +92,7 @@ val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT
const val VULCAN_HEBE_USER_AGENT = "Dart/2.10 (dart:io)"
const val VULCAN_HEBE_APP_NAME = "DzienniczekPlus 2.0"
-const val VULCAN_HEBE_APP_VERSION = "21.02.09 (G)"
+const val VULCAN_HEBE_APP_VERSION = "22.09.02 (G)"
private const val VULCAN_API_DEVICE_NAME_PREFIX = "Szkolny.eu "
private const val VULCAN_API_DEVICE_NAME_SUFFIX = " - nie usuwać"
val VULCAN_API_DEVICE_NAME by lazy {
@@ -116,9 +116,11 @@ const val VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY = "api/mobile/grade/summary"
const val VULCAN_HEBE_ENDPOINT_HOMEWORK = "api/mobile/homework"
const val VULCAN_HEBE_ENDPOINT_NOTICES = "api/mobile/note"
const val VULCAN_HEBE_ENDPOINT_ATTENDANCE = "api/mobile/lesson"
-const val VULCAN_HEBE_ENDPOINT_MESSAGES = "api/mobile/message"
-const val VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS = "api/mobile/message/status"
-const val VULCAN_HEBE_ENDPOINT_MESSAGES_SEND = "api/mobile/message"
+const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX = "api/mobile/messagebox"
+const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK = "api/mobile/messagebox/addressbook"
+const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES = "api/mobile/messagebox/message"
+const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS = "api/mobile/messagebox/message/status"
+const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND = "api/mobile/messagebox/message"
const val VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER = "api/mobile/school/lucky"
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt
index b42de2c4..e71a8d13 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt
@@ -20,6 +20,10 @@ object Regexes {
"""
""".toRegex()
}
+ val MESSAGE_META by lazy {
+ """^\[META:([A-z0-9-&=]+)]""".toRegex()
+ }
+
val MOBIDZIENNIK_GRADES_SUBJECT_NAME by lazy {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
index c6d797fa..0c2bc91c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt
@@ -222,15 +222,15 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
get() { mHebeContext = mHebeContext ?: profile?.getStudentData("hebeContext", null); return mHebeContext }
set(value) { profile?.putStudentData("hebeContext", value) ?: return; mHebeContext = value }
- private var mSenderAddressHash: String? = null
- var senderAddressHash: String?
- get() { mSenderAddressHash = mSenderAddressHash ?: profile?.getStudentData("senderAddressHash", null); return mSenderAddressHash }
- set(value) { profile?.putStudentData("senderAddressHash", value) ?: return; mSenderAddressHash = value }
+ private var mMessageBoxKey: String? = null
+ var messageBoxKey: String?
+ get() { mMessageBoxKey = mMessageBoxKey ?: profile?.getStudentData("messageBoxKey", null); return mMessageBoxKey }
+ set(value) { profile?.putStudentData("messageBoxKey", value) ?: return; mMessageBoxKey = value }
- private var mSenderAddressName: String? = null
- var senderAddressName: String?
- get() { mSenderAddressName = mSenderAddressName ?: profile?.getStudentData("senderAddressName", null); return mSenderAddressName }
- set(value) { profile?.putStudentData("senderAddressName", value) ?: return; mSenderAddressName = value }
+ private var mMessageBoxName: String? = null
+ var messageBoxName: String?
+ get() { mMessageBoxName = mMessageBoxName ?: profile?.getStudentData("messageBoxName", null); return mMessageBoxName }
+ set(value) { profile?.putStudentData("messageBoxName", value) ?: return; mMessageBoxName = value }
val apiUrl: String?
get() {
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
index 924d7ced..857a596e 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt
@@ -12,6 +12,7 @@ const val ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS = 2010
const val ENDPOINT_VULCAN_HEBE_MAIN = 3000
const val ENDPOINT_VULCAN_HEBE_PUSH_CONFIG = 3005
const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK = 3010
+const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 = 3011
const val ENDPOINT_VULCAN_HEBE_TIMETABLE = 3020
const val ENDPOINT_VULCAN_HEBE_EXAMS = 3030
const val ENDPOINT_VULCAN_HEBE_GRADES = 3040
@@ -19,10 +20,11 @@ const val ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY = 3050
const val ENDPOINT_VULCAN_HEBE_HOMEWORK = 3060
const val ENDPOINT_VULCAN_HEBE_NOTICES = 3070
const val ENDPOINT_VULCAN_HEBE_ATTENDANCE = 3080
-const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3090
-const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3100
const val ENDPOINT_VULCAN_HEBE_TEACHERS = 3110
const val ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER = 3200
+const val ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES = 3500
+const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3510
+const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3520
val VulcanFeatures = listOf(
// timetable
@@ -85,6 +87,8 @@ val VulcanFeatures = listOf(
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
ENDPOINT_VULCAN_HEBE_MAIN to LOGIN_METHOD_VULCAN_HEBE,
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE,
- ENDPOINT_VULCAN_HEBE_TEACHERS to LOGIN_METHOD_VULCAN_HEBE
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 to LOGIN_METHOD_VULCAN_HEBE,
+ ENDPOINT_VULCAN_HEBE_TEACHERS to LOGIN_METHOD_VULCAN_HEBE,
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES to LOGIN_METHOD_VULCAN_HEBE,
), listOf(LOGIN_METHOD_VULCAN_HEBE))
)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
index 6170d817..4b3f961f 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt
@@ -21,10 +21,12 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
ENDPOINT_VULCAN_HEBE_MAIN,
ENDPOINT_VULCAN_HEBE_PUSH_CONFIG,
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK,
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2,
ENDPOINT_VULCAN_HEBE_TIMETABLE,
ENDPOINT_VULCAN_HEBE_EXAMS,
ENDPOINT_VULCAN_HEBE_HOMEWORK,
ENDPOINT_VULCAN_HEBE_NOTICES,
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES,
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX,
ENDPOINT_VULCAN_HEBE_MESSAGES_SENT,
ENDPOINT_VULCAN_HEBE_TEACHERS,
@@ -107,6 +109,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_addressbook)
VulcanHebeAddressbook(data, lastSync, onSuccess)
}
+ ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_addressbook)
+ VulcanHebeAddressbook2(data, lastSync, onSuccess)
+ }
ENDPOINT_VULCAN_HEBE_TEACHERS -> {
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
VulcanHebeTeachers(data, lastSync, onSuccess)
@@ -139,6 +145,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
VulcanHebeAttendance(data, lastSync, onSuccess)
}
+ ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES -> {
+ data.startProgress(R.string.edziennik_progress_endpoint_messages)
+ VulcanHebeMessageBoxes(data, lastSync, onSuccess)
+ }
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX -> {
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_RECEIVED)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
index 457306c2..a99ac7a4 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt
@@ -14,7 +14,6 @@ import im.wangchao.mhttp.Response
import im.wangchao.mhttp.body.MediaTypeUtils
import im.wangchao.mhttp.callback.JsonCallbackHandler
import io.github.wulkanowy.signer.hebe.getSignatureHeaders
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.*
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.HebeFilterType
@@ -55,6 +54,15 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
return date.getLong("Timestamp") ?: return default
}
+ fun buildDateTime(): JsonObject {
+ return JsonObject(
+ "Timestamp" to System.currentTimeMillis(),
+ "Date" to Date.getToday().stringY_m_d,
+ "DateDisplay" to Date.getToday().stringDmy,
+ "Time" to Time.getNow().stringHMS,
+ )
+ }
+
fun getDate(json: JsonObject?, key: String): Date? {
val date = json.getJsonObject(key)
return date.getString("Date")?.let { Date.fromY_m_d(it) }
@@ -74,6 +82,22 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
return teacherId
}
+ fun getTeacherRecipient(json: JsonObject): Teacher? {
+ val globalKey = json.getString("GlobalKey") ?: return null
+ if (globalKey == data.messageBoxKey)
+ return null
+ var name = json.getString("Name") ?: return null
+ val group = json.getString("Group", "P")
+ val loginId = "${globalKey};${group};${name}"
+ val pattern = " - $group - (${data.schoolShort})"
+ if (name.endsWith(pattern))
+ name = name.substringBefore(pattern)
+ val teacher = data.getTeacherByFirstLast(name, loginId)
+ if (teacher.type == 0)
+ teacher.type = Teacher.TYPE_OTHER
+ return teacher
+ }
+
fun getSubjectId(json: JsonObject?, key: String): Long? {
val subject = json.getJsonObject(key)
val subjectId = subject.getLong("Id") ?: return null
@@ -89,7 +113,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
}
fun getTeamId(json: JsonObject?, key: String): Long? {
- val team = json.getJsonObject(key)
+ val team = json.getJsonObject(key) ?: return null
val teamId = team.getLong("Id")
var teamName = team.getString("Shortcut")
?: team.getString("Name")
@@ -104,7 +128,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
}
fun getClassId(json: JsonObject?, key: String): Long? {
- val team = json.getJsonObject(key)
+ val team = json.getJsonObject(key) ?: return null
val teamId = team.getLong("Id")
val teamName = data.profile?.studentClassName
?: team.getString("Name")
@@ -148,7 +172,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
fun isCurrentYear(dateTime: Long): Boolean {
return profile?.let { profile ->
- return@let dateTime >= profile.dateSemester1Start.inMillis
+ return@let dateTime >= profile.dateSemester1Start.inMillis - WEEK * MS
} ?: false
}
@@ -355,6 +379,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
dateTo: Date? = null,
lastSync: Long? = null,
folder: Int? = null,
+ messageBox: String? = null,
params: Map = mapOf(),
includeFilterType: Boolean = true,
onSuccess: (data: List, response: Response?) -> Unit
@@ -378,6 +403,9 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
query["periodId"] = data.studentSemesterId.toString()
query["pupilId"] = data.studentId.toString()
}
+ HebeFilterType.BY_MESSAGEBOX -> {
+ query["box"] = messageBox ?: data.messageBoxKey ?: ""
+ }
}
if (dateFrom != null)
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
index a4ea84b1..bd8b58e5 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt
@@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
enum class HebeFilterType(val endpoint: String) {
+ BY_MESSAGEBOX("byBox"),
BY_PUPIL("byPupil"),
BY_PERSON("byPerson"),
BY_PERIOD("byPeriod")
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
index 13eeb8db..d7bec22b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt
@@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
import androidx.core.util.set
+import androidx.room.OnConflictStrategy
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_ADDRESSBOOK
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
@@ -44,7 +45,6 @@ class VulcanHebeAddressbook(
) { list, _ ->
list.forEach { person ->
val id = person.getString("Id") ?: return@forEach
- val loginId = person.getString("LoginId") ?: return@forEach
val idType = id.split("-")
.getOrNull(0)
@@ -69,7 +69,7 @@ class VulcanHebeAddressbook(
idLong,
name,
surname,
- loginId
+ null
).also {
data.teacherList[idLong] = it
}
@@ -108,13 +108,14 @@ class VulcanHebeAddressbook(
}
teacher.setTeacherType(personType)
- teacher.typeDescription = roleText
+ if (roleText != null)
+ teacher.typeDescription = roleText
}
if (teacher.type == 0)
teacher.setTeacherType(typeBase)
}
-
+ data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK, 2 * DAY)
onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK)
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt
new file mode 100644
index 00000000..1a6606d0
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2021-2-21.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+
+import androidx.room.OnConflictStrategy
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_OTHER
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENT
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_STUDENT
+import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_TEACHER
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getString
+
+class VulcanHebeAddressbook2(
+ override val data: DataVulcan,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit
+) : VulcanHebe(data, lastSync) {
+ companion object {
+ const val TAG = "VulcanHebeAddressbook2"
+ }
+
+ init {
+ apiGetList(
+ TAG,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK,
+ HebeFilterType.BY_MESSAGEBOX,
+ messageBox = data.messageBoxKey,
+ lastSync = lastSync,
+ includeFilterType = false
+ ) { list, _ ->
+ list.forEach { person ->
+ val teacher = getTeacherRecipient(person) ?: return@forEach
+ val group = person.getString("Group", "P")
+ if (teacher.type == TYPE_OTHER) {
+ teacher.type = when (group) {
+ "P" -> TYPE_TEACHER // Pracownik
+ "O" -> TYPE_PARENT // Opiekun
+ "U" -> TYPE_STUDENT // Uczeń
+ else -> TYPE_OTHER
+ }
+ }
+ }
+ data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2, 2 * DAY)
+ onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt
new file mode 100644
index 00000000..e1c03aff
--- /dev/null
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) Kuba Szczodrzyński 2022-9-16.
+ */
+
+package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES
+import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
+import pl.szczodrzynski.edziennik.ext.DAY
+import pl.szczodrzynski.edziennik.ext.getString
+
+class VulcanHebeMessageBoxes(
+ override val data: DataVulcan,
+ override val lastSync: Long?,
+ val onSuccess: (endpointId: Int) -> Unit
+) : VulcanHebe(data, lastSync) {
+ companion object {
+ const val TAG = "VulcanHebeMessageBoxes"
+ }
+
+ init {
+ apiGetList(
+ TAG,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX,
+ lastSync = lastSync
+ ) { list, _ ->
+ for (messageBox in list) {
+ val name = messageBox.getString("Name") ?: continue
+ val studentName = profile?.studentNameLong ?: continue
+ if (!name.startsWith(studentName))
+ continue
+
+ data.messageBoxKey = messageBox.getString("GlobalKey")
+ data.messageBoxName = name
+ break
+ }
+ data.setSyncNext(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES, 7 * DAY)
+ onSuccess(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES)
+ }
+ }
+}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
index 5d6e5da4..29f37e62 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt
@@ -4,22 +4,21 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
-import androidx.core.util.set
-import com.google.gson.JsonObject
-import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_SENT
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
-import pl.szczodrzynski.edziennik.data.db.entity.*
+import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
+import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
+import pl.szczodrzynski.edziennik.data.db.entity.Metadata
+import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.ext.*
import pl.szczodrzynski.edziennik.utils.Utils
-import pl.szczodrzynski.navlib.crc16
class VulcanHebeMessages(
override val data: DataVulcan,
@@ -27,29 +26,7 @@ class VulcanHebeMessages(
val onSuccess: (endpointId: Int) -> Unit
) : VulcanHebe(data, lastSync) {
companion object {
- const val TAG = "VulcanHebeMessagesInbox"
- }
-
- private fun getPersonId(json: JsonObject): Long {
- val senderLoginId = json.getInt("LoginId") ?: return -1
- /*if (senderLoginId == data.studentLoginId)
- return -1*/
-
- val senderName = json.getString("Address") ?: return -1
- val senderNameSplit = senderName.splitName()
- val senderLoginIdStr = senderLoginId.toString()
- val teacher = data.teacherList.singleOrNull { it.loginId == senderLoginIdStr }
- ?: Teacher(
- profileId,
- -1 * crc16(senderName).toLong(),
- senderNameSplit?.second ?: "",
- senderNameSplit?.first ?: "",
- senderLoginIdStr
- ).also {
- it.setTeacherType(Teacher.TYPE_OTHER)
- data.teacherList[it.id] = it
- }
- return teacher.id
+ const val TAG = "VulcanHebeMessages"
}
fun getMessages(messageType: Int) {
@@ -64,17 +41,28 @@ class VulcanHebeMessages(
TYPE_SENT -> ENDPOINT_VULCAN_HEBE_MESSAGES_SENT
else -> ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX
}
+
+ val messageBox = data.messageBoxKey
+ if (messageBox == null) {
+ onSuccess(endpointId)
+ return
+ }
+
apiGetList(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES,
- HebeFilterType.BY_PERSON,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES,
+ HebeFilterType.BY_MESSAGEBOX,
+ messageBox = data.messageBoxKey,
folder = folder,
lastSync = lastSync
) { list, _ ->
list.forEach { message ->
- val id = message.getLong("Id") ?: return@forEach
+ val uuid = message.getString("Id") ?: return@forEach
+ val id = Utils.crc32(uuid.toByteArray())
+ val globalKey = message.getString("GlobalKey", "")
+ val threadKey = message.getString("ThreadKey", "")
val subject = message.getString("Subject") ?: return@forEach
- val body = message.getString("Content") ?: return@forEach
+ var body = message.getString("Content") ?: return@forEach
val sender = message.getJsonObject("Sender") ?: return@forEach
@@ -83,13 +71,27 @@ class VulcanHebeMessages(
if (!isCurrentYear(sentDate)) return@forEach
+ val senderId = if (messageType == TYPE_RECEIVED)
+ getTeacherRecipient(sender)?.id
+ else
+ null
+
+ val meta = mutableMapOf(
+ "uuid" to uuid,
+ "globalKey" to globalKey,
+ "threadKey" to threadKey,
+ )
+ val metaString = meta.map { "${it.key}=${it.value}" }.join("&")
+ body = "[META:${metaString}]" + body
+ body = body.replace("\n", "
")
+
val messageObject = Message(
profileId = profileId,
id = id,
type = messageType,
subject = subject,
- body = body.replace("\n", "
"),
- senderId = if (messageType == TYPE_RECEIVED) getPersonId(sender) else null,
+ body = body,
+ senderId = senderId,
addedDate = sentDate
)
@@ -101,9 +103,14 @@ class VulcanHebeMessages(
else -1
for (receiver in receivers) {
+ val recipientId = if (messageType == TYPE_SENT)
+ getTeacherRecipient(receiver)?.id ?: -1
+ else
+ -1
+
val messageRecipientObject = MessageRecipient(
profileId,
- if (messageType == TYPE_SENT) getPersonId(receiver) else -1,
+ recipientId,
-1,
receiverReadDate,
id
@@ -115,6 +122,9 @@ class VulcanHebeMessages(
?.asJsonObjectList()
?: return@forEach
+ messageObject.attachmentIds = mutableListOf()
+ messageObject.attachmentNames = mutableListOf()
+ messageObject.attachmentSizes = mutableListOf()
for (attachment in attachments) {
val fileName = attachment.getString("Name") ?: continue
val url = attachment.getString("Link") ?: continue
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
index bd86cfce..f0090a9c 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt
@@ -5,7 +5,7 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
import org.greenrobot.eventbus.EventBus
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
@@ -23,13 +23,19 @@ class VulcanHebeMessagesChangeStatus(
const val TAG = "VulcanHebeMessagesChangeStatus"
}
- init {
+ init { let {
+ val messageKey = messageObject.body?.let { data.parseMessageMeta(it) }?.get("globalKey") ?: run {
+ EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
+ onSuccess()
+ return@let
+ }
+
apiPost(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS,
payload = JsonObject(
- "MessageId" to messageObject.id,
- "LoginId" to data.studentLoginId,
+ "BoxKey" to data.messageBoxKey,
+ "MessageKey" to messageKey,
"Status" to 1
)
) { _: Boolean, _ ->
@@ -61,5 +67,5 @@ class VulcanHebeMessagesChangeStatus(
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
onSuccess()
}
- }
+ }}
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
index e71c4089..5e607caa 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt
@@ -4,17 +4,20 @@
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
+import com.google.gson.JsonArray
import com.google.gson.JsonObject
import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.*
+import pl.szczodrzynski.edziennik.data.api.ERROR_MESSAGE_NOT_SENT
import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY
-import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_SEND
+import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
import pl.szczodrzynski.edziennik.data.db.entity.Message
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
import pl.szczodrzynski.edziennik.ext.*
+import java.util.UUID
class VulcanHebeSendMessage(
override val data: DataVulcan,
@@ -28,9 +31,9 @@ class VulcanHebeSendMessage(
}
init {
- if (data.senderAddressName == null || data.senderAddressHash == null) {
- VulcanHebeMain(data).getStudents(data.profile, null) {
- if (data.senderAddressName == null || data.senderAddressHash == null) {
+ if (data.messageBoxKey == null || data.messageBoxName == null) {
+ VulcanHebeMessageBoxes(data, 0) {
+ if (data.messageBoxKey == null || data.messageBoxName == null) {
data.error(TAG, ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY)
}
else {
@@ -44,47 +47,64 @@ class VulcanHebeSendMessage(
}
private fun sendMessage() {
+ val uuid = UUID.randomUUID().toString()
+ val globalKey = UUID.randomUUID().toString()
+ val partition = "${data.symbol}-${data.schoolSymbol}"
+
val recipientsArray = JsonArray()
recipients.forEach { teacher ->
+ val loginId = teacher.loginId?.split(";", limit = 3) ?: return@forEach
+ val key = loginId.getOrNull(0) ?: teacher.loginId
+ val group = loginId.getOrNull(1)
+ val name = loginId.getOrNull(2)
+ if (key?.toIntOrNull() != null) {
+ // raise error for old-format (non-UUID) login IDs
+ data.error(TAG, ERROR_MESSAGE_NOT_SENT)
+ return
+ }
recipientsArray += JsonObject(
- "Address" to teacher.fullNameLastFirst,
- "LoginId" to (teacher.loginId?.toIntOrNull() ?: return@forEach),
- "Initials" to teacher.initialsLastFirst,
- "AddressHash" to teacher.fullNameLastFirst.sha1Hex()
+ "Id" to "${data.messageBoxKey}-${key}",
+ "Partition" to partition,
+ "Owner" to data.messageBoxKey,
+ "GlobalKey" to key,
+ "Name" to name,
+ "Group" to group,
+ "Initials" to "",
+ "HasRead" to 0,
)
}
- val senderName = (profile?.accountName ?: profile?.studentNameLong)
- ?.swapFirstLastName() ?: ""
val sender = JsonObject(
- "Address" to data.senderAddressName,
- "LoginId" to data.studentLoginId.toString(),
- "Initials" to senderName.getNameInitials(),
- "AddressHash" to data.senderAddressHash
+ "Id" to "0",
+ "Partition" to partition,
+ "Owner" to data.messageBoxKey,
+ "GlobalKey" to data.messageBoxKey,
+ "Name" to data.messageBoxName,
+ "Group" to "",
+ "Initials" to "",
+ "HasRead" to 0,
)
apiPost(
TAG,
- VULCAN_HEBE_ENDPOINT_MESSAGES_SEND,
+ VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND,
payload = JsonObject(
- "Status" to 1,
- "Sender" to sender,
- "DateSent" to null,
- "DateRead" to null,
- "Content" to text,
- "Receiver" to recipientsArray,
- "Id" to 0,
+ "Id" to uuid,
+ "GlobalKey" to globalKey,
+ "Partition" to partition,
+ "ThreadKey" to globalKey, // TODO correct threadKey for reply messages
"Subject" to subject,
- "Attachments" to null,
- "Self" to null
+ "Content" to text,
+ "Status" to 1,
+ "Owner" to data.messageBoxKey,
+ "DateSent" to buildDateTime(),
+ "DateRead" to null,
+ "Sender" to sender,
+ "Receiver" to recipientsArray,
+ "Attachments" to JsonArray(),
)
- ) { json: JsonObject, _ ->
- val messageId = json.getLong("Id")
-
- if (messageId == null) {
- // TODO error
- return@apiPost
- }
+ ) { _: JsonObject, _ ->
+ // TODO handle errors
VulcanHebeMessages(data, null) {
val message = data.messageList.firstOrNull { it.isSent && it.subject == subject }
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt
index f01e0d6b..7be65e34 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt
@@ -45,6 +45,7 @@ class VulcanHebeTeachers(
when (subjectName) {
"Pedagog" -> teacher.setTeacherType(Teacher.TYPE_PEDAGOGUE)
+ "Dyrektor" -> teacher.setTeacherType(Teacher.TYPE_PRINCIPAL)
else -> {
val subjectId = data.getSubject(null, subjectName).id
if (!teacher.subjects.contains(subjectId))
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 94e12fe8..ea53112a 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
@@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.BuildConfig
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE
+import pl.szczodrzynski.edziennik.data.api.Regexes.MESSAGE_META
import pl.szczodrzynski.edziennik.data.api.interfaces.EndpointCallback
import pl.szczodrzynski.edziennik.data.db.AppDb
import pl.szczodrzynski.edziennik.data.db.entity.*
@@ -489,11 +490,19 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt
teacherList[id] = this
}
return obj.also {
- if (loginId != null && it.loginId != null)
+ if (loginId != null)
it.loginId = loginId
if (firstName.length > 1)
it.name = firstName
it.surname = lastName
}
}
+
+ fun parseMessageMeta(body: String): Map? {
+ val match = MESSAGE_META.find(body) ?: return null
+ return match[1].split("&").associateBy(
+ { it.substringBefore("=") },
+ { it.substringAfter("=") },
+ )
+ }
}
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt
index 7266be41..52e7c23b 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt
@@ -77,7 +77,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
private lateinit var stylingConfig: StylingConfig
private lateinit var uiConfig: UIConfig
private val enableTextStyling
- get() = app.profile.loginStoreType != LoginStore.LOGIN_TYPE_VULCAN && app.profile.loginStoreType != LoginStore.LOGIN_TYPE_LIBRUS
+ get() = app.profile.loginStoreType != LoginStore.LOGIN_TYPE_LIBRUS
private var changedRecipients = false
private var changedSubject = false
private var changedBody = false
diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt
index 2e3bc072..97610845 100644
--- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt
+++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt
@@ -15,6 +15,7 @@ import android.text.style.*
import androidx.appcompat.widget.AppCompatEditText
import androidx.core.graphics.ColorUtils
import androidx.core.text.HtmlCompat
+import pl.szczodrzynski.edziennik.data.api.Regexes.MESSAGE_META
import pl.szczodrzynski.edziennik.ext.dp
import pl.szczodrzynski.edziennik.ext.getWordBounds
import pl.szczodrzynski.edziennik.ext.resolveAttr
@@ -45,7 +46,7 @@ object BetterHtml {
.toRegex(RegexOption.IGNORE_CASE)
var text = html
- .replace("\\[META:[A-z0-9]+;[0-9-]+]".toRegex(), "")
+ .replace(MESSAGE_META, "")
.replace("background-color: ?$hexPattern;".toRegex(), "")
// treat paragraphs as if they had no margin
.replace("Open-source licenses
Privacy policy
E-register
- © Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - 2022
+ © Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 – 2022
Click to check for updates
Update
Version
diff --git a/build.gradle b/build.gradle
index c259c51b..c9b3fbae 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,8 +23,8 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'com.google.gms:google-services:4.3.13'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
+ classpath 'com.google.gms:google-services:4.3.14'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
}
}