Merge branch 'develop'

This commit is contained in:
Kuba Szczodrzyński 2022-11-28 20:39:51 +01:00
commit a322986df5
No known key found for this signature in database
GPG Key ID: 70CB8A85BA1633CB
15 changed files with 63 additions and 27 deletions

View File

@ -1,14 +1,7 @@
<h3>Wersja 4.13, 2022-10-26</h3> <h3>Wersja 4.13.2, 2022-11-28</h3>
<ul> <ul>
<li>Poprawione powiadomienia na Androidzie 13. @santoni0</li> <li>Poprawiono synchronizację w Mobidzienniku bez ustawionego adresu e-mail.</li>
<li>Opcja kolorowania bloków w planie lekcji.</li> <li>Poprawiono błąd synchronizacji w Vulcanie.</li>
<li><b>USOS</b> - pierwsza wersja obsługi systemu. Osobne rodzaje wydarzeń (oraz wygląd niektórych części aplikacji) lepiej dostosowany do nauki na studiach.</li>
<li>Możliwość dostosowania wyświetlania planu lekcji.</li>
<li>Opcja ustawienia nowych wydarzeń domyślnie jako udostępnione.</li>
<li>Poprawione udostępnianie notatek dotyczących danej lekcji</li>
<li>Bardziej czytelna legenda rodzaju udostępnionego wydarzenia.</li>
<li>Poprawione opcje filtrowania powiadomień i wyboru przycisków menu bocznego.</li>
<li>Ulepszony system pobierania aktualizacji aplikacji.</li>
</ul> </ul>
<br> <br>
<br> <br>

View File

@ -9,7 +9,7 @@
/*secret password - removed for source code publication*/ /*secret password - removed for source code publication*/
static toys AES_IV[16] = { static toys AES_IV[16] = {
0xce, 0x63, 0xdd, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 0x8c, 0xad, 0x9c, 0x3e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat); unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);

View File

@ -33,7 +33,7 @@ class Config(db: AppDb) : BaseConfig(db) {
var update by config<Update?>(null) var update by config<Update?>(null)
var updatesChannel by config<String>("release") var updatesChannel by config<String>("release")
var devMode by config<Boolean?>(null) var devMode by config<Boolean?>("debugMode", null)
var devModePassword by config<String?>(null) var devModePassword by config<String?>(null)
var enableChucker by config<Boolean?>(null) var enableChucker by config<Boolean?>(null)

View File

@ -115,9 +115,9 @@ class ConfigDelegate<T>(
is Boolean -> value is Boolean -> value
// enums, maps & collections // enums, maps & collections
is Enum<*> -> value.toInt() is Enum<*> -> value.toInt()
is Collection<*> -> JsonArray(value.map { is Collection<*> -> value.map {
if (it is Number || it is Boolean) it else serialize(it, serializeObjects = false) if (it is Number || it is Boolean) it else serialize(it, serializeObjects = false)
}) }.toJsonElement()
is Map<*, *> -> gson.toJson(value.mapValues { (_, it) -> is Map<*, *> -> gson.toJson(value.mapValues { (_, it) ->
if (it is Number || it is Boolean) it else serialize(it, serializeObjects = false) if (it is Number || it is Boolean) it else serialize(it, serializeObjects = false)
}) })

View File

@ -36,7 +36,7 @@ class LibrusApiNotices(override val data: DataLibrus,
val id = note.getLong("Id") ?: return@forEach val id = note.getLong("Id") ?: return@forEach
val text = note.getString("Text") ?: "" val text = note.getString("Text") ?: ""
val categoryId = note.getJsonObject("Category")?.getLong("Id") ?: -1 val categoryId = note.getJsonObject("Category")?.getLong("Id") ?: -1
val teacherId = note.getJsonObject("AddedBy")?.getLong("Id") ?: -1 val teacherId = note.getJsonObject("Teacher")?.getLong("Id") ?: -1
val addedDate = note.getString("Date")?.let { Date.fromY_m_d(it) } ?: return@forEach val addedDate = note.getString("Date")?.let { Date.fromY_m_d(it) } ?: return@forEach
val type = when (note.getInt("Positive")) { val type = when (note.getInt("Positive")) {

View File

@ -125,7 +125,7 @@ class LibrusMessagesGetMessage(override val data: DataLibrus,
val receiverId = teacher?.id ?: -1 val receiverId = teacher?.id ?: -1
teacher?.loginId = receiverLoginId teacher?.loginId = receiverLoginId
val readDateText = message.select("readed").text() val readDateText = receiver.select("readed").text()
val readDate = when (readDateText.isNotNullNorEmpty()) { val readDate = when (readDateText.isNotNullNorEmpty()) {
true -> Date.fromIso(readDateText) true -> Date.fromIso(readDateText)
else -> 0 else -> 0

View File

@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.ENDPOINT_MOBID
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.ext.DAY import pl.szczodrzynski.edziennik.ext.DAY
import pl.szczodrzynski.edziennik.ext.get import pl.szczodrzynski.edziennik.ext.get
import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank
class MobidziennikWebAccountEmail(override val data: DataMobidziennik, class MobidziennikWebAccountEmail(override val data: DataMobidziennik,
override val lastSync: Long?, override val lastSync: Long?,
@ -24,7 +25,8 @@ class MobidziennikWebAccountEmail(override val data: DataMobidziennik,
MobidziennikLuckyNumberExtractor(data, text) MobidziennikLuckyNumberExtractor(data, text)
val email = Regexes.MOBIDZIENNIK_ACCOUNT_EMAIL.find(text)?.let { it[1] } val email = Regexes.MOBIDZIENNIK_ACCOUNT_EMAIL.find(text)?.let { it[1] }
data.loginEmail = email if (email.isNotNullNorBlank())
data.loginEmail = email
data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL, if (email == null) 3* DAY else 7* DAY) data.setSyncNext(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL, if (email == null) 3* DAY else 7* DAY)
onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL) onSuccess(ENDPOINT_MOBIDZIENNIK_WEB_ACCOUNT_EMAIL)

View File

@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
import pl.szczodrzynski.edziennik.ext.JsonObject import pl.szczodrzynski.edziennik.ext.JsonObject
import pl.szczodrzynski.edziennik.ext.getJsonObject import pl.szczodrzynski.edziennik.ext.getJsonObject
import pl.szczodrzynski.edziennik.ext.getString import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.Utils
@ -77,7 +78,9 @@ class MobidziennikLoginApi2(val data: DataMobidziennik, val onSuccess: () -> Uni
} }
} }
data.loginEmail = json.getString("email") val email = json.getString("email")
if (email.isNotNullNorBlank())
data.loginEmail = email
data.globalId = json.getString("id_global") data.globalId = json.getString("id_global")
data.loginId = json.getString("login") data.loginId = json.getString("login")
onSuccess() onSuccess()

View File

@ -26,6 +26,7 @@ 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 java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.HttpURLConnection.HTTP_NOT_FOUND
import java.net.URLEncoder import java.net.URLEncoder
import java.time.Instant import java.time.Instant
import java.time.LocalDateTime import java.time.LocalDateTime
@ -183,6 +184,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
payload: JsonElement? = null, payload: JsonElement? = null,
baseUrl: Boolean = false, baseUrl: Boolean = false,
firebaseToken: String? = null, firebaseToken: String? = null,
allow404: Boolean = false,
crossinline onSuccess: (json: T, response: Response?) -> Unit crossinline onSuccess: (json: T, response: Response?) -> Unit
) { ) {
val url = "${if (baseUrl) data.apiUrl else data.fullApiUrl}$endpoint" val url = "${if (baseUrl) data.apiUrl else data.fullApiUrl}$endpoint"
@ -295,6 +297,19 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
} }
override fun onFailure(response: Response?, throwable: Throwable?) { override fun onFailure(response: Response?, throwable: Throwable?) {
if (allow404 && response?.code() == HTTP_NOT_FOUND) {
try {
onSuccess(null as T, response)
} catch (e: Exception) {
data.error(
ApiError(tag, EXCEPTION_VULCAN_HEBE_REQUEST)
.withResponse(response)
.withThrowable(e)
)
}
return
}
data.error( data.error(
ApiError(tag, ERROR_REQUEST_FAILURE) ApiError(tag, ERROR_REQUEST_FAILURE)
.withResponse(response) .withResponse(response)
@ -338,6 +353,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
query: Map<String, String> = mapOf(), query: Map<String, String> = mapOf(),
baseUrl: Boolean = false, baseUrl: Boolean = false,
firebaseToken: String? = null, firebaseToken: String? = null,
allow404: Boolean = false,
crossinline onSuccess: (json: T, response: Response?) -> Unit crossinline onSuccess: (json: T, response: Response?) -> Unit
) { ) {
val queryPath = query.map { val queryPath = query.map {
@ -348,6 +364,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
if (query.isNotEmpty()) "$endpoint?$queryPath" else endpoint, if (query.isNotEmpty()) "$endpoint?$queryPath" else endpoint,
baseUrl = baseUrl, baseUrl = baseUrl,
firebaseToken = firebaseToken, firebaseToken = firebaseToken,
allow404 = allow404,
onSuccess = onSuccess onSuccess = onSuccess
) )
} }
@ -382,6 +399,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
messageBox: String? = null, messageBox: String? = null,
params: Map<String, String> = mapOf(), params: Map<String, String> = mapOf(),
includeFilterType: Boolean = true, includeFilterType: Boolean = true,
allow404: Boolean = false,
onSuccess: (data: List<JsonObject>, response: Response?) -> Unit onSuccess: (data: List<JsonObject>, response: Response?) -> Unit
) { ) {
val url = if (includeFilterType && filterType != null) val url = if (includeFilterType && filterType != null)
@ -427,8 +445,8 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
) )
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
apiGet(tag, url, query) { json: JsonArray, response -> apiGet(tag, url, query, allow404 = allow404) { json: JsonArray?, response ->
onSuccess(json.map { it.asJsonObject }, response) onSuccess(json?.map { it.asJsonObject } ?: listOf(), response)
} }
} }
} }

View File

@ -19,6 +19,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENTS_
import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_STUDENT 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.data.db.entity.Teacher.Companion.TYPE_TEACHER
import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.ext.*
import java.net.HttpURLConnection.HTTP_NOT_FOUND
class VulcanHebeAddressbook( class VulcanHebeAddressbook(
override val data: DataVulcan, override val data: DataVulcan,
@ -41,8 +42,15 @@ class VulcanHebeAddressbook(
VULCAN_HEBE_ENDPOINT_ADDRESSBOOK, VULCAN_HEBE_ENDPOINT_ADDRESSBOOK,
HebeFilterType.BY_PERSON, HebeFilterType.BY_PERSON,
lastSync = lastSync, lastSync = lastSync,
includeFilterType = false includeFilterType = false,
) { list, _ -> allow404 = true,
) { list, response ->
if (response?.code() == HTTP_NOT_FOUND) {
data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK, 2 * DAY)
onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK)
return@apiGetList
}
list.forEach { person -> list.forEach { person ->
val id = person.getString("Id") ?: return@forEach val id = person.getString("Id") ?: return@forEach

View File

@ -46,6 +46,6 @@ object Signing {
/*fun provideKey(param1: String, param2: Long): ByteArray {*/ /*fun provideKey(param1: String, param2: Long): ByteArray {*/
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray { fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
return "$param1.MTIzNDU2Nzg5MDHSZrnOj0===.$param2".sha256() return "$param1.MTIzNDU2Nzg5MDLUEjNGMN===.$param2".sha256()
} }
} }

View File

@ -6,6 +6,8 @@ package pl.szczodrzynski.edziennik.data.db.enums
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
import pl.szczodrzynski.edziennik.data.db.entity.Profile import pl.szczodrzynski.edziennik.data.db.entity.Profile
import pl.szczodrzynski.edziennik.ext.getString
import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank
enum class LoginMethod( enum class LoginMethod(
val loginType: LoginType, val loginType: LoginType,
@ -26,7 +28,7 @@ enum class LoginMethod(
MOBIDZIENNIK_API2( MOBIDZIENNIK_API2(
loginType = LoginType.MOBIDZIENNIK, loginType = LoginType.MOBIDZIENNIK,
id = 1300, id = 1300,
isPossible = { profile, _ -> profile?.studentData?.has("email") ?: false }, isPossible = { profile, _ -> profile?.studentData?.getString("email").isNotNullNorBlank() },
), ),
LIBRUS_PORTAL( LIBRUS_PORTAL(
loginType = LoginType.LIBRUS, loginType = LoginType.LIBRUS,
@ -57,7 +59,7 @@ enum class LoginMethod(
VULCAN_WEB_MAIN( VULCAN_WEB_MAIN(
loginType = LoginType.VULCAN, loginType = LoginType.VULCAN,
id = 4100, id = 4100,
isPossible = { _, loginStore -> loginStore.hasLoginData("webHost") }, isPossible = { _, loginStore -> loginStore.getLoginData("webHost", null).isNotNullNorBlank() },
), ),
VULCAN_HEBE( VULCAN_HEBE(
loginType = LoginType.VULCAN, loginType = LoginType.VULCAN,

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.ext package pl.szczodrzynski.edziennik.ext
import android.os.Bundle import android.os.Bundle
import com.google.gson.Gson
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
@ -48,6 +49,11 @@ fun JsonObject.putEnum(key: String, value: Enum<*>) = addProperty(key, value.toI
fun String.toJsonObject(): JsonObject? = try { JsonParser.parseString(this).asJsonObject } catch (ignore: Exception) { null } fun String.toJsonObject(): JsonObject? = try { JsonParser.parseString(this).asJsonObject } catch (ignore: Exception) { null }
fun String.toJsonArray(): JsonArray? = try { JsonParser.parseString(this).asJsonArray } catch (ignore: Exception) { null } fun String.toJsonArray(): JsonArray? = try { JsonParser.parseString(this).asJsonArray } catch (ignore: Exception) { null }
fun Any?.toJsonElement(): JsonElement = when (this) {
is Collection<*> -> JsonArray(this)
else -> Gson().toJsonTree(this)
}
operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value) operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value)
operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value) operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value)
operator fun JsonObject.set(key: String, value: String?) = this.addProperty(key, value) operator fun JsonObject.set(key: String, value: String?) = this.addProperty(key, value)
@ -67,6 +73,7 @@ fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
is Number -> addProperty(key, value) is Number -> addProperty(key, value)
is Boolean -> addProperty(key, value) is Boolean -> addProperty(key, value)
is Enum<*> -> addProperty(key, value.toInt()) is Enum<*> -> addProperty(key, value.toInt())
else -> add(key, property.toJsonElement())
} }
} }
} }
@ -98,6 +105,8 @@ fun JsonArray(properties: Collection<Any?>): JsonArray {
is Char -> add(property as Char?) is Char -> add(property as Char?)
is Number -> add(property as Number?) is Number -> add(property as Number?)
is Boolean -> add(property as Boolean?) is Boolean -> add(property as Boolean?)
is Enum<*> -> add(property.toInt())
else -> add(property.toJsonElement())
} }
} }
} }

View File

@ -1433,4 +1433,5 @@
<string name="dialog_lesson_attendance_details">Details</string> <string name="dialog_lesson_attendance_details">Details</string>
<string name="menu_agenda_config">Agenda settings</string> <string name="menu_agenda_config">Agenda settings</string>
<string name="registration_config_note_sharing_title">Share notes</string> <string name="registration_config_note_sharing_title">Share notes</string>
<string name="home_timetable_all_lessons">All lessons:</string>
</resources> </resources>

View File

@ -5,8 +5,8 @@ buildscript {
kotlin_version = '1.6.10' kotlin_version = '1.6.10'
release = [ release = [
versionName: "4.13", versionName: "4.13.2",
versionCode: 4130099 versionCode: 4130299
] ]
setup = [ setup = [