mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-31 13:48:20 +01:00
Merge branch 'develop'
This commit is contained in:
commit
fd31cafd8f
@ -183,7 +183,6 @@ dependencies {
|
|||||||
|
|
||||||
//implementation "org.redundent:kotlin-xml-builder:1.5.3"
|
//implementation "org.redundent:kotlin-xml-builder:1.5.3"
|
||||||
|
|
||||||
implementation "io.github.wulkanowy:signer-android:0.1.1"
|
|
||||||
implementation 'com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31'
|
implementation 'com.github.wulkanowy.uonet-request-signer:hebe-jvm:a99ca50a31'
|
||||||
|
|
||||||
implementation "androidx.work:work-runtime-ktx:${versions.work}"
|
implementation "androidx.work:work-runtime-ktx:${versions.work}"
|
||||||
@ -211,7 +210,7 @@ dependencies {
|
|||||||
implementation 'com.qifan.powerpermission:powerpermission:1.3.0'
|
implementation 'com.qifan.powerpermission:powerpermission:1.3.0'
|
||||||
implementation 'com.qifan.powerpermission:powerpermission-coroutines:1.3.0'
|
implementation 'com.qifan.powerpermission:powerpermission-coroutines:1.3.0'
|
||||||
|
|
||||||
implementation 'com.github.kuba2k2.FSLogin:lib:master-SNAPSHOT'
|
implementation 'com.github.kuba2k2.FSLogin:lib:2.0.0'
|
||||||
implementation 'pl.droidsonroids:jspoon:1.3.2'
|
implementation 'pl.droidsonroids:jspoon:1.3.2'
|
||||||
implementation "com.squareup.retrofit2:converter-scalars:2.8.1"
|
implementation "com.squareup.retrofit2:converter-scalars:2.8.1"
|
||||||
implementation "pl.droidsonroids.retrofit2:converter-jspoon:1.3.2"
|
implementation "pl.droidsonroids.retrofit2:converter-jspoon:1.3.2"
|
||||||
|
@ -67,3 +67,6 @@
|
|||||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.request.** { *; }
|
||||||
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.data.api.szkolny.response.** { *; }
|
||||||
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo$Platform { *; }
|
-keepclassmembernames class pl.szczodrzynski.edziennik.ui.modules.login.LoginInfo$Platform { *; }
|
||||||
|
|
||||||
|
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData { *; }
|
||||||
|
-keepclassmembernames class pl.szczodrzynski.fslogin.realm.RealmData$Type { *; }
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
<h3>Wersja 4.5, 2021-02-21</h3>
|
<h3>Wersja 4.6, 2021-02-26</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Vulcan: aplikacja Szkolny.eu zaktualizowana w związku z wygaszeniem aplikacji Dzienniczek+.</li>
|
<li>Vulcan: aplikacja Szkolny.eu zaktualizowana w związku z wygaszeniem aplikacji Dzienniczek+.</li>
|
||||||
<li><b>Mogą pojawić się brakujące funkcje, np. wysyłanie wiadomości - zostaną one wprowadzone w najbliższych dniach.</b></li>
|
<li>Vulcan: dodano wyświetlanie <b>szczęśliwego numerka.</b></li>
|
||||||
|
<li>Vulcan: dodano możliwość logowania adresem e-mail lub nazwą użytkownika - wersja testowa.</li>
|
||||||
|
<li>Vulcan: usunięto wyświetlanie zadań domowych i sprawdzianów z poprzednich lat.</li>
|
||||||
|
<li>Mobidziennik: naprawiono otwieranie wysłanej wiadomości.</li>
|
||||||
|
<li>Mobidziennik: poprawiono wyświetlanie oraz liczenie e-obecności.</li>
|
||||||
|
<li>iDziennik: usunięto dziennik w związku z wygaszeniem systemu. [*]</li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
@ -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] = {
|
||||||
0x4f, 0x43, 0x04, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
0x9f, 0xff, 0x0f, 0x1f, 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);
|
||||||
|
|
||||||
|
@ -43,10 +43,9 @@ import androidx.viewpager.widget.ViewPager
|
|||||||
import com.google.android.gms.security.ProviderInstaller
|
import com.google.android.gms.security.ProviderInstaller
|
||||||
import com.google.android.material.button.MaterialButton
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.google.gson.*
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
@ -538,6 +537,12 @@ fun String.md5(): String {
|
|||||||
return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
|
return BigInteger(1, md.digest(toByteArray())).toString(16).padStart(32, '0')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.sha1Hex(): String {
|
||||||
|
val md = MessageDigest.getInstance("SHA-1")
|
||||||
|
md.update(toByteArray())
|
||||||
|
return md.digest().joinToString("") { "%02x".format(it) }
|
||||||
|
}
|
||||||
|
|
||||||
fun String.sha256(): ByteArray {
|
fun String.sha256(): ByteArray {
|
||||||
val md = MessageDigest.getInstance("SHA-256")
|
val md = MessageDigest.getInstance("SHA-256")
|
||||||
md.update(toByteArray())
|
md.update(toByteArray())
|
||||||
@ -697,6 +702,21 @@ fun JsonObject(vararg properties: Pair<String, Any?>): JsonObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun JsonObject.toBundle(): Bundle {
|
||||||
|
return Bundle().also {
|
||||||
|
for ((key, value) in this.entrySet()) {
|
||||||
|
when (value) {
|
||||||
|
is JsonObject -> it.putBundle(key, value.toBundle())
|
||||||
|
is JsonPrimitive -> when {
|
||||||
|
value.isString -> it.putString(key, value.asString)
|
||||||
|
value.isBoolean -> it.putBoolean(key, value.asBoolean)
|
||||||
|
value.isNumber -> it.putInt(key, value.asInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun JsonArray(vararg properties: Any?): JsonArray {
|
fun JsonArray(vararg properties: Any?): JsonArray {
|
||||||
return JsonArray().apply {
|
return JsonArray().apply {
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
|
@ -751,6 +751,11 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskErrorEvent(event: ApiTaskErrorEvent) {
|
fun onApiTaskErrorEvent(event: ApiTaskErrorEvent) {
|
||||||
EventBus.getDefault().removeStickyEvent(event)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
if (event.error.errorCode == ERROR_VULCAN_API_DEPRECATED) {
|
||||||
|
if (event.error.profileId != App.profileId)
|
||||||
|
return
|
||||||
|
ErrorDetailsDialog(this, listOf(event.error))
|
||||||
|
}
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
subtitleFormat = R.string.toolbar_subtitle
|
subtitleFormat = R.string.toolbar_subtitle
|
||||||
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
subtitleFormatWithUnread = R.plurals.toolbar_subtitle_with_unread
|
||||||
@ -758,9 +763,6 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
mainSnackbar.dismiss()
|
mainSnackbar.dismiss()
|
||||||
errorSnackbar.addError(event.error).show()
|
errorSnackbar.addError(event.error).show()
|
||||||
if (event.error.errorCode == ERROR_VULCAN_API_DEPRECATED) {
|
|
||||||
ErrorDetailsDialog(this, listOf(event.error))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
||||||
|
@ -105,6 +105,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() }
|
get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() }
|
||||||
set(value) { set("widgetConfigs", value); mWidgetConfigs = value }
|
set(value) { set("widgetConfigs", value); mWidgetConfigs = value }
|
||||||
|
|
||||||
|
private var mArchiverEnabled: Boolean? = null
|
||||||
|
var archiverEnabled: Boolean
|
||||||
|
get() { mArchiverEnabled = mArchiverEnabled ?: values.get("archiverEnabled", true); return mArchiverEnabled ?: true }
|
||||||
|
set(value) { set("archiverEnabled", value); mArchiverEnabled = value }
|
||||||
|
|
||||||
private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow()
|
private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow()
|
||||||
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
|
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
|
||||||
init {
|
init {
|
||||||
|
@ -90,11 +90,6 @@ const val IDZIENNIK_API_MESSAGES_SENT = "Wiadomosci/Wyslane"
|
|||||||
|
|
||||||
val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT
|
val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT
|
||||||
|
|
||||||
const val VULCAN_API_USER_AGENT = "MobileUserAgent"
|
|
||||||
const val VULCAN_API_APP_NAME = "VULCAN-Android-ModulUcznia"
|
|
||||||
const val VULCAN_API_APP_VERSION = "20.5.1.470"
|
|
||||||
const val VULCAN_API_PASSWORD = "CE75EA598C7743AD9B0B7328DED85B06"
|
|
||||||
const val VULCAN_API_PASSWORD_FAKELOG = "012345678901234567890123456789AB"
|
|
||||||
const val VULCAN_HEBE_USER_AGENT = "Dart/2.10 (dart:io)"
|
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_NAME = "DzienniczekPlus 2.0"
|
||||||
const val VULCAN_HEBE_APP_VERSION = "21.02.09 (G)"
|
const val VULCAN_HEBE_APP_VERSION = "21.02.09 (G)"
|
||||||
@ -106,36 +101,24 @@ val VULCAN_API_DEVICE_NAME by lazy {
|
|||||||
base.take(baseMaxLength) + VULCAN_API_DEVICE_NAME_SUFFIX
|
base.take(baseMaxLength) + VULCAN_API_DEVICE_NAME_SUFFIX
|
||||||
}
|
}
|
||||||
|
|
||||||
const val VULCAN_API_ENDPOINT_CERTIFICATE = "mobile-api/Uczen.v3.UczenStart/Certyfikat"
|
|
||||||
const val VULCAN_API_ENDPOINT_STUDENT_LIST = "mobile-api/Uczen.v3.UczenStart/ListaUczniow"
|
|
||||||
const val VULCAN_API_ENDPOINT_DICTIONARIES = "mobile-api/Uczen.v3.Uczen/Slowniki"
|
|
||||||
const val VULCAN_API_ENDPOINT_TIMETABLE = "mobile-api/Uczen.v3.Uczen/PlanLekcjiZeZmianami"
|
|
||||||
const val VULCAN_API_ENDPOINT_GRADES = "mobile-api/Uczen.v3.Uczen/Oceny"
|
|
||||||
const val VULCAN_API_ENDPOINT_GRADES_PROPOSITIONS = "mobile-api/Uczen.v3.Uczen/OcenyPodsumowanie"
|
|
||||||
const val VULCAN_API_ENDPOINT_EVENTS = "mobile-api/Uczen.v3.Uczen/Sprawdziany"
|
|
||||||
const val VULCAN_API_ENDPOINT_HOMEWORK = "mobile-api/Uczen.v3.Uczen/ZadaniaDomowe"
|
|
||||||
const val VULCAN_API_ENDPOINT_NOTICES = "mobile-api/Uczen.v3.Uczen/UwagiUcznia"
|
|
||||||
const val VULCAN_API_ENDPOINT_ATTENDANCE = "mobile-api/Uczen.v3.Uczen/Frekwencje"
|
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_RECEIVED = "mobile-api/Uczen.v3.Uczen/WiadomosciOdebrane"
|
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_SENT = "mobile-api/Uczen.v3.Uczen/WiadomosciWyslane"
|
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS = "mobile-api/Uczen.v3.Uczen/ZmienStatusWiadomosci"
|
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_ADD = "mobile-api/Uczen.v3.Uczen/DodajWiadomosc"
|
|
||||||
const val VULCAN_API_ENDPOINT_PUSH = "mobile-api/Uczen.v3.Uczen/UstawPushToken"
|
|
||||||
const val VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/WiadomosciZalacznik"
|
|
||||||
const val VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS = "mobile-api/Uczen.v3.Uczen/ZadaniaDomoweZalacznik"
|
|
||||||
const val VULCAN_WEB_ENDPOINT_LUCKY_NUMBER = "Start.mvc/GetKidsLuckyNumbers"
|
const val VULCAN_WEB_ENDPOINT_LUCKY_NUMBER = "Start.mvc/GetKidsLuckyNumbers"
|
||||||
const val VULCAN_WEB_ENDPOINT_REGISTER_DEVICE = "RejestracjaUrzadzeniaToken.mvc/Get"
|
const val VULCAN_WEB_ENDPOINT_REGISTER_DEVICE = "RejestracjaUrzadzeniaToken.mvc/Get"
|
||||||
const val VULCAN_HEBE_ENDPOINT_REGISTER_NEW = "api/mobile/register/new"
|
const val VULCAN_HEBE_ENDPOINT_REGISTER_NEW = "api/mobile/register/new"
|
||||||
const val VULCAN_HEBE_ENDPOINT_MAIN = "api/mobile/register/hebe"
|
const val VULCAN_HEBE_ENDPOINT_MAIN = "api/mobile/register/hebe"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_PUSH_ALL = "api/mobile/push/all"
|
||||||
const val VULCAN_HEBE_ENDPOINT_TIMETABLE = "api/mobile/schedule"
|
const val VULCAN_HEBE_ENDPOINT_TIMETABLE = "api/mobile/schedule"
|
||||||
const val VULCAN_HEBE_ENDPOINT_TIMETABLE_CHANGES = "api/mobile/schedule/changes"
|
const val VULCAN_HEBE_ENDPOINT_TIMETABLE_CHANGES = "api/mobile/schedule/changes"
|
||||||
const val VULCAN_HEBE_ENDPOINT_ADDRESSBOOK = "api/mobile/addressbook"
|
const val VULCAN_HEBE_ENDPOINT_ADDRESSBOOK = "api/mobile/addressbook"
|
||||||
const val VULCAN_HEBE_ENDPOINT_EXAMS = "api/mobile/exam"
|
const val VULCAN_HEBE_ENDPOINT_EXAMS = "api/mobile/exam"
|
||||||
const val VULCAN_HEBE_ENDPOINT_GRADES = "api/mobile/grade"
|
const val VULCAN_HEBE_ENDPOINT_GRADES = "api/mobile/grade"
|
||||||
|
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_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_ATTENDANCE = "api/mobile/lesson"
|
||||||
const val VULCAN_HEBE_ENDPOINT_MESSAGES = "api/mobile/message"
|
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_STATUS = "api/mobile/message/status"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_MESSAGES_SEND = "api/mobile/message"
|
||||||
|
const val VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER = "api/mobile/school/lucky"
|
||||||
|
|
||||||
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
||||||
|
|
||||||
|
@ -148,17 +148,11 @@ const val ERROR_MOBIDZIENNIK_WEB_SERVER_PROBLEM = 218
|
|||||||
|
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_PIN = 309
|
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING = 310
|
const val ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING = 310
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING = 311
|
const val ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING = 311
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING = 312
|
const val ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING = 312
|
||||||
const val ERROR_LOGIN_VULCAN_EXPIRED_TOKEN = 321
|
const val ERROR_LOGIN_VULCAN_EXPIRED_TOKEN = 321
|
||||||
const val ERROR_LOGIN_VULCAN_OTHER = 322
|
|
||||||
const val ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN = 330
|
|
||||||
const val ERROR_LOGIN_VULCAN_NO_PUPILS = 331
|
const val ERROR_LOGIN_VULCAN_NO_PUPILS = 331
|
||||||
const val ERROR_VULCAN_API_MAINTENANCE = 340
|
|
||||||
const val ERROR_VULCAN_API_BAD_REQUEST = 341
|
|
||||||
const val ERROR_VULCAN_API_OTHER = 342
|
|
||||||
const val ERROR_VULCAN_ATTACHMENT_DOWNLOAD = 343
|
const val ERROR_VULCAN_ATTACHMENT_DOWNLOAD = 343
|
||||||
const val ERROR_VULCAN_WEB_DATA_MISSING = 344
|
const val ERROR_VULCAN_WEB_DATA_MISSING = 344
|
||||||
const val ERROR_VULCAN_WEB_429 = 345
|
const val ERROR_VULCAN_WEB_429 = 345
|
||||||
@ -171,30 +165,14 @@ const val ERROR_VULCAN_WEB_CERTIFICATE_POST_FAILED = 351
|
|||||||
const val ERROR_VULCAN_WEB_GRADUATE_ACCOUNT = 352
|
const val ERROR_VULCAN_WEB_GRADUATE_ACCOUNT = 352
|
||||||
const val ERROR_VULCAN_WEB_NO_SCHOOLS = 353
|
const val ERROR_VULCAN_WEB_NO_SCHOOLS = 353
|
||||||
const val ERROR_VULCAN_HEBE_OTHER = 354
|
const val ERROR_VULCAN_HEBE_OTHER = 354
|
||||||
|
const val ERROR_VULCAN_HEBE_SIGNATURE_ERROR = 360
|
||||||
|
const val ERROR_VULCAN_HEBE_INVALID_PAYLOAD = 361
|
||||||
|
const val ERROR_VULCAN_HEBE_FIREBASE_ERROR = 362
|
||||||
|
const val ERROR_VULCAN_HEBE_CERTIFICATE_GONE = 363
|
||||||
|
const val ERROR_VULCAN_HEBE_SERVER_ERROR = 364
|
||||||
|
const val ERROR_VULCAN_HEBE_ENTITY_NOT_FOUND = 365
|
||||||
const val ERROR_VULCAN_API_DEPRECATED = 390
|
const val ERROR_VULCAN_API_DEPRECATED = 390
|
||||||
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED = 403
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_MAINTENANCE = 404
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_SERVER_ERROR = 405
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_OTHER = 410
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_API_NO_ACCESS = 411 /* {"d":{"__type":"mds.Web.mod_komunikator.WS_mod_wiadomosci+detailWiadomosci","Wiadomosc":{"_recordId":0,"DataNadania":null,"DataOdczytania":null,"Nadawca":null,"ListaOdbiorcow":[],"Tytul":null,"Text":null,"ListaZal":[]},"Bledy":{"__type":"mds.Module.Globalne+sBledy","CzyJestBlad":true,"ListaBledow":["Nie masz dostępu do tych zasobów!"],"ListaKodowBledow":[]},"czyJestWiecej":false}} */
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION = 420
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH = 421
|
|
||||||
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER = 422
|
|
||||||
const val ERROR_IDZIENNIK_WEB_ACCESS_DENIED = 430
|
|
||||||
const val ERROR_IDZIENNIK_WEB_OTHER = 431
|
|
||||||
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_IDZIENNIK_API_ACCESS_DENIED = 450
|
|
||||||
const val ERROR_IDZIENNIK_API_OTHER = 451
|
|
||||||
const val ERROR_IDZIENNIK_API_NO_REGISTER = 452
|
|
||||||
const val ERROR_IDZIENNIK_WEB_RECIPIENT_LIST_NO_PERMISSION = 453
|
|
||||||
|
|
||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501
|
||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510
|
||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511
|
||||||
@ -217,14 +195,10 @@ const val EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN = 903
|
|||||||
const val EXCEPTION_LIBRUS_API_REQUEST = 904
|
const val EXCEPTION_LIBRUS_API_REQUEST = 904
|
||||||
const val EXCEPTION_LIBRUS_SYNERGIA_REQUEST = 905
|
const val EXCEPTION_LIBRUS_SYNERGIA_REQUEST = 905
|
||||||
const val EXCEPTION_MOBIDZIENNIK_WEB_REQUEST = 906
|
const val EXCEPTION_MOBIDZIENNIK_WEB_REQUEST = 906
|
||||||
const val EXCEPTION_VULCAN_API_REQUEST = 907
|
|
||||||
const val EXCEPTION_MOBIDZIENNIK_WEB_FILE_REQUEST = 908
|
const val EXCEPTION_MOBIDZIENNIK_WEB_FILE_REQUEST = 908
|
||||||
const val EXCEPTION_LIBRUS_MESSAGES_FILE_REQUEST = 909
|
const val EXCEPTION_LIBRUS_MESSAGES_FILE_REQUEST = 909
|
||||||
const val EXCEPTION_NOTIFY = 910
|
const val EXCEPTION_NOTIFY = 910
|
||||||
const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911
|
const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911
|
||||||
const val EXCEPTION_IDZIENNIK_WEB_REQUEST = 912
|
|
||||||
const val EXCEPTION_IDZIENNIK_WEB_API_REQUEST = 913
|
|
||||||
const val EXCEPTION_IDZIENNIK_API_REQUEST = 914
|
|
||||||
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920
|
||||||
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921
|
||||||
const val ERROR_ONEDRIVE_DOWNLOAD = 930
|
const val ERROR_ONEDRIVE_DOWNLOAD = 930
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
||||||
@ -16,14 +14,13 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.Mobidzie
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.login.PodlasieLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
||||||
|
|
||||||
// librus
|
// librus
|
||||||
// mobidziennik
|
// mobidziennik
|
||||||
// idziennik
|
// idziennik [*]
|
||||||
// vulcan
|
// vulcan
|
||||||
// mobireg
|
// mobireg
|
||||||
|
|
||||||
@ -35,14 +32,10 @@ const val LOGIN_TYPE_IDZIENNIK = 3
|
|||||||
const val LOGIN_TYPE_TEMPLATE = 21
|
const val LOGIN_TYPE_TEMPLATE = 21
|
||||||
|
|
||||||
// LOGIN MODES
|
// LOGIN MODES
|
||||||
const val LOGIN_MODE_IDZIENNIK_WEB = 0
|
|
||||||
|
|
||||||
const val LOGIN_MODE_TEMPLATE_WEB = 0
|
const val LOGIN_MODE_TEMPLATE_WEB = 0
|
||||||
|
|
||||||
// LOGIN METHODS
|
// LOGIN METHODS
|
||||||
const val LOGIN_METHOD_NOT_NEEDED = -1
|
const val LOGIN_METHOD_NOT_NEEDED = -1
|
||||||
const val LOGIN_METHOD_IDZIENNIK_WEB = 100
|
|
||||||
const val LOGIN_METHOD_IDZIENNIK_API = 200
|
|
||||||
const val LOGIN_METHOD_TEMPLATE_WEB = 100
|
const val LOGIN_METHOD_TEMPLATE_WEB = 100
|
||||||
const val LOGIN_METHOD_TEMPLATE_API = 200
|
const val LOGIN_METHOD_TEMPLATE_API = 200
|
||||||
|
|
||||||
@ -104,7 +97,6 @@ const val LOGIN_METHOD_VULCAN_WEB_MAIN = 100
|
|||||||
const val LOGIN_METHOD_VULCAN_WEB_NEW = 200
|
const val LOGIN_METHOD_VULCAN_WEB_NEW = 200
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_OLD = 300
|
const val LOGIN_METHOD_VULCAN_WEB_OLD = 300
|
||||||
const val LOGIN_METHOD_VULCAN_WEB_MESSAGES = 400
|
const val LOGIN_METHOD_VULCAN_WEB_MESSAGES = 400
|
||||||
const val LOGIN_METHOD_VULCAN_API = 500
|
|
||||||
const val LOGIN_METHOD_VULCAN_HEBE = 600
|
const val LOGIN_METHOD_VULCAN_HEBE = 600
|
||||||
val vulcanLoginMethods = listOf(
|
val vulcanLoginMethods = listOf(
|
||||||
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_MAIN, VulcanLoginWebMain::class.java)
|
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_WEB_MAIN, VulcanLoginWebMain::class.java)
|
||||||
@ -119,31 +111,11 @@ val vulcanLoginMethods = listOf(
|
|||||||
.withIsPossible { _, _ -> false }
|
.withIsPossible { _, _ -> false }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },*/
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_VULCAN_WEB_MAIN },*/
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_API, VulcanLoginApi::class.java)
|
|
||||||
.withIsPossible { _, loginStore ->
|
|
||||||
loginStore.mode != LOGIN_MODE_VULCAN_HEBE
|
|
||||||
}
|
|
||||||
.withRequiredLoginMethod { _, loginStore ->
|
|
||||||
if (loginStore.mode == LOGIN_MODE_VULCAN_WEB) LOGIN_METHOD_VULCAN_WEB_MAIN else LOGIN_METHOD_NOT_NEEDED
|
|
||||||
},
|
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_HEBE, VulcanLoginHebe::class.java)
|
LoginMethod(LOGIN_TYPE_VULCAN, LOGIN_METHOD_VULCAN_HEBE, VulcanLoginHebe::class.java)
|
||||||
.withIsPossible { _, loginStore ->
|
.withIsPossible { _, loginStore ->
|
||||||
loginStore.mode != LOGIN_MODE_VULCAN_API
|
loginStore.mode != LOGIN_MODE_VULCAN_API
|
||||||
}
|
}
|
||||||
.withRequiredLoginMethod { _, loginStore ->
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
if (loginStore.mode == LOGIN_MODE_VULCAN_WEB) LOGIN_METHOD_VULCAN_WEB_MAIN else LOGIN_METHOD_NOT_NEEDED
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val idziennikLoginMethods = listOf(
|
|
||||||
LoginMethod(LOGIN_TYPE_IDZIENNIK, LOGIN_METHOD_IDZIENNIK_WEB, IdziennikLoginWeb::class.java)
|
|
||||||
.withIsPossible { _, _ -> true }
|
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_IDZIENNIK, LOGIN_METHOD_IDZIENNIK_API, IdziennikLoginApi::class.java)
|
|
||||||
.withIsPossible { _, _ -> true }
|
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_IDZIENNIK_WEB }
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
||||||
|
@ -156,7 +156,7 @@ object Regexes {
|
|||||||
"""\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex()
|
"""\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex()
|
||||||
}
|
}
|
||||||
val VULCAN_WEB_PERMISSIONS by lazy {
|
val VULCAN_WEB_PERMISSIONS by lazy {
|
||||||
"""permissions: '([A-z0-9/=+\-_]+?)'""".toRegex()
|
"""permissions: '([A-z0-9/=+\-_|]+?)'""".toRegex()
|
||||||
}
|
}
|
||||||
val VULCAN_WEB_SYMBOL_VALIDATE by lazy {
|
val VULCAN_WEB_SYMBOL_VALIDATE by lazy {
|
||||||
"""[A-z0-9]+""".toRegex(IGNORE_CASE)
|
"""[A-z0-9]+""".toRegex(IGNORE_CASE)
|
||||||
|
@ -9,7 +9,6 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.Idziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
|
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
|
||||||
@ -123,7 +122,6 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
|
|
||||||
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
||||||
|
@ -1,175 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
|
||||||
|
|
||||||
import androidx.core.util.set
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_WEB
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
|
|
||||||
class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
|
|
||||||
|
|
||||||
fun isWebLoginValid() = loginExpiryTime-30 > currentTimeUnix() && webSessionId.isNotNullNorEmpty() && webAuth.isNotNullNorEmpty()
|
|
||||||
fun isApiLoginValid() = apiExpiryTime-30 > currentTimeUnix() && apiBearer.isNotNullNorEmpty()
|
|
||||||
|
|
||||||
override fun satisfyLoginMethods() {
|
|
||||||
loginMethods.clear()
|
|
||||||
if (isWebLoginValid()) {
|
|
||||||
loginMethods += LOGIN_METHOD_IDZIENNIK_WEB
|
|
||||||
app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", webSessionId)
|
|
||||||
app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", webAuth)
|
|
||||||
}
|
|
||||||
if (isApiLoginValid())
|
|
||||||
loginMethods += LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateUserCode() = "$webSchoolName:$webUsername:$registerId"
|
|
||||||
|
|
||||||
private var mLoginExpiryTime: Long? = null
|
|
||||||
var loginExpiryTime: Long
|
|
||||||
get() { mLoginExpiryTime = mLoginExpiryTime ?: loginStore.getLoginData("loginExpiryTime", 0L); return mLoginExpiryTime ?: 0L }
|
|
||||||
set(value) { loginStore.putLoginData("loginExpiryTime", value); mLoginExpiryTime = value }
|
|
||||||
|
|
||||||
private var mApiExpiryTime: Long? = null
|
|
||||||
var apiExpiryTime: Long
|
|
||||||
get() { mApiExpiryTime = mApiExpiryTime ?: loginStore.getLoginData("apiExpiryTime", 0L); return mApiExpiryTime ?: 0L }
|
|
||||||
set(value) { loginStore.putLoginData("apiExpiryTime", value); mApiExpiryTime = value }
|
|
||||||
|
|
||||||
/* __ __ _
|
|
||||||
\ \ / / | |
|
|
||||||
\ \ /\ / /__| |__
|
|
||||||
\ \/ \/ / _ \ '_ \
|
|
||||||
\ /\ / __/ |_) |
|
|
||||||
\/ \/ \___|_._*/
|
|
||||||
private var mWebSchoolName: String? = null
|
|
||||||
var webSchoolName: String?
|
|
||||||
get() { mWebSchoolName = mWebSchoolName ?: loginStore.getLoginData("schoolName", null); return mWebSchoolName }
|
|
||||||
set(value) { loginStore.putLoginData("schoolName", value); mWebSchoolName = value }
|
|
||||||
private var mWebUsername: String? = null
|
|
||||||
var webUsername: String?
|
|
||||||
get() { mWebUsername = mWebUsername ?: loginStore.getLoginData("username", null); return mWebUsername }
|
|
||||||
set(value) { loginStore.putLoginData("username", value); mWebUsername = value }
|
|
||||||
private var mWebPassword: String? = null
|
|
||||||
var webPassword: String?
|
|
||||||
get() { mWebPassword = mWebPassword ?: loginStore.getLoginData("password", null); return mWebPassword }
|
|
||||||
set(value) { loginStore.putLoginData("password", value); mWebPassword = value }
|
|
||||||
|
|
||||||
private var mWebSessionId: String? = null
|
|
||||||
var webSessionId: String?
|
|
||||||
get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("webSessionId", null); return mWebSessionId }
|
|
||||||
set(value) { loginStore.putLoginData("webSessionId", value); mWebSessionId = value }
|
|
||||||
private var mWebAuth: String? = null
|
|
||||||
var webAuth: String?
|
|
||||||
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
|
||||||
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
|
||||||
|
|
||||||
private var mWebSelectedRegister: Int? = null
|
|
||||||
var webSelectedRegister: Int
|
|
||||||
get() { mWebSelectedRegister = mWebSelectedRegister ?: loginStore.getLoginData("webSelectedRegister", 0); return mWebSelectedRegister ?: 0 }
|
|
||||||
set(value) { loginStore.putLoginData("webSelectedRegister", value); mWebSelectedRegister = value }
|
|
||||||
|
|
||||||
/* _
|
|
||||||
/\ (_)
|
|
||||||
/ \ _ __ _
|
|
||||||
/ /\ \ | '_ \| |
|
|
||||||
/ ____ \| |_) | |
|
|
||||||
/_/ \_\ .__/|_|
|
|
||||||
| |
|
|
||||||
|*/
|
|
||||||
private var mApiBearer: String? = null
|
|
||||||
var apiBearer: String?
|
|
||||||
get() { mApiBearer = mApiBearer ?: loginStore.getLoginData("apiBearer", null); return mApiBearer }
|
|
||||||
set(value) { loginStore.putLoginData("apiBearer", value); mApiBearer = value }
|
|
||||||
|
|
||||||
/* ____ _ _
|
|
||||||
/ __ \| | | |
|
|
||||||
| | | | |_| |__ ___ _ __
|
|
||||||
| | | | __| '_ \ / _ \ '__|
|
|
||||||
| |__| | |_| | | | __/ |
|
|
||||||
\____/ \__|_| |_|\___|*/
|
|
||||||
private var mStudentId: String? = null
|
|
||||||
var studentId: String?
|
|
||||||
get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", null); return mStudentId }
|
|
||||||
set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value }
|
|
||||||
|
|
||||||
private var mRegisterId: Int? = null
|
|
||||||
var registerId: Int
|
|
||||||
get() { mRegisterId = mRegisterId ?: profile?.getStudentData("registerId", 0); return mRegisterId ?: 0 }
|
|
||||||
set(value) { profile?.putStudentData("registerId", value) ?: return; mRegisterId = value }
|
|
||||||
|
|
||||||
private var mSchoolYearId: Int? = null
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,169 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikData
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin.IdziennikFirstLogin
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLogin
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
|
|
||||||
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "Idziennik"
|
|
||||||
}
|
|
||||||
|
|
||||||
val internalErrorList = mutableListOf<Int>()
|
|
||||||
val data: DataIdziennik
|
|
||||||
private var afterLogin: (() -> Unit)? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
data = DataIdziennik(app, profile, loginStore).apply {
|
|
||||||
callback = wrapCallback(this@Idziennik.callback)
|
|
||||||
satisfyLoginMethods()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun completed() {
|
|
||||||
data.saveData()
|
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
|
||||||
|__ __| | /\ | | (_) | | |
|
|
||||||
| | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___
|
|
||||||
| | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \
|
|
||||||
| | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | |
|
|
||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|
||||||
__/ |
|
|
||||||
|__*/
|
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
|
||||||
data.arguments = arguments
|
|
||||||
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId, onlyEndpoints)
|
|
||||||
login()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun login(loginMethodId: Int? = null, afterLogin: (() -> Unit)? = null) {
|
|
||||||
d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
|
|
||||||
if (internalErrorList.isNotEmpty()) {
|
|
||||||
d(TAG, " - Internal errors:")
|
|
||||||
internalErrorList.forEach { d(TAG, " - code $it") }
|
|
||||||
}
|
|
||||||
loginMethodId?.let { data.prepareFor(idziennikLoginMethods, it) }
|
|
||||||
afterLogin?.let { this.afterLogin = it }
|
|
||||||
IdziennikLogin(data) {
|
|
||||||
data()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun data() {
|
|
||||||
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
|
||||||
if (internalErrorList.isNotEmpty()) {
|
|
||||||
d(TAG, " - Internal errors:")
|
|
||||||
internalErrorList.forEach { d(TAG, " - code $it") }
|
|
||||||
}
|
|
||||||
afterLogin?.invoke() ?: IdziennikData(data) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMessage(message: MessageFull) {
|
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
|
||||||
IdziennikWebGetMessage(data, message) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun sendMessage(recipients: List<Teacher>, subject: String, text: String) {
|
|
||||||
login(LOGIN_METHOD_IDZIENNIK_API) {
|
|
||||||
IdziennikWebSendMessage(data, recipients, subject, text) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun markAllAnnouncementsAsRead() {}
|
|
||||||
override fun getAnnouncement(announcement: AnnouncementFull) {}
|
|
||||||
|
|
||||||
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
|
||||||
if (owner is Message) {
|
|
||||||
IdziennikWebGetAttachment(data, owner, attachmentId, attachmentName) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (owner is Event) {
|
|
||||||
IdziennikWebGetHomeworkAttachment(data, owner, attachmentId, attachmentName) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getRecipientList() {
|
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
|
||||||
IdziennikWebGetRecipientList(data) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getEvent(eventFull: EventFull) {
|
|
||||||
login(LOGIN_METHOD_IDZIENNIK_WEB) {
|
|
||||||
IdziennikWebGetHomework(data, eventFull) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun firstLogin() { IdziennikFirstLogin(data) { completed() } }
|
|
||||||
override fun cancel() {
|
|
||||||
d(TAG, "Cancelled")
|
|
||||||
data.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
|
||||||
return object : EdziennikCallback {
|
|
||||||
override fun onCompleted() { callback.onCompleted() }
|
|
||||||
override fun onProgress(step: Float) { callback.onProgress(step) }
|
|
||||||
override fun onStartProgress(stringRes: Int) { callback.onStartProgress(stringRes) }
|
|
||||||
override fun onError(apiError: ApiError) {
|
|
||||||
if (apiError.errorCode in internalErrorList) {
|
|
||||||
// finish immediately if the same error occurs twice during the same sync
|
|
||||||
callback.onError(apiError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
internalErrorList.add(apiError.errorCode)
|
|
||||||
when (apiError.errorCode) {
|
|
||||||
ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION,
|
|
||||||
ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH,
|
|
||||||
ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER,
|
|
||||||
ERROR_IDZIENNIK_WEB_ACCESS_DENIED,
|
|
||||||
ERROR_IDZIENNIK_API_ACCESS_DENIED -> {
|
|
||||||
data.loginMethods.remove(LOGIN_METHOD_IDZIENNIK_WEB)
|
|
||||||
data.prepareFor(idziennikLoginMethods, LOGIN_METHOD_IDZIENNIK_WEB)
|
|
||||||
data.loginExpiryTime = 0
|
|
||||||
login()
|
|
||||||
}
|
|
||||||
ERROR_IDZIENNIK_API_NO_REGISTER -> {
|
|
||||||
data()
|
|
||||||
}
|
|
||||||
else -> callback.onError(apiError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
|
||||||
|
|
||||||
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_HOMEWORK = 1061
|
|
||||||
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_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_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_HOMEWORK, listOf(
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_HOMEWORK 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)).withPriority(2),
|
|
||||||
Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_SENT, listOf(
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_MESSAGES_SENT to LOGIN_METHOD_IDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_IDZIENNIK_WEB)).withPriority(2),*/
|
|
||||||
|
|
||||||
Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_INBOX, listOf(
|
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX to LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
), listOf(LOGIN_METHOD_IDZIENNIK_API)),
|
|
||||||
Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_MESSAGES_SENT, listOf(
|
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT to LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
), listOf(LOGIN_METHOD_IDZIENNIK_API)),
|
|
||||||
|
|
||||||
Feature(LOGIN_TYPE_IDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
|
|
||||||
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER to LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
), listOf(LOGIN_METHOD_IDZIENNIK_API))
|
|
||||||
)
|
|
@ -1,118 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-29.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import im.wangchao.mhttp.Request
|
|
||||||
import im.wangchao.mhttp.Response
|
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
|
|
||||||
open class IdziennikApi(open val data: DataIdziennik, open val lastSync: Long?) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "IdziennikApi"
|
|
||||||
}
|
|
||||||
|
|
||||||
val profileId
|
|
||||||
get() = data.profile?.id ?: -1
|
|
||||||
|
|
||||||
val profile
|
|
||||||
get() = data.profile
|
|
||||||
|
|
||||||
fun apiGet(tag: String, endpointTemplate: String, method: Int = GET, parameters: Map<String, Any> = emptyMap(), onSuccess: (json: JsonElement) -> Unit) {
|
|
||||||
val endpoint = endpointTemplate.replace("\$STUDENT_ID", data.studentId ?: "")
|
|
||||||
Utils.d(tag, "Request: Idziennik/API - $IDZIENNIK_API_URL/$endpoint")
|
|
||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
|
||||||
if (text == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val json = try {
|
|
||||||
JsonParser().parse(text)
|
|
||||||
} catch (_: Exception) { null }
|
|
||||||
|
|
||||||
var error: String? = null
|
|
||||||
if (json == null) {
|
|
||||||
error = text
|
|
||||||
}
|
|
||||||
else if (json is JsonObject) {
|
|
||||||
error = if (response?.code() == 200) null else
|
|
||||||
json.getString("message") ?: json.toString()
|
|
||||||
}
|
|
||||||
error?.let { code ->
|
|
||||||
when (code) {
|
|
||||||
"Uczeń nie posiada aktywnej pozycji w dzienniku" -> ERROR_IDZIENNIK_API_NO_REGISTER
|
|
||||||
"Authorization has been denied for this request." -> ERROR_IDZIENNIK_API_ACCESS_DENIED
|
|
||||||
else -> ERROR_IDZIENNIK_API_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(tag, errorCode)
|
|
||||||
.withApiResponse(text)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(json!!)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_IDZIENNIK_API_REQUEST)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(e)
|
|
||||||
.withApiResponse(text))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_API_URL/$endpoint")
|
|
||||||
.userAgent(IDZIENNIK_API_USER_AGENT)
|
|
||||||
.addHeader("Authorization", "Bearer ${data.apiBearer}")
|
|
||||||
.apply {
|
|
||||||
when (method) {
|
|
||||||
GET -> get()
|
|
||||||
POST -> {
|
|
||||||
postJson()
|
|
||||||
val json = JsonObject()
|
|
||||||
parameters.map { (name, value) ->
|
|
||||||
when (value) {
|
|
||||||
is JsonObject -> json.add(name, value)
|
|
||||||
is JsonArray -> json.add(name, value)
|
|
||||||
is String -> json.addProperty(name, value)
|
|
||||||
is Int -> json.addProperty(name, value)
|
|
||||||
is Long -> json.addProperty(name, value)
|
|
||||||
is Float -> json.addProperty(name, value)
|
|
||||||
is Char -> json.addProperty(name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setJsonBody(json)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_INTERNAL_ERROR)
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api.IdziennikApiCurrentRegister
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api.IdziennikApiMessagesInbox
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api.IdziennikApiMessagesSent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.*
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
|
|
||||||
class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikData"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
nextEndpoint(onSuccess)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun nextEndpoint(onSuccess: () -> Unit) {
|
|
||||||
if (data.targetEndpointIds.isEmpty()) {
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (data.cancelled) {
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val id = data.targetEndpointIds.firstKey()
|
|
||||||
val lastSync = data.targetEndpointIds.remove(id)
|
|
||||||
useEndpoint(id, lastSync) { endpointId ->
|
|
||||||
data.progress(data.progressStep)
|
|
||||||
nextEndpoint(onSuccess)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
|
||||||
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
|
||||||
when (endpointId) {
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
|
||||||
IdziennikWebTimetable(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_GRADES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
|
||||||
IdziennikWebGrades(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
|
||||||
IdziennikWebProposedGrades(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_EXAMS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
|
||||||
IdziennikWebExams(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_HOMEWORK -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
|
||||||
IdziennikWebHomework(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_NOTICES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
|
||||||
IdziennikWebNotices(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
|
||||||
IdziennikWebAnnouncements(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_WEB_ATTENDANCE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
|
||||||
IdziennikWebAttendance(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
|
||||||
IdziennikApiCurrentRegister(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
|
||||||
IdziennikApiMessagesInbox(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
|
||||||
IdziennikApiMessagesSent(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
else -> onSuccess(endpointId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,238 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import im.wangchao.mhttp.Request
|
|
||||||
import im.wangchao.mhttp.Response
|
|
||||||
import im.wangchao.mhttp.callback.FileCallbackHandler
|
|
||||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSwitchRegister
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import java.io.File
|
|
||||||
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
|
||||||
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
|
||||||
|
|
||||||
open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "IdziennikWeb"
|
|
||||||
}
|
|
||||||
|
|
||||||
val profileId
|
|
||||||
get() = data.profile?.id ?: -1
|
|
||||||
|
|
||||||
val profile
|
|
||||||
get() = data.profile
|
|
||||||
|
|
||||||
fun webApiGet(tag: String, endpoint: String, parameters: Map<String, Any> = emptyMap(), onSuccess: (json: JsonObject) -> Unit) {
|
|
||||||
d(tag, "Request: Idziennik/Web/API - $IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
|
|
||||||
val callback = object : JsonCallbackHandler() {
|
|
||||||
override fun onSuccess(json: JsonObject?, response: Response?) {
|
|
||||||
if (json == null && response?.parserErrorBody == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response?.code() == HTTP_INTERNAL_ERROR && endpoint == IDZIENNIK_WEB_GET_RECIPIENT_LIST) {
|
|
||||||
data.error(ApiError(tag, ERROR_IDZIENNIK_WEB_RECIPIENT_LIST_NO_PERMISSION)
|
|
||||||
.withResponse(response)
|
|
||||||
.withApiResponse(json))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response?.code() == HTTP_INTERNAL_ERROR && endpoint == IDZIENNIK_WEB_GRADES) {
|
|
||||||
// special override for accounts where displaying grades
|
|
||||||
// for another student requires switching it manually
|
|
||||||
if (data.registerId != data.webSelectedRegister) {
|
|
||||||
IdziennikWebSwitchRegister(data, data.registerId) {
|
|
||||||
webApiGet(tag, endpoint, parameters, onSuccess)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
when {
|
|
||||||
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
|
||||||
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
|
||||||
response?.parserErrorBody != null -> when {
|
|
||||||
response.parserErrorBody.contains("Identyfikator zgłoszenia") -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
|
||||||
response.parserErrorBody.contains("Hasło dostępu do systemu wygasło") -> ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED
|
|
||||||
response.parserErrorBody.contains("Trwają prace konserwacyjne") -> ERROR_IDZIENNIK_WEB_MAINTENANCE
|
|
||||||
else -> ERROR_IDZIENNIK_WEB_OTHER
|
|
||||||
}
|
|
||||||
else -> null
|
|
||||||
}?.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(json?.toString() ?: response?.parserErrorBody)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json == null) {
|
|
||||||
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(json)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_IDZIENNIK_WEB_API_REQUEST)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(e)
|
|
||||||
.withApiResponse(json))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
|
||||||
.postJson()
|
|
||||||
.apply {
|
|
||||||
val json = JsonObject()
|
|
||||||
parameters.map { (name, value) ->
|
|
||||||
when (value) {
|
|
||||||
is JsonObject -> json.add(name, value)
|
|
||||||
is JsonArray -> json.add(name, value)
|
|
||||||
is String -> json.addProperty(name, value)
|
|
||||||
is Int -> json.addProperty(name, value)
|
|
||||||
is Long -> json.addProperty(name, value)
|
|
||||||
is Float -> json.addProperty(name, value)
|
|
||||||
is Char -> json.addProperty(name, value)
|
|
||||||
is Boolean -> json.addProperty(name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setJsonBody(json)
|
|
||||||
}
|
|
||||||
.allowErrorCode(HTTP_UNAUTHORIZED)
|
|
||||||
.allowErrorCode(HTTP_INTERNAL_ERROR)
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) {
|
|
||||||
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
|
||||||
if (text == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!text.contains("czyWyswietlicDostepMobilny")) {
|
|
||||||
when {
|
|
||||||
text.contains("Identyfikator zgłoszenia") -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
|
||||||
text.contains("Hasło dostępu do systemu wygasło") -> ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED
|
|
||||||
text.contains("Trwają prace konserwacyjne") -> ERROR_IDZIENNIK_WEB_MAINTENANCE
|
|
||||||
else -> ERROR_IDZIENNIK_WEB_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(text)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(text)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_IDZIENNIK_WEB_REQUEST)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(e)
|
|
||||||
.withApiResponse(text))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
|
||||||
.apply {
|
|
||||||
if (parameters.isEmpty()) get()
|
|
||||||
else post()
|
|
||||||
|
|
||||||
parameters.map { (name, value) ->
|
|
||||||
addParameter(name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun webGetFile(tag: String, endpoint: String, targetFile: File, parameters: Map<String, Any>,
|
|
||||||
onSuccess: (file: File) -> Unit, onProgress: (written: Long, total: Long) -> Unit) {
|
|
||||||
|
|
||||||
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
|
|
||||||
val callback = object : FileCallbackHandler(targetFile) {
|
|
||||||
override fun onSuccess(file: File?, response: Response?) {
|
|
||||||
if (file == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_FILE_DOWNLOAD)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(file)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_EDUDZIENNIK_FILE_REQUEST)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onProgress(bytesWritten: Long, bytesTotal: Long) {
|
|
||||||
try {
|
|
||||||
onProgress(bytesWritten, bytesTotal)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_EDUDZIENNIK_FILE_REQUEST)
|
|
||||||
.withThrowable(e))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
|
||||||
.apply {
|
|
||||||
parameters.forEach { (k, v) -> addParameter(k, v) }
|
|
||||||
}
|
|
||||||
.contentType("application/x-www-form-urlencoded")
|
|
||||||
.post()
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-29.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.DAY
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_API_CURRENT_REGISTER
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.getInt
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
|
||||||
|
|
||||||
class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikApiCurrentRegister"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
apiGet(TAG, IDZIENNIK_API_CURRENT_REGISTER) { json ->
|
|
||||||
if (json !is JsonObject) {
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
var nextSync = System.currentTimeMillis() + 14*DAY*1000
|
|
||||||
|
|
||||||
val settings = json.getJsonObject("ustawienia")?.apply {
|
|
||||||
getString("poczatekSemestru1")?.let { profile?.dateSemester1Start = Date.fromY_m_d(it) }
|
|
||||||
getString("koniecSemestru1")?.let { profile?.dateSemester2Start = Date.fromY_m_d(it).stepForward(0, 0, 1) }
|
|
||||||
getString("koniecSemestru2")?.let { profile?.dateYearEnd = Date.fromY_m_d(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getInt("szczesliwyNumerek")?.let { luckyNumber ->
|
|
||||||
val luckyNumberDate = Date.getToday()
|
|
||||||
settings.getString("godzinaPublikacjiSzczesliwegoLosu")
|
|
||||||
?.let { Time.fromH_m(it) }
|
|
||||||
?.let { publishTime ->
|
|
||||||
val now = Time.getNow()
|
|
||||||
if (publishTime.value < 150000 && now.value < publishTime.value) {
|
|
||||||
nextSync = luckyNumberDate.combineWith(publishTime)
|
|
||||||
luckyNumberDate.stepForward(0, 0, -1) // the lucky number is still for yesterday
|
|
||||||
}
|
|
||||||
else if (publishTime.value >= 150000 && now.value > publishTime.value) {
|
|
||||||
luckyNumberDate.stepForward(0, 0, 1) // the lucky number is already for tomorrow
|
|
||||||
nextSync = luckyNumberDate.combineWith(publishTime)
|
|
||||||
}
|
|
||||||
else if (publishTime.value < 150000) {
|
|
||||||
nextSync = luckyNumberDate
|
|
||||||
.clone()
|
|
||||||
.stepForward(0, 0, 1)
|
|
||||||
.combineWith(publishTime)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
nextSync = luckyNumberDate.combineWith(publishTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
|
||||||
profileId = data.profileId,
|
|
||||||
date = luckyNumberDate,
|
|
||||||
number = luckyNumber
|
|
||||||
)
|
|
||||||
|
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
|
||||||
data.metadataList.add(
|
|
||||||
Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_LUCKY_NUMBER,
|
|
||||||
luckyNumberObject.date.value.toLong(),
|
|
||||||
true,
|
|
||||||
data.profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER, syncAt = nextSync)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-30.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.asJsonObjectList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_API_MESSAGES_INBOX
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
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.getBoolean
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikApiMessagesInbox"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_INBOX) { json ->
|
|
||||||
if (json !is JsonArray) {
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.asJsonObjectList().forEach { jMessage ->
|
|
||||||
val subject = jMessage.getString("tytul") ?: ""
|
|
||||||
if (subject.contains("(") && subject.startsWith("iDziennik - "))
|
|
||||||
return@forEach
|
|
||||||
if (subject.startsWith("Uwaga dla ucznia (klasa:"))
|
|
||||||
return@forEach
|
|
||||||
|
|
||||||
val messageIdStr = jMessage.getString("id")
|
|
||||||
val messageId = crc32((messageIdStr + "0").toByteArray())
|
|
||||||
|
|
||||||
var body = "[META:$messageIdStr;-1]"
|
|
||||||
body += jMessage.getString("tresc")?.replace("\n".toRegex(), "<br>")
|
|
||||||
|
|
||||||
val readDate = if (jMessage.getBoolean("odczytana") == true) Date.fromIso(jMessage.getString("wersjaRekordu")) else 0
|
|
||||||
val sentDate = Date.fromIso(jMessage.getString("dataWyslania"))
|
|
||||||
|
|
||||||
val sender = jMessage.getAsJsonObject("nadawca")
|
|
||||||
var firstName = sender.getString("imie")
|
|
||||||
var lastName = sender.getString("nazwisko")
|
|
||||||
if (firstName.isNullOrEmpty() || lastName.isNullOrEmpty()) {
|
|
||||||
firstName = "usunięty"
|
|
||||||
lastName = "użytkownik"
|
|
||||||
}
|
|
||||||
val rTeacher = data.getTeacher(
|
|
||||||
firstName,
|
|
||||||
lastName
|
|
||||||
)
|
|
||||||
rTeacher.loginId = /*sender.getString("id") + ":" + */sender.getString("usr")
|
|
||||||
rTeacher.setTeacherType(Teacher.TYPE_OTHER)
|
|
||||||
|
|
||||||
val message = Message(
|
|
||||||
profileId = profileId,
|
|
||||||
id = messageId,
|
|
||||||
type = if (jMessage.getBoolean("rekordUsuniety") == true) TYPE_DELETED else TYPE_RECEIVED,
|
|
||||||
subject = subject,
|
|
||||||
body = body,
|
|
||||||
senderId = rTeacher.id,
|
|
||||||
addedDate = sentDate
|
|
||||||
)
|
|
||||||
|
|
||||||
val messageRecipient = MessageRecipient(
|
|
||||||
profileId,
|
|
||||||
-1 /* me */,
|
|
||||||
-1,
|
|
||||||
readDate,
|
|
||||||
/*messageId*/ messageId
|
|
||||||
)
|
|
||||||
|
|
||||||
data.messageList.add(message)
|
|
||||||
data.messageRecipientList.add(messageRecipient)
|
|
||||||
data.setSeenMetadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_MESSAGE,
|
|
||||||
message.id,
|
|
||||||
readDate > 0,
|
|
||||||
readDate > 0 || profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-30.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.DAY
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.asJsonObjectList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_API_MESSAGES_SENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_SENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
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.utils.Utils.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikApiMessagesSent"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_SENT) { json ->
|
|
||||||
if (json !is JsonArray) {
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.asJsonObjectList()?.forEach { jMessage ->
|
|
||||||
val messageIdStr = jMessage.get("id").asString
|
|
||||||
val messageId = crc32((messageIdStr + "1").toByteArray())
|
|
||||||
|
|
||||||
val subject = jMessage.get("tytul").asString
|
|
||||||
|
|
||||||
var body = "[META:$messageIdStr;-1]"
|
|
||||||
body += jMessage.get("tresc").asString.replace("\n".toRegex(), "<br>")
|
|
||||||
|
|
||||||
val sentDate = Date.fromIso(jMessage.get("dataWyslania").asString)
|
|
||||||
|
|
||||||
val message = Message(
|
|
||||||
profileId = profileId,
|
|
||||||
id = messageId,
|
|
||||||
type = TYPE_SENT,
|
|
||||||
subject = subject,
|
|
||||||
body = body,
|
|
||||||
senderId = null,
|
|
||||||
addedDate = sentDate
|
|
||||||
)
|
|
||||||
|
|
||||||
for (recipientEl in jMessage.getAsJsonArray("odbiorcy")) {
|
|
||||||
val recipient = recipientEl.asJsonObject
|
|
||||||
var firstName = recipient.get("imie").asString
|
|
||||||
var lastName = recipient.get("nazwisko").asString
|
|
||||||
if (firstName.isEmpty() || lastName.isEmpty()) {
|
|
||||||
firstName = "usunięty"
|
|
||||||
lastName = "użytkownik"
|
|
||||||
}
|
|
||||||
val rTeacher = data.getTeacher(firstName, lastName)
|
|
||||||
rTeacher.loginId = /*recipient.get("id").asString + ":" + */recipient.get("usr").asString
|
|
||||||
|
|
||||||
val messageRecipient = MessageRecipient(
|
|
||||||
profileId,
|
|
||||||
rTeacher.id,
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
/*messageId*/ messageId
|
|
||||||
)
|
|
||||||
data.messageRecipientIgnoreList.add(messageRecipient)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.messageList.add(message)
|
|
||||||
data.metadataList.add(Metadata(profileId, Metadata.TYPE_MESSAGE, message.id, true, true))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getLong
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebAnnouncements"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val param = JsonObject()
|
|
||||||
param.add("parametryFiltrow", JsonArray())
|
|
||||||
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_ANNOUNCEMENTS, mapOf(
|
|
||||||
"uczenId" to (data.studentId ?: ""),
|
|
||||||
"param" to param
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
for (jAnnouncementEl in json.getAsJsonArray("ListK")) {
|
|
||||||
val jAnnouncement = jAnnouncementEl.asJsonObject
|
|
||||||
// jAnnouncement
|
|
||||||
val announcementId = jAnnouncement.getLong("Id") ?: -1
|
|
||||||
|
|
||||||
val rTeacher = data.getTeacherByFirstLast(jAnnouncement.getString("Autor") ?: "")
|
|
||||||
val addedDate = jAnnouncement.getString("DataDodania")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull() ?: System.currentTimeMillis()
|
|
||||||
val startDate = jAnnouncement.getString("DataWydarzenia")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull()?.let { Date.fromMillis(it) }
|
|
||||||
|
|
||||||
val announcementObject = Announcement(
|
|
||||||
profileId = profileId,
|
|
||||||
id = announcementId,
|
|
||||||
subject = jAnnouncement.get("Temat").asString,
|
|
||||||
text = jAnnouncement.get("Tresc").asString,
|
|
||||||
startDate = startDate,
|
|
||||||
endDate = null,
|
|
||||||
teacherId = rTeacher.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
data.announcementList.add(announcementObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_ANNOUNCEMENT,
|
|
||||||
announcementObject.id,
|
|
||||||
profile?.empty ?: false,
|
|
||||||
profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_ABSENT_EXCUSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_BELATED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT_CUSTOM
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_RELEASED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_UNKNOWN
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getInt
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
|
||||||
|
|
||||||
class IdziennikWebAttendance(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebAttendance"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var attendanceYear = Date.getToday().year
|
|
||||||
private var attendanceMonth = Date.getToday().month
|
|
||||||
private var attendancePrevMonthChecked = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
getAttendance()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAttendance() {
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_ATTENDANCE, mapOf(
|
|
||||||
"idPozDziennika" to data.registerId,
|
|
||||||
"mc" to attendanceMonth,
|
|
||||||
"rok" to attendanceYear,
|
|
||||||
"dataTygodnia" to ""
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
for (jAttendanceEl in json.getAsJsonArray("Obecnosci")) {
|
|
||||||
val jAttendance = jAttendanceEl.asJsonObject
|
|
||||||
// jAttendance
|
|
||||||
val type = jAttendance.get("TypObecnosci").asInt
|
|
||||||
|
|
||||||
// skip "zajęcia nie odbyły się" and "Ferie"
|
|
||||||
if (type == 5 || type == 7)
|
|
||||||
continue
|
|
||||||
|
|
||||||
val date = Date.fromY_m_d(jAttendance.get("Data").asString)
|
|
||||||
val time = Time.fromH_m(jAttendance.get("OdDoGodziny").asString)
|
|
||||||
if (date.combineWith(time) > System.currentTimeMillis())
|
|
||||||
continue
|
|
||||||
|
|
||||||
val id = jAttendance.get("IdLesson").asString.crc16().toLong()
|
|
||||||
val rSubject = data.getSubject(jAttendance.get("Przedmiot").asString, jAttendance.get("IdPrzedmiot").asLong, "")
|
|
||||||
val rTeacher = data.getTeacherByFDotSpaceLast(jAttendance.get("PrzedmiotNauczyciel").asString)
|
|
||||||
|
|
||||||
var baseType = TYPE_UNKNOWN
|
|
||||||
var typeName = "nieznany rodzaj"
|
|
||||||
var typeSymbol: String? = null
|
|
||||||
var typeColor: Long? = null
|
|
||||||
|
|
||||||
/* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosciUcznia_lmt637231494660000000.js */
|
|
||||||
/* https://iuczniowie.progman.pl/idziennik/mod_panelRodzica/obecnosci/obecnosci_lmt637231494660000000.css */
|
|
||||||
when (type) {
|
|
||||||
1 -> {
|
|
||||||
baseType = TYPE_ABSENT_EXCUSED
|
|
||||||
typeName = "nieobecność usprawiedliwiona"
|
|
||||||
typeColor = 0xffffe099
|
|
||||||
}
|
|
||||||
2 -> {
|
|
||||||
baseType = TYPE_BELATED
|
|
||||||
typeName = "spóźnienie"
|
|
||||||
typeColor = 0xffffffaa
|
|
||||||
}
|
|
||||||
3 -> {
|
|
||||||
baseType = TYPE_ABSENT
|
|
||||||
typeName = "nieobecność nieusprawiedliwiona"
|
|
||||||
typeColor = 0xffffad99
|
|
||||||
}
|
|
||||||
4, 9 -> {
|
|
||||||
baseType = TYPE_RELEASED
|
|
||||||
if (type == 4) {
|
|
||||||
typeName = "zwolnienie"
|
|
||||||
typeColor = 0xffa8beff
|
|
||||||
}
|
|
||||||
if (type == 9) {
|
|
||||||
typeName = "zwolniony / obecny"
|
|
||||||
typeSymbol = "zb"
|
|
||||||
typeColor = 0xffff69b4
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8 -> {
|
|
||||||
baseType = TYPE_PRESENT_CUSTOM
|
|
||||||
typeName = "wycieczka"
|
|
||||||
typeSymbol = "w"
|
|
||||||
typeColor = null
|
|
||||||
}
|
|
||||||
0 -> {
|
|
||||||
baseType = TYPE_PRESENT
|
|
||||||
typeName = "obecny"
|
|
||||||
typeColor = 0xffccffcc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val semester = profile?.dateToSemester(date) ?: 1
|
|
||||||
|
|
||||||
val attendanceObject = Attendance(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
baseType = baseType,
|
|
||||||
typeName = typeName,
|
|
||||||
typeShort = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
|
|
||||||
typeSymbol = typeSymbol ?: data.app.attendanceManager.getTypeShort(baseType),
|
|
||||||
typeColor = typeColor?.toInt(),
|
|
||||||
date = date,
|
|
||||||
startTime = time,
|
|
||||||
semester = semester,
|
|
||||||
teacherId = rTeacher.id,
|
|
||||||
subjectId = rSubject.id
|
|
||||||
).also {
|
|
||||||
it.lessonTopic = jAttendance.getString("PrzedmiotTemat")
|
|
||||||
it.lessonNumber = jAttendance.getInt("Godzina")
|
|
||||||
}
|
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
|
||||||
if (attendanceObject.baseType != TYPE_PRESENT) {
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_ATTENDANCE,
|
|
||||||
attendanceObject.id,
|
|
||||||
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN,
|
|
||||||
profile?.empty ?: false || baseType == TYPE_PRESENT_CUSTOM || baseType == TYPE_UNKNOWN
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val attendanceDateValue = attendanceYear * 10000 + attendanceMonth * 100
|
|
||||||
if (profile?.empty == true && attendanceDateValue > profile?.getSemesterStart(1)?.value ?: 99999999) {
|
|
||||||
attendancePrevMonthChecked = true // do not need to check prev month later
|
|
||||||
attendanceMonth--
|
|
||||||
if (attendanceMonth < 1) {
|
|
||||||
attendanceMonth = 12
|
|
||||||
attendanceYear--
|
|
||||||
}
|
|
||||||
getAttendance()
|
|
||||||
} else if (!attendancePrevMonthChecked /* get also the previous month */) {
|
|
||||||
attendanceMonth--
|
|
||||||
if (attendanceMonth < 1) {
|
|
||||||
attendanceMonth = 12
|
|
||||||
attendanceYear--
|
|
||||||
}
|
|
||||||
attendancePrevMonthChecked = true
|
|
||||||
getAttendance()
|
|
||||||
} else {
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_EXAMS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_EXAMS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class IdziennikWebExams(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebExams"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var examsYear = Date.getToday().year
|
|
||||||
private var examsMonth = Date.getToday().month
|
|
||||||
private var examsMonthsChecked = 0
|
|
||||||
private var examsNextMonthChecked = false // TO DO temporary // no more // idk
|
|
||||||
|
|
||||||
init {
|
|
||||||
getExams()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getExams() {
|
|
||||||
val param = JsonObject().apply {
|
|
||||||
addProperty("strona", 1)
|
|
||||||
addProperty("iloscNaStrone", "99")
|
|
||||||
addProperty("iloscRekordow", -1)
|
|
||||||
addProperty("kolumnaSort", "ss.Nazwa,sp.Data_sprawdzianu")
|
|
||||||
addProperty("kierunekSort", 0)
|
|
||||||
addProperty("maxIloscZaznaczonych", 0)
|
|
||||||
addProperty("panelFiltrow", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_EXAMS, mapOf(
|
|
||||||
"idP" to data.registerId,
|
|
||||||
"rok" to examsYear,
|
|
||||||
"miesiac" to examsMonth,
|
|
||||||
"param" to param
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { exam ->
|
|
||||||
val id = exam.getLong("_recordId") ?: return@forEach
|
|
||||||
val examDate = Date.fromY_m_d(exam.getString("data") ?: return@forEach)
|
|
||||||
val subjectName = exam.getString("przedmiot") ?: return@forEach
|
|
||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
|
||||||
val teacherName = exam.getString("wpisal") ?: return@forEach
|
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
|
||||||
val topic = exam.getString("zakres")?.trim() ?: ""
|
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, examDate)
|
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
|
||||||
|
|
||||||
val eventType = when (exam.getString("rodzaj")?.toLowerCase(Locale.getDefault())) {
|
|
||||||
"sprawdzian/praca klasowa",
|
|
||||||
"sprawdzian",
|
|
||||||
"praca klasowa" -> Event.TYPE_EXAM
|
|
||||||
"kartkówka" -> Event.TYPE_SHORT_QUIZ
|
|
||||||
else -> Event.TYPE_EXAM
|
|
||||||
}
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = examDate,
|
|
||||||
time = startTime,
|
|
||||||
topic = topic,
|
|
||||||
color = null,
|
|
||||||
type = eventType,
|
|
||||||
teacherId = teacherId,
|
|
||||||
subjectId = subjectId,
|
|
||||||
teamId = data.teamClass?.id ?: -1
|
|
||||||
)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_EVENT,
|
|
||||||
eventObject.id,
|
|
||||||
profile?.empty ?: false,
|
|
||||||
profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile?.empty == true && examsMonthsChecked < 3 /* how many months backwards to check? */) {
|
|
||||||
examsMonthsChecked++
|
|
||||||
examsMonth--
|
|
||||||
if (examsMonth < 1) {
|
|
||||||
examsMonth = 12
|
|
||||||
examsYear--
|
|
||||||
}
|
|
||||||
getExams()
|
|
||||||
} else if (!examsNextMonthChecked /* get also one month forward */) {
|
|
||||||
val showDate = Date.getToday().stepForward(0, 1, 0)
|
|
||||||
examsYear = showDate.year
|
|
||||||
examsMonth = showDate.month
|
|
||||||
examsNextMonthChecked = true
|
|
||||||
getExams()
|
|
||||||
} else {
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_EXAMS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-28
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_ATTACHMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
|
||||||
val owner: Any,
|
|
||||||
val attachmentId: Long,
|
|
||||||
val attachmentName: String,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "IdziennikWebGetAttachment"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val message = owner as Message
|
|
||||||
|
|
||||||
val messageId = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex().find(message.body ?: "")?.get(2) ?: -1
|
|
||||||
val targetFile = File(Utils.getStorageDir(), attachmentName)
|
|
||||||
|
|
||||||
webGetFile(TAG, IDZIENNIK_WEB_GET_ATTACHMENT, targetFile, mapOf(
|
|
||||||
"id" to messageId,
|
|
||||||
"fileName" to attachmentName
|
|
||||||
), { file ->
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
owner,
|
|
||||||
attachmentId,
|
|
||||||
AttachmentGetEvent.TYPE_FINISHED,
|
|
||||||
file.absolutePath
|
|
||||||
)
|
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
|
|
||||||
}) { written, _ ->
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
owner,
|
|
||||||
attachmentId,
|
|
||||||
AttachmentGetEvent.TYPE_PROGRESS,
|
|
||||||
bytesWritten = written
|
|
||||||
)
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
|
||||||
import pl.szczodrzynski.edziennik.getBoolean
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
|
|
||||||
class IdziennikWebGetHomework(override val data: DataIdziennik,
|
|
||||||
val event: EventFull,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebGetHomework"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK, mapOf(
|
|
||||||
"idP" to data.registerId,
|
|
||||||
"idPD" to event.id
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
val homework = json.getJsonObject("praca") ?: return@webApiGet
|
|
||||||
|
|
||||||
if (homework.getBoolean("zalacznik", false)) {
|
|
||||||
event.attachmentIds = mutableListOf(event.id)
|
|
||||||
event.attachmentNames = mutableListOf("Załącznik do zadania")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
event.attachmentIds = mutableListOf()
|
|
||||||
event.attachmentNames = mutableListOf()
|
|
||||||
}
|
|
||||||
event.homeworkBody = homework.getString("tresc")
|
|
||||||
|
|
||||||
data.eventList.add(event)
|
|
||||||
data.eventListReplace = true
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(EventGetEvent(event))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.set
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
class IdziennikWebGetHomeworkAttachment(override val data: DataIdziennik,
|
|
||||||
val owner: Any,
|
|
||||||
val attachmentId: Long,
|
|
||||||
val attachmentName: String,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "IdziennikWebGetHomeworkAttachment"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val homework = owner as Event
|
|
||||||
|
|
||||||
/*val request = Request.Builder()
|
|
||||||
.url("")
|
|
||||||
.build()
|
|
||||||
data.app.http.newCall(request).enqueue(object : Callback {
|
|
||||||
override fun onFailure(call: Call, e: IOException) {
|
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
|
||||||
.withThrowable(e))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResponse(call: Call, response: Response) {
|
|
||||||
val filename = response.header("content-disposition")?.substringAfter("\"")?.substringBeforeLast("\"")
|
|
||||||
|
|
||||||
val file: File = File(Utils.getStorageDir(), filename)
|
|
||||||
val sink = file.sink().buffer()
|
|
||||||
response.body()?.source()?.let {
|
|
||||||
sink.writeAll(it)
|
|
||||||
}
|
|
||||||
sink.close()
|
|
||||||
}
|
|
||||||
})*/
|
|
||||||
|
|
||||||
webGet(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT) { text ->
|
|
||||||
val hiddenFields = JsonObject()
|
|
||||||
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
|
||||||
hiddenFields[it[1]] = it[2]
|
|
||||||
}
|
|
||||||
|
|
||||||
webGetFile(TAG, IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT, Utils.getStorageDir(), mapOf(
|
|
||||||
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
|
||||||
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
|
||||||
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
|
||||||
"__EVENTTARGET" to "ctl00\$cphContent\$bt_pobraniePliku",
|
|
||||||
"ctl00\$dxComboUczniowie" to data.registerId,
|
|
||||||
"ctl00\$cphContent\$idPracyDomowej" to attachmentId
|
|
||||||
), { file ->
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
owner,
|
|
||||||
attachmentId,
|
|
||||||
AttachmentGetEvent.TYPE_FINISHED,
|
|
||||||
file.absolutePath
|
|
||||||
)
|
|
||||||
|
|
||||||
val attachmentDataFile = File(Utils.getStorageDir(), ".${profileId}_${event.ownerId}_${event.attachmentId}")
|
|
||||||
Utils.writeStringToFile(attachmentDataFile, event.fileName)
|
|
||||||
|
|
||||||
homework.attachmentNames = mutableListOf(file.name)
|
|
||||||
data.eventList.add(homework)
|
|
||||||
data.eventListReplace = true
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
onSuccess()
|
|
||||||
|
|
||||||
}) { written, _ ->
|
|
||||||
val event = AttachmentGetEvent(
|
|
||||||
profileId,
|
|
||||||
owner,
|
|
||||||
attachmentId,
|
|
||||||
AttachmentGetEvent.TYPE_PROGRESS,
|
|
||||||
bytesWritten = written
|
|
||||||
)
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-28
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
|
||||||
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.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikWebGetMessage(override val data: DataIdziennik,
|
|
||||||
private val message: MessageFull,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "IdziennikWebGetMessage"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
val metaPattern = "\\[META:([A-z0-9]+);([0-9-]+)]".toRegex()
|
|
||||||
val meta = metaPattern.find(message.body!!)
|
|
||||||
val messageIdString = meta?.get(1) ?: ""
|
|
||||||
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_GET_MESSAGE, parameters = mapOf(
|
|
||||||
"idWiadomosci" to messageIdString,
|
|
||||||
"typWiadomosci" to if (message.type == TYPE_SENT) 1 else 0
|
|
||||||
)) { json ->
|
|
||||||
json.getJsonObject("d")?.getJsonObject("Wiadomosc")?.also {
|
|
||||||
val id = it.getLong("_recordId")
|
|
||||||
message.body = message.body?.replace(metaPattern, "[META:$messageIdString;$id]")
|
|
||||||
|
|
||||||
message.clearAttachments()
|
|
||||||
it.getJsonArray("ListaZal")?.asJsonObjectList()?.forEach { attachment ->
|
|
||||||
message.addAttachment(
|
|
||||||
attachment.getLong("Id") ?: return@forEach,
|
|
||||||
attachment.getString("Nazwa") ?: return@forEach,
|
|
||||||
-1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
message.recipients?.clear()
|
|
||||||
when (message.type) {
|
|
||||||
TYPE_RECEIVED -> {
|
|
||||||
val recipientObject = MessageRecipientFull(
|
|
||||||
profileId = profileId,
|
|
||||||
id = -1,
|
|
||||||
messageId = message.id
|
|
||||||
)
|
|
||||||
|
|
||||||
val readDateString = it.getString("DataOdczytania")
|
|
||||||
recipientObject.readDate = if (readDateString.isNullOrBlank()) System.currentTimeMillis()
|
|
||||||
else Date.fromIso(readDateString)
|
|
||||||
|
|
||||||
recipientObject.fullName = profile.accountName ?: profile.studentNameLong
|
|
||||||
|
|
||||||
data.messageRecipientList.add(recipientObject)
|
|
||||||
message.addRecipient(recipientObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
TYPE_SENT -> {
|
|
||||||
it.getJsonArray("ListaOdbiorcow")?.asJsonObjectList()?.forEach { recipient ->
|
|
||||||
val recipientName = recipient.getString("NazwaOdbiorcy") ?: return@forEach
|
|
||||||
val teacher = data.getTeacherByLastFirst(recipientName)
|
|
||||||
|
|
||||||
val recipientObject = MessageRecipientFull(
|
|
||||||
profileId = profileId,
|
|
||||||
id = teacher.id,
|
|
||||||
messageId = message.id
|
|
||||||
)
|
|
||||||
|
|
||||||
recipientObject.readDate = recipient.getLong("Status") ?: return@forEach
|
|
||||||
recipientObject.fullName = teacher.fullName
|
|
||||||
|
|
||||||
data.messageRecipientList.add(recipientObject)
|
|
||||||
message.addRecipient(recipientObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!message.seen) {
|
|
||||||
message.seen = true
|
|
||||||
|
|
||||||
data.setSeenMetadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_MESSAGE,
|
|
||||||
message.id,
|
|
||||||
message.seen,
|
|
||||||
message.notified
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.messageList.add(message)
|
|
||||||
data.messageListReplace = true
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ?: onSuccess() }
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-12-30.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import androidx.room.OnConflictStrategy
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GET_RECIPIENT_LIST
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.RecipientListGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
|
|
||||||
class IdziennikWebGetRecipientList(override val data: DataIdziennik,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebGetRecipientList"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_GET_RECIPIENT_LIST, mapOf(
|
|
||||||
"idP" to data.registerId
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getJsonArray("ListK_Pracownicy")?.asJsonObjectList()?.forEach { recipient ->
|
|
||||||
val name = recipient.getString("ImieNazwisko") ?: ": "
|
|
||||||
val (fullName, subject) = name.split(": ").let {
|
|
||||||
Pair(it.getOrNull(0), it.getOrNull(1))
|
|
||||||
}
|
|
||||||
val guid = recipient.getString("Id") ?: ""
|
|
||||||
// get teacher by ID or create it
|
|
||||||
val teacher = data.getTeacherByFirstLast(fullName ?: " ")
|
|
||||||
teacher.loginId = guid
|
|
||||||
teacher.setTeacherType(Teacher.TYPE_TEACHER)
|
|
||||||
// unset OTHER that is automatically set in IdziennikApiMessages*
|
|
||||||
teacher.unsetTeacherType(Teacher.TYPE_OTHER)
|
|
||||||
teacher.typeDescription = subject
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getJsonArray("ListK_Opiekunowie")?.asJsonObjectList()?.forEach { recipient ->
|
|
||||||
val name = recipient.getString("ImieNazwisko") ?: ": "
|
|
||||||
val (fullName, parentOf) = Regexes.IDZIENNIK_MESSAGES_RECIPIENT_PARENT.find(name)?.let {
|
|
||||||
Pair(it.groupValues.getOrNull(1), it.groupValues.getOrNull(2))
|
|
||||||
} ?: Pair(null, null)
|
|
||||||
val guid = recipient.getString("Id") ?: ""
|
|
||||||
// get teacher by ID or create it
|
|
||||||
val teacher = data.getTeacherByFirstLast(fullName ?: " ")
|
|
||||||
teacher.loginId = guid
|
|
||||||
teacher.setTeacherType(Teacher.TYPE_PARENT)
|
|
||||||
// unset OTHER that is automatically set in IdziennikApiMessages*
|
|
||||||
teacher.unsetTeacherType(Teacher.TYPE_OTHER)
|
|
||||||
teacher.typeDescription = parentOf
|
|
||||||
}
|
|
||||||
|
|
||||||
val event = RecipientListGetEvent(
|
|
||||||
data.profileId,
|
|
||||||
data.teacherList.filter { it.loginId != null }
|
|
||||||
)
|
|
||||||
|
|
||||||
profile?.lastReceiversSync = System.currentTimeMillis()
|
|
||||||
|
|
||||||
data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikWebGrades(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebGrades"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_GRADES, mapOf(
|
|
||||||
"idPozDziennika" to data.registerId
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.onEach { subjectJson ->
|
|
||||||
val subject = data.getSubject(
|
|
||||||
subjectJson.getString("Przedmiot") ?: return@onEach,
|
|
||||||
subjectJson.getLong("IdPrzedmiotu") ?: return@onEach,
|
|
||||||
subjectJson.getString("Przedmiot") ?: return@onEach
|
|
||||||
)
|
|
||||||
subjectJson.getJsonArray("Oceny")?.asJsonObjectList()?.forEach { grade ->
|
|
||||||
val id = grade.getLong("idK") ?: return@forEach
|
|
||||||
val category = grade.getString("Kategoria") ?: ""
|
|
||||||
val name = grade.getString("Ocena") ?: "?"
|
|
||||||
val semester = grade.getInt("Semestr") ?: 1
|
|
||||||
val teacher = data.getTeacherByLastFirst(grade.getString("Wystawil") ?: return@forEach)
|
|
||||||
|
|
||||||
val countToAverage = grade.getBoolean("DoSredniej") ?: true
|
|
||||||
var value = grade.getFloat("WartoscDoSred") ?: 0.0f
|
|
||||||
val weight = if (countToAverage)
|
|
||||||
grade.getFloat("Waga") ?: 0.0f
|
|
||||||
else
|
|
||||||
0.0f
|
|
||||||
|
|
||||||
val gradeColor = grade.getString("Kolor") ?: ""
|
|
||||||
var colorInt = 0xff2196f3.toInt()
|
|
||||||
if (gradeColor.isNotEmpty()) {
|
|
||||||
colorInt = Color.parseColor("#$gradeColor")
|
|
||||||
}
|
|
||||||
|
|
||||||
val addedDate = grade.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
name = name,
|
|
||||||
type = TYPE_NORMAL,
|
|
||||||
value = value,
|
|
||||||
weight = weight,
|
|
||||||
color = colorInt,
|
|
||||||
category = category,
|
|
||||||
description = null,
|
|
||||||
comment = null,
|
|
||||||
semester = semester,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
subjectId = subject.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
when (grade.getInt("Typ")) {
|
|
||||||
0 -> {
|
|
||||||
val history = grade.getJsonArray("Historia")?.asJsonObjectList()
|
|
||||||
if (history?.isNotEmpty() == true) {
|
|
||||||
var sum = gradeObject.value * gradeObject.weight
|
|
||||||
var count = gradeObject.weight
|
|
||||||
for (historyItem in history) {
|
|
||||||
val countToTheAverage = historyItem.getBoolean("DoSredniej") ?: false
|
|
||||||
value = historyItem.get("WartoscDoSred").asFloat
|
|
||||||
val weight = historyItem.get("Waga").asFloat
|
|
||||||
|
|
||||||
if (value > 0 && countToTheAverage) {
|
|
||||||
sum += value * weight
|
|
||||||
count += weight
|
|
||||||
}
|
|
||||||
|
|
||||||
val historyColor = historyItem.getString("Kolor") ?: ""
|
|
||||||
colorInt = 0xff2196f3.toInt()
|
|
||||||
if (historyColor.isNotEmpty()) {
|
|
||||||
colorInt = Color.parseColor("#$historyColor")
|
|
||||||
}
|
|
||||||
|
|
||||||
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
|
||||||
|
|
||||||
val historyObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = gradeObject.id * -1,
|
|
||||||
name = historyItem.getString("Ocena") ?: "",
|
|
||||||
type = TYPE_NORMAL,
|
|
||||||
value = value,
|
|
||||||
weight = if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
|
||||||
color = colorInt,
|
|
||||||
category = historyItem.getString("Kategoria"),
|
|
||||||
description = historyItem.getString("Uzasadnienie"),
|
|
||||||
comment = null,
|
|
||||||
semester = historyItem.getInt("Semestr") ?: 1,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
subjectId = subject.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
historyObject.parentId = gradeObject.id
|
|
||||||
|
|
||||||
data.gradeList.add(historyObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
historyObject.id,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
// update the current grade's value with an average of all historical grades and itself
|
|
||||||
if (sum > 0 && count > 0) {
|
|
||||||
gradeObject.value = sum / count
|
|
||||||
}
|
|
||||||
gradeObject.isImprovement = true // gradeObject is the improved grade. Originals are historyObjects
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1 -> {
|
|
||||||
gradeObject.type = Grade.TYPE_SEMESTER1_FINAL
|
|
||||||
gradeObject.name = value.toInt().toString()
|
|
||||||
gradeObject.weight = 0f
|
|
||||||
}
|
|
||||||
2 -> {
|
|
||||||
gradeObject.type = Grade.TYPE_YEAR_FINAL
|
|
||||||
gradeObject.name = value.toInt().toString()
|
|
||||||
gradeObject.weight = 0f
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(
|
|
||||||
Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
id,
|
|
||||||
data.profile.empty,
|
|
||||||
data.profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.addAll(listOf(
|
|
||||||
Grade.TYPE_NORMAL,
|
|
||||||
Grade.TYPE_SEMESTER1_FINAL,
|
|
||||||
Grade.TYPE_YEAR_FINAL
|
|
||||||
).map {
|
|
||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
|
||||||
})
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES) }
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikWebHomework(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebHomework"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val param = JsonObject().apply {
|
|
||||||
addProperty("strona", 1)
|
|
||||||
addProperty("iloscNaStrone", 997)
|
|
||||||
addProperty("iloscRekordow", -1)
|
|
||||||
addProperty("kolumnaSort", "DataZadania")
|
|
||||||
addProperty("kierunekSort", 0)
|
|
||||||
addProperty("maxIloscZaznaczonych", 0)
|
|
||||||
addProperty("panelFiltrow", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_HOMEWORK, mapOf(
|
|
||||||
"idP" to data.registerId,
|
|
||||||
"data" to Date.getToday().stringY_m_d,
|
|
||||||
"wszystkie" to true,
|
|
||||||
"param" to param
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
json.getJsonArray("ListK")?.asJsonObjectList()?.forEach { homework ->
|
|
||||||
val id = homework.getLong("_recordId") ?: return@forEach
|
|
||||||
val eventDate = Date.fromY_m_d(homework.getString("dataO") ?: return@forEach)
|
|
||||||
val addedDate = Date.fromY_m_d(homework.getString("dataZ") ?: return@forEach)
|
|
||||||
val subjectName = homework.getString("przed") ?: return@forEach
|
|
||||||
val subjectId = data.getSubject(subjectName, null, subjectName).id
|
|
||||||
val teacherName = homework.getString("usr") ?: return@forEach
|
|
||||||
val teacherId = data.getTeacherByLastFirst(teacherName).id
|
|
||||||
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.displayStartTime
|
|
||||||
val topic = homework.getString("tytul")?.trim() ?: ""
|
|
||||||
|
|
||||||
val seen = when (profile?.empty) {
|
|
||||||
true -> true
|
|
||||||
else -> eventDate < Date.getToday()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = eventDate,
|
|
||||||
time = startTime,
|
|
||||||
topic = topic,
|
|
||||||
color = null,
|
|
||||||
type = Event.TYPE_HOMEWORK,
|
|
||||||
teacherId = teacherId,
|
|
||||||
subjectId = subjectId,
|
|
||||||
teamId = data.teamClass?.id ?: -1,
|
|
||||||
addedDate = addedDate.inMillis
|
|
||||||
)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_HOMEWORK,
|
|
||||||
eventObject.id,
|
|
||||||
seen,
|
|
||||||
seen
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_HOMEWORK)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_NOTICES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_NOTICES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEGATIVE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_NEUTRAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice.Companion.TYPE_POSITIVE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikWebNotices(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebNotices"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_NOTICES, mapOf(
|
|
||||||
"idPozDziennika" to data.registerId
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
for (jNoticeEl in json.getAsJsonArray("SUwaga")) {
|
|
||||||
val jNotice = jNoticeEl.asJsonObject
|
|
||||||
// jNotice
|
|
||||||
val noticeId = jNotice.get("id").asString.crc16().toLong()
|
|
||||||
|
|
||||||
val rTeacher = data.getTeacherByLastFirst(jNotice.get("Nauczyciel").asString)
|
|
||||||
val addedDate = Date.fromY_m_d(jNotice.get("Data").asString)
|
|
||||||
|
|
||||||
var nType = TYPE_NEUTRAL
|
|
||||||
val jType = jNotice.get("Typ").asString
|
|
||||||
if (jType == "n") {
|
|
||||||
nType = TYPE_NEGATIVE
|
|
||||||
} else if (jType == "p") {
|
|
||||||
nType = TYPE_POSITIVE
|
|
||||||
}
|
|
||||||
|
|
||||||
val noticeObject = Notice(
|
|
||||||
profileId = profileId,
|
|
||||||
id = noticeId,
|
|
||||||
type = nType,
|
|
||||||
semester = jNotice.get("Semestr").asInt,
|
|
||||||
text = jNotice.getString("Tresc") ?: "",
|
|
||||||
category = null,
|
|
||||||
points = null,
|
|
||||||
teacherId = rTeacher.id,
|
|
||||||
addedDate = addedDate.inMillis
|
|
||||||
)
|
|
||||||
|
|
||||||
data.noticeList.add(noticeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_NOTICE,
|
|
||||||
noticeObject.id,
|
|
||||||
profile?.empty ?: false,
|
|
||||||
profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_NOTICES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_NOTICES)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-28.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.asJsonObjectList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_MISSING_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
|
|
||||||
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebProposedGrades"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_MISSING_GRADES, mapOf(
|
|
||||||
"idPozDziennika" to data.registerId
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
val manager = data.app.gradesManager
|
|
||||||
|
|
||||||
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { subject ->
|
|
||||||
val subjectName = subject.getString("Przedmiot") ?: return@forEach
|
|
||||||
val subjectObject = data.getSubject(subjectName, null, subjectName)
|
|
||||||
|
|
||||||
val semester1Proposed = subject.getString("OcenaSem1") ?: ""
|
|
||||||
val semester1Value = manager.getGradeValue(semester1Proposed)
|
|
||||||
val semester1Id = subjectObject.id * (-100) - 1
|
|
||||||
val semester1Type =
|
|
||||||
if (semester1Value == 0f) TYPE_DESCRIPTIVE
|
|
||||||
else TYPE_SEMESTER1_PROPOSED
|
|
||||||
val semester1Name = when {
|
|
||||||
semester1Value == 0f -> " "
|
|
||||||
semester1Value % 1.0f == 0f -> semester1Value.toInt().toString()
|
|
||||||
else -> semester1Value.toString()
|
|
||||||
}
|
|
||||||
val semester1Color =
|
|
||||||
if (semester1Value == 0f) 0xff536dfe.toInt()
|
|
||||||
else -1
|
|
||||||
|
|
||||||
val semester2Proposed = subject.getString("OcenaSem2") ?: ""
|
|
||||||
val semester2Value = manager.getGradeValue(semester2Proposed)
|
|
||||||
val semester2Id = subjectObject.id * (-100) - 2
|
|
||||||
val semester2Type =
|
|
||||||
if (semester2Value == 0f) TYPE_DESCRIPTIVE
|
|
||||||
else TYPE_YEAR_PROPOSED
|
|
||||||
val semester2Name = when {
|
|
||||||
semester2Value == 0f -> " "
|
|
||||||
semester2Value % 1.0f == 0f -> semester2Value.toInt().toString()
|
|
||||||
else -> semester2Value.toString()
|
|
||||||
}
|
|
||||||
val semester2Color =
|
|
||||||
if (semester2Value == 0f) 0xffff4081.toInt()
|
|
||||||
else -1
|
|
||||||
|
|
||||||
if (semester1Proposed != "") {
|
|
||||||
val addedDate = if (data.profile.empty)
|
|
||||||
data.profile.dateSemester1Start.inMillis
|
|
||||||
else
|
|
||||||
System.currentTimeMillis()
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = semester1Id,
|
|
||||||
name = semester1Name,
|
|
||||||
type = semester1Type,
|
|
||||||
value = semester1Value,
|
|
||||||
weight = 0f,
|
|
||||||
color = semester1Color,
|
|
||||||
category = if (semester1Value == 0f) "Ocena opisowa semestralna" else null,
|
|
||||||
description = if (semester1Value == 0f) semester1Proposed else null,
|
|
||||||
comment = null,
|
|
||||||
semester = 1,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subjectObject.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
gradeObject.id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semester2Proposed != "") {
|
|
||||||
val addedDate = if (data.profile.empty)
|
|
||||||
data.profile.dateSemester2Start.inMillis
|
|
||||||
else
|
|
||||||
System.currentTimeMillis()
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = semester2Id,
|
|
||||||
name = semester2Name,
|
|
||||||
type = semester2Type,
|
|
||||||
value = semester2Value,
|
|
||||||
weight = 0f,
|
|
||||||
color = semester2Color,
|
|
||||||
category = if (semester2Value == 0f) "Ocena opisowa końcoworoczna" else null,
|
|
||||||
description = if (semester2Value == 0f) semester2Proposed else null,
|
|
||||||
comment = null,
|
|
||||||
semester = 2,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subjectObject.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
gradeObject.id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.addAll(listOf(TYPE_SEMESTER1_PROPOSED, TYPE_YEAR_PROPOSED).map {
|
|
||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
|
||||||
})
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES) }
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-12-30.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_SEND_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.api.IdziennikApiMessagesSent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class IdziennikWebSendMessage(override val data: DataIdziennik,
|
|
||||||
val recipients: List<Teacher>,
|
|
||||||
val subject: String,
|
|
||||||
val text: String,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebSendMessage"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val recipientsArray = JsonArray()
|
|
||||||
for (teacher in recipients) {
|
|
||||||
teacher.loginId?.let {
|
|
||||||
recipientsArray += it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
webApiGet(TAG, IDZIENNIK_WEB_SEND_MESSAGE, mapOf(
|
|
||||||
"Wiadomosc" to JsonObject(
|
|
||||||
"Tytul" to subject,
|
|
||||||
"Tresc" to text,
|
|
||||||
"Confirmation" to false,
|
|
||||||
"GuidMessage" to UUID.randomUUID().toString().toUpperCase(Locale.ROOT),
|
|
||||||
"Odbiorcy" to recipientsArray
|
|
||||||
)
|
|
||||||
)) { result ->
|
|
||||||
val json = result.getJsonObject("d") ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
|
|
||||||
.withApiResponse(result))
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json.getBoolean("CzyJestBlad") != false) {
|
|
||||||
// TODO error
|
|
||||||
return@webApiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
IdziennikApiMessagesSent(data, null) {
|
|
||||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
|
||||||
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_HOME
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
|
|
||||||
class IdziennikWebSwitchRegister(override val data: DataIdziennik,
|
|
||||||
val registerId: Int,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : IdziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebSwitchRegister"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val hiddenFields = data.loginStore.getLoginData("hiddenFields", JsonObject())
|
|
||||||
// TODO error checking
|
|
||||||
|
|
||||||
webGet(TAG, IDZIENNIK_WEB_HOME, mapOf(
|
|
||||||
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
|
||||||
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
|
||||||
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
|
||||||
"ctl00\$dxComboUczniowie" to registerId
|
|
||||||
)) { text ->
|
|
||||||
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
|
||||||
val registerId = it[1].toIntOrNull() ?: return@let
|
|
||||||
data.webSelectedRegister = registerId
|
|
||||||
}
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,194 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
|
||||||
|
|
||||||
import androidx.core.util.set
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
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,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : IdziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikWebTimetable"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
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 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"
|
|
||||||
)) { 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()?.forEachIndexed { index, range ->
|
|
||||||
val lessonRange = LessonRange(
|
|
||||||
profileId,
|
|
||||||
index + 1,
|
|
||||||
range.getString("Poczatek")?.let { Time.fromH_m(it) }
|
|
||||||
?: return@forEachIndexed,
|
|
||||||
range.getString("Koniec")?.let { Time.fromH_m(it) } ?: return@forEachIndexed
|
|
||||||
)
|
|
||||||
data.lessonRanges[lessonRange.lessonNumber] = lessonRange
|
|
||||||
}
|
|
||||||
|
|
||||||
val dates = mutableSetOf<Int>()
|
|
||||||
val lessons = mutableListOf<Lesson>()
|
|
||||||
|
|
||||||
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 newSubjectName = lesson.getString("PrzedmiotZastepujacy")
|
|
||||||
val newSubject = when (newSubjectName.isNullOrBlank()) {
|
|
||||||
true -> null
|
|
||||||
else -> data.getSubject(newSubjectName, null, newSubjectName)
|
|
||||||
}
|
|
||||||
|
|
||||||
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 type = lesson.getInt("TypZastepstwa") ?: -1
|
|
||||||
|
|
||||||
val lessonObject = Lesson(profileId, -1)
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lessonObject.id = lessonObject.buildId()
|
|
||||||
|
|
||||||
dates.add(lessonDate.value)
|
|
||||||
lessons.add(lessonObject)
|
|
||||||
|
|
||||||
val seen = profile.empty || lessonDate < Date.getToday()
|
|
||||||
|
|
||||||
if (lessonObject.type != Lesson.TYPE_NORMAL && lessonDate >= Date.getToday()) {
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_LESSON_CHANGE,
|
|
||||||
lessonObject.id,
|
|
||||||
seen,
|
|
||||||
seen
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.lessonList.addAll(lessons)
|
|
||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_IDZIENNIK_WEB_TIMETABLE)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-27.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.firstlogin
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_SETTINGS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_IDZIENNIK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.fixName
|
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.set
|
|
||||||
import pl.szczodrzynski.edziennik.swapFirstLastName
|
|
||||||
|
|
||||||
class IdziennikFirstLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikFirstLogin"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val web = IdziennikWeb(data, null)
|
|
||||||
private val profileList = mutableListOf<Profile>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
val loginStoreId = data.loginStore.id
|
|
||||||
val loginStoreType = LOGIN_TYPE_IDZIENNIK
|
|
||||||
var firstProfileId = loginStoreId
|
|
||||||
|
|
||||||
IdziennikLoginWeb(data) {
|
|
||||||
web.webGet(TAG, IDZIENNIK_WEB_SETTINGS) { text ->
|
|
||||||
//val accounts = json.getJsonArray("accounts")
|
|
||||||
|
|
||||||
val isParent = Regexes.IDZIENNIK_LOGIN_FIRST_IS_PARENT.find(text)?.get(1) != "0"
|
|
||||||
val accountNameLong = if (isParent)
|
|
||||||
Regexes.IDZIENNIK_LOGIN_FIRST_ACCOUNT_NAME.find(text)?.get(1)?.swapFirstLastName()?.fixName()
|
|
||||||
else null
|
|
||||||
|
|
||||||
var schoolYearStart: Int? = null
|
|
||||||
var schoolYearEnd: Int? = null
|
|
||||||
var schoolYearName: String? = null
|
|
||||||
val schoolYearId = Regexes.IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR.find(text)?.let {
|
|
||||||
schoolYearName = it[2]+"/"+it[3]
|
|
||||||
schoolYearStart = it[2].toIntOrNull()
|
|
||||||
schoolYearEnd = it[3].toIntOrNull()
|
|
||||||
it[1].toIntOrNull()
|
|
||||||
} ?: run {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR)
|
|
||||||
.withApiResponse(text))
|
|
||||||
return@webGet
|
|
||||||
}
|
|
||||||
|
|
||||||
Regexes.IDZIENNIK_LOGIN_FIRST_STUDENT.findAll(text)
|
|
||||||
.toMutableList()
|
|
||||||
.reversed()
|
|
||||||
.forEach { match ->
|
|
||||||
val registerId = match[1].toIntOrNull() ?: return@forEach
|
|
||||||
val studentId = match[2]
|
|
||||||
val firstName = match[3]
|
|
||||||
val lastName = match[4]
|
|
||||||
val className = match[5] + " " + match[6]
|
|
||||||
|
|
||||||
val studentNameLong = "$firstName $lastName".fixName()
|
|
||||||
val studentNameShort = "$firstName ${lastName[0]}.".fixName()
|
|
||||||
val accountName = if (accountNameLong == studentNameLong) null else accountNameLong
|
|
||||||
|
|
||||||
val profile = Profile(
|
|
||||||
firstProfileId++,
|
|
||||||
loginStoreId,
|
|
||||||
loginStoreType,
|
|
||||||
studentNameLong,
|
|
||||||
data.webUsername,
|
|
||||||
studentNameLong,
|
|
||||||
studentNameShort,
|
|
||||||
accountName
|
|
||||||
).apply {
|
|
||||||
schoolYearStart?.let { studentSchoolYearStart = it }
|
|
||||||
studentClassName = className
|
|
||||||
studentData["studentId"] = studentId
|
|
||||||
studentData["registerId"] = registerId
|
|
||||||
studentData["schoolYearId"] = schoolYearId
|
|
||||||
}
|
|
||||||
profileList.add(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-25.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_API
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_IDZIENNIK_WEB
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
|
|
||||||
class IdziennikLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikLogin"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var cancelled = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
nextLoginMethod(onSuccess)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun nextLoginMethod(onSuccess: () -> Unit) {
|
|
||||||
if (data.targetLoginMethodIds.isEmpty()) {
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (cancelled) {
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
|
|
||||||
data.progress(data.progressStep)
|
|
||||||
if (usedMethodId != -1)
|
|
||||||
data.loginMethods.add(usedMethodId)
|
|
||||||
nextLoginMethod(onSuccess)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun useLoginMethod(loginMethodId: Int, onSuccess: (usedMethodId: Int) -> Unit) {
|
|
||||||
// this should never be true
|
|
||||||
if (data.loginMethods.contains(loginMethodId)) {
|
|
||||||
onSuccess(-1)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Utils.d(TAG, "Using login method $loginMethodId")
|
|
||||||
when (loginMethodId) {
|
|
||||||
LOGIN_METHOD_IDZIENNIK_WEB -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_login_idziennik_web)
|
|
||||||
IdziennikLoginWeb(data) { onSuccess(loginMethodId) }
|
|
||||||
}
|
|
||||||
LOGIN_METHOD_IDZIENNIK_API -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_login_idziennik_api)
|
|
||||||
IdziennikLoginApi(data) { onSuccess(loginMethodId) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-27.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
|
|
||||||
class IdziennikLoginApi(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikLoginApi"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (data.isApiLoginValid()) {
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-26.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login
|
|
||||||
|
|
||||||
import im.wangchao.mhttp.Request
|
|
||||||
import im.wangchao.mhttp.Response
|
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "IdziennikLoginWeb"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (data.isWebLoginValid()) {
|
|
||||||
data.app.cookieJar.set("iuczniowie.progman.pl", "ASP.NET_SessionId_iDziennik", data.webSessionId)
|
|
||||||
data.app.cookieJar.set("iuczniowie.progman.pl", ".ASPXAUTH", data.webAuth)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data.app.cookieJar.clear("iuczniowie.progman.pl")
|
|
||||||
if (data.webSchoolName != null && data.webUsername != null && data.webPassword != null) {
|
|
||||||
loginWithCredentials()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun loginWithCredentials() {
|
|
||||||
Utils.d(TAG, "Request: Idziennik/Login/Web - $IDZIENNIK_WEB_URL/$IDZIENNIK_WEB_LOGIN")
|
|
||||||
|
|
||||||
val loginCallback = object : TextCallbackHandler() {
|
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
|
||||||
if (text.isNullOrEmpty()) {
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// login succeeded: there is a start page
|
|
||||||
if (text.contains("czyWyswietlicDostepMobilny")) {
|
|
||||||
val cookies = data.app.cookieJar.getAll("iuczniowie.progman.pl")
|
|
||||||
run {
|
|
||||||
data.webSessionId = cookies["ASP.NET_SessionId_iDziennik"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION
|
|
||||||
data.webAuth = cookies[".ASPXAUTH"] ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH
|
|
||||||
data.apiBearer = cookies["Bearer"]?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
|
||||||
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
|
||||||
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
|
||||||
|
|
||||||
val hiddenFields = JsonObject()
|
|
||||||
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
|
||||||
hiddenFields[it[1]] = it[2]
|
|
||||||
}
|
|
||||||
data.loginStore.putLoginData("hiddenFields", hiddenFields)
|
|
||||||
|
|
||||||
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
|
||||||
val registerId = it[1].toIntOrNull() ?: return@let
|
|
||||||
data.webSelectedRegister = registerId
|
|
||||||
}
|
|
||||||
|
|
||||||
// for profiles created after archiving
|
|
||||||
data.schoolYearId = Regexes.IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR.find(text)?.let {
|
|
||||||
it[1].toIntOrNull()
|
|
||||||
} ?: data.schoolYearId
|
|
||||||
data.profile?.studentClassName = Regexes.IDZIENNIK_LOGIN_FIRST_STUDENT.findAll(text)
|
|
||||||
.firstOrNull { it[1].toIntOrNull() == data.registerId }
|
|
||||||
?.let { "${it[5]} ${it[6]}" } ?: data.profile?.studentClassName
|
|
||||||
|
|
||||||
data.profile?.let { profile ->
|
|
||||||
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
|
|
||||||
val number = it[1].toIntOrNull() ?: return@also
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
|
||||||
profileId = data.profileId,
|
|
||||||
date = Date.getToday(),
|
|
||||||
number = number
|
|
||||||
)
|
|
||||||
|
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
|
||||||
data.metadataList.add(
|
|
||||||
Metadata(
|
|
||||||
profile.id,
|
|
||||||
Metadata.TYPE_LUCKY_NUMBER,
|
|
||||||
luckyNumberObject.date.value.toLong(),
|
|
||||||
true,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return@run null
|
|
||||||
}?.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(text)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val errorText = Regexes.IDZIENNIK_LOGIN_ERROR.find(text)?.get(1)
|
|
||||||
when {
|
|
||||||
errorText?.contains("nieprawidłową nazwę szkoły") == true -> ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME
|
|
||||||
errorText?.contains("nieprawidłowy login lub hasło") == true -> ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN
|
|
||||||
text.contains("Identyfikator zgłoszenia") -> ERROR_LOGIN_IDZIENNIK_WEB_SERVER_ERROR
|
|
||||||
text.contains("Hasło dostępu do systemu wygasło") -> ERROR_LOGIN_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED
|
|
||||||
text.contains("Trwają prace konserwacyjne") -> ERROR_LOGIN_IDZIENNIK_WEB_MAINTENANCE
|
|
||||||
else -> ERROR_LOGIN_IDZIENNIK_WEB_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(text)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val getCallback = object : TextCallbackHandler() {
|
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_WEB_URL/$IDZIENNIK_WEB_LOGIN")
|
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
|
||||||
.addHeader("Origin", "https://iuczniowie.progman.pl")
|
|
||||||
.addHeader("Referer", "$IDZIENNIK_WEB_URL/$IDZIENNIK_WEB_LOGIN")
|
|
||||||
.apply {
|
|
||||||
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text ?: return@apply).forEach {
|
|
||||||
addParameter(it[1], it[2])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$nazwaPrzegladarki", IDZIENNIK_USER_AGENT)
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$NazwaSzkoly", data.webSchoolName)
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$UserName", data.webUsername)
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$Password", data.webPassword)
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$captcha", "")
|
|
||||||
.addParameter("ctl00\$ContentPlaceHolder\$Logowanie", "Zaloguj")
|
|
||||||
.post()
|
|
||||||
.allowErrorCode(502)
|
|
||||||
.callback(loginCallback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("$IDZIENNIK_WEB_URL/$IDZIENNIK_WEB_LOGIN")
|
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
|
||||||
.get()
|
|
||||||
.allowErrorCode(502)
|
|
||||||
.callback(getCallback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -174,7 +174,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
val topic = lesson[1].substringAfter(" - ", missingDelimiterValue = "").takeIf { it.isNotBlank() }
|
val topic = lesson[1].substringAfter(" - ", missingDelimiterValue = "").takeIf { it.isNotBlank() }
|
||||||
if (topic?.startsWith("Lekcja odwołana: ") == true || entry.isEmpty())
|
if (topic?.startsWith("Lekcja odwołana: ") == true || entry.isEmpty())
|
||||||
return
|
return
|
||||||
val subjectName = lesson[1].substringBefore(" - ")
|
val subjectName = lesson[1].substringBefore(" - ").trim()
|
||||||
//val team = lesson[3]
|
//val team = lesson[3]
|
||||||
val teacherName = lesson[3].fixName()
|
val teacherName = lesson[3].fixName()
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
}
|
}
|
||||||
entry = entry.removePrefix(typeSymbol)
|
entry = entry.removePrefix(typeSymbol)
|
||||||
|
|
||||||
var isCounted = true
|
var isCustom = false
|
||||||
val baseType = when (typeSymbol) {
|
val baseType = when (typeSymbol) {
|
||||||
"." -> TYPE_PRESENT
|
"." -> TYPE_PRESENT
|
||||||
"|" -> TYPE_ABSENT
|
"|" -> TYPE_ABSENT
|
||||||
@ -196,11 +196,12 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
"s" -> TYPE_BELATED
|
"s" -> TYPE_BELATED
|
||||||
"z" -> TYPE_RELEASED
|
"z" -> TYPE_RELEASED
|
||||||
else -> {
|
else -> {
|
||||||
isCounted = false
|
isCustom = true
|
||||||
when (typeSymbol) {
|
when (typeSymbol) {
|
||||||
"e" -> TYPE_PRESENT_CUSTOM
|
"e" -> TYPE_PRESENT_CUSTOM
|
||||||
"en" -> TYPE_ABSENT
|
"en" -> TYPE_ABSENT
|
||||||
"ep" -> TYPE_PRESENT_CUSTOM
|
"ep" -> TYPE_PRESENT_CUSTOM
|
||||||
|
"+ₑ" -> TYPE_ABSENT_EXCUSED
|
||||||
else -> TYPE_UNKNOWN
|
else -> TYPE_UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,10 +211,11 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
"e" -> 0xff673ab7
|
"e" -> 0xff673ab7
|
||||||
"en" -> 0xffec407a
|
"en" -> 0xffec407a
|
||||||
"ep" -> 0xff4caf50
|
"ep" -> 0xff4caf50
|
||||||
|
"+ₑ" -> 0xff795548
|
||||||
else -> null
|
else -> null
|
||||||
}?.toInt()
|
}?.toInt()
|
||||||
|
|
||||||
val typeShort = if (isCounted)
|
val typeShort = if (!isCustom)
|
||||||
data.app.attendanceManager.getTypeShort(baseType)
|
data.app.attendanceManager.getTypeShort(baseType)
|
||||||
else
|
else
|
||||||
typeSymbol
|
typeSymbol
|
||||||
@ -237,7 +239,6 @@ class MobidziennikWebAttendance(override val data: DataMobidziennik,
|
|||||||
subjectId = subjectId
|
subjectId = subjectId
|
||||||
).also {
|
).also {
|
||||||
it.lessonTopic = topic
|
it.lessonTopic = topic
|
||||||
it.isCounted = isCounted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
|
@ -74,16 +74,16 @@ class MobidziennikWebGetMessage(override val data: DataMobidziennik,
|
|||||||
message.senderId = null
|
message.senderId = null
|
||||||
|
|
||||||
content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
|
content.select("table.spis tr:has(td)")?.forEach { recipientEl ->
|
||||||
val senderEl = recipientEl.select("td:eq(0)").first()
|
val senderEl = recipientEl.select("td:eq(1)")?.first() ?: return@forEach
|
||||||
val senderName = senderEl.text().fixName()
|
val senderName = senderEl.text().fixName()
|
||||||
|
|
||||||
val teacher = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }
|
val teacher = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName }
|
||||||
val receiverId = teacher?.id ?: -1
|
val receiverId = teacher?.id ?: -1
|
||||||
|
|
||||||
var readDate = 0L
|
var readDate = 0L
|
||||||
val isReadEl = recipientEl.select("td:eq(2)").first()
|
val isReadEl = recipientEl.select("td:eq(4)")?.first() ?: return@forEach
|
||||||
if (isReadEl.ownText() != "NIE") {
|
if (isReadEl.html().contains("tak")) {
|
||||||
val readDateEl = recipientEl.select("td:eq(3) small").first()
|
val readDateEl = recipientEl.select("td:eq(5) small")?.first() ?: return@forEach
|
||||||
Regexes.MOBIDZIENNIK_MESSAGE_SENT_READ_DATE.find(readDateEl.ownText())?.let {
|
Regexes.MOBIDZIENNIK_MESSAGE_SENT_READ_DATE.find(readDateEl.ownText())?.let {
|
||||||
val date = Date(
|
val date = Date(
|
||||||
it[3].toIntOrNull() ?: 2019,
|
it[3].toIntOrNull() ?: 2019,
|
||||||
|
@ -46,7 +46,7 @@ class MobidziennikWebGrades(override val data: DataMobidziennik,
|
|||||||
when (e.tagName()) {
|
when (e.tagName()) {
|
||||||
"div" -> {
|
"div" -> {
|
||||||
Regexes.MOBIDZIENNIK_GRADES_SUBJECT_NAME.find(e.outerHtml())?.let {
|
Regexes.MOBIDZIENNIK_GRADES_SUBJECT_NAME.find(e.outerHtml())?.let {
|
||||||
subjectName = it[1]
|
subjectName = it[1].trim()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"span" -> {
|
"span" -> {
|
||||||
|
@ -4,28 +4,23 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_API
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
|
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_HEBE
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_HEBE
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_WEB_MAIN
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_WEB_MAIN
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_MODE_VULCAN_API
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||||
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.data.db.entity.Team
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.fslogin.realm.RealmData
|
||||||
|
|
||||||
class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
|
class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
|
||||||
|
fun isWebMainLoginValid() = symbol.isNotNullNorEmpty()
|
||||||
fun isWebMainLoginValid() = webExpiryTime-30 > currentTimeUnix()
|
&& (webExpiryTime[symbol]?.toLongOrNull() ?: 0) - 30 > currentTimeUnix()
|
||||||
&& webAuthCookie.isNotNullNorEmpty()
|
&& webAuthCookie[symbol].isNotNullNorEmpty()
|
||||||
&& webHost.isNotNullNorEmpty()
|
&& webRealmData != null
|
||||||
&& webType.isNotNullNorEmpty()
|
|
||||||
&& symbol.isNotNullNorEmpty()
|
|
||||||
fun isApiLoginValid() = currentSemesterEndDate-30 > currentTimeUnix()
|
|
||||||
&& apiFingerprint[symbol].isNotNullNorEmpty()
|
|
||||||
&& apiPrivateKey[symbol].isNotNullNorEmpty()
|
|
||||||
&& symbol.isNotNullNorEmpty()
|
|
||||||
fun isHebeLoginValid() = hebePublicKey.isNotNullNorEmpty()
|
fun isHebeLoginValid() = hebePublicKey.isNotNullNorEmpty()
|
||||||
&& hebePrivateKey.isNotNullNorEmpty()
|
&& hebePrivateKey.isNotNullNorEmpty()
|
||||||
&& symbol.isNotNullNorEmpty()
|
&& symbol.isNotNullNorEmpty()
|
||||||
@ -35,34 +30,11 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
if (isWebMainLoginValid()) {
|
if (isWebMainLoginValid()) {
|
||||||
loginMethods += LOGIN_METHOD_VULCAN_WEB_MAIN
|
loginMethods += LOGIN_METHOD_VULCAN_WEB_MAIN
|
||||||
}
|
}
|
||||||
if (isApiLoginValid()) {
|
|
||||||
loginMethods += LOGIN_METHOD_VULCAN_API
|
|
||||||
}
|
|
||||||
if (isHebeLoginValid()) {
|
if (isHebeLoginValid()) {
|
||||||
loginMethods += LOGIN_METHOD_VULCAN_HEBE
|
loginMethods += LOGIN_METHOD_VULCAN_HEBE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
// during the first sync `profile.studentClassName` is already set
|
|
||||||
if (loginStore.mode == LOGIN_MODE_VULCAN_API
|
|
||||||
&& teamList.values().none { it.type == Team.TYPE_CLASS }) {
|
|
||||||
profile?.studentClassName?.also { name ->
|
|
||||||
val id = Utils.crc16(name.toByteArray()).toLong()
|
|
||||||
|
|
||||||
val teamObject = Team(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
Team.TYPE_CLASS,
|
|
||||||
"$schoolCode:$name",
|
|
||||||
-1
|
|
||||||
)
|
|
||||||
teamList.put(id, teamObject)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateUserCode() = "$schoolCode:$studentId"
|
override fun generateUserCode() = "$schoolCode:$studentId"
|
||||||
|
|
||||||
fun buildDeviceId(): String {
|
fun buildDeviceId(): String {
|
||||||
@ -224,16 +196,6 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
get() { mApiPin = mApiPin ?: loginStore.getLoginData("apiPin", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mApiPin ?: mapOf() }
|
get() { mApiPin = mApiPin ?: loginStore.getLoginData("apiPin", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mApiPin ?: mapOf() }
|
||||||
set(value) { loginStore.putLoginData("apiPin", app.gson.toJson(value)); mApiPin = value }
|
set(value) { loginStore.putLoginData("apiPin", app.gson.toJson(value)); mApiPin = value }
|
||||||
|
|
||||||
private var mApiFingerprint: Map<String?, String?>? = null
|
|
||||||
var apiFingerprint: Map<String?, String?> = mapOf()
|
|
||||||
get() { mApiFingerprint = mApiFingerprint ?: loginStore.getLoginData("apiFingerprint", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mApiFingerprint ?: mapOf() }
|
|
||||||
set(value) { loginStore.putLoginData("apiFingerprint", app.gson.toJson(value)); mApiFingerprint = value }
|
|
||||||
|
|
||||||
private var mApiPrivateKey: Map<String?, String?>? = null
|
|
||||||
var apiPrivateKey: Map<String?, String?> = mapOf()
|
|
||||||
get() { mApiPrivateKey = mApiPrivateKey ?: loginStore.getLoginData("apiPrivateKey", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mApiPrivateKey ?: mapOf() }
|
|
||||||
set(value) { loginStore.putLoginData("apiPrivateKey", app.gson.toJson(value)); mApiPrivateKey = value }
|
|
||||||
|
|
||||||
/* _ _ _ _____ _____
|
/* _ _ _ _____ _____
|
||||||
| | | | | | /\ | __ \_ _|
|
| | | | | | /\ | __ \_ _|
|
||||||
| |__| | ___| |__ ___ / \ | |__) || |
|
| |__| | ___| |__ ___ / \ | |__) || |
|
||||||
@ -297,49 +259,15 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
\/ \/ \___|_.__/ |_| |_____/ |______\___/ \__, |_|_| |_|
|
\/ \/ \___|_.__/ |_| |_____/ |______\___/ \__, |_|_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
/**
|
var webRealmData: RealmData?
|
||||||
* Federation Services login type.
|
get() { mWebRealmData = mWebRealmData ?: loginStore.getLoginData("webRealmData", JsonObject()).let {
|
||||||
* This might be one of: cufs, adfs, adfslight.
|
app.gson.fromJson(it, RealmData::class.java)
|
||||||
*/
|
}; return mWebRealmData }
|
||||||
var webType: String?
|
set(value) { loginStore.putLoginData("webRealmData", app.gson.toJsonTree(value) as JsonObject); mWebRealmData = value }
|
||||||
get() { mWebType = mWebType ?: loginStore.getLoginData("webType", null); return mWebType }
|
private var mWebRealmData: RealmData? = null
|
||||||
set(value) { loginStore.putLoginData("webType", value); mWebType = value }
|
|
||||||
private var mWebType: String? = null
|
|
||||||
|
|
||||||
/**
|
val webHost
|
||||||
* Web server providing the federation services login.
|
get() = webRealmData?.host
|
||||||
* If this is present, WEB_MAIN login is considered as available.
|
|
||||||
*/
|
|
||||||
var webHost: String?
|
|
||||||
get() { mWebHost = mWebHost ?: loginStore.getLoginData("webHost", null); return mWebHost }
|
|
||||||
set(value) { loginStore.putLoginData("webHost", value); mWebHost = value }
|
|
||||||
private var mWebHost: String? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An ID used in ADFS & ADFSLight login types.
|
|
||||||
*/
|
|
||||||
var webAdfsId: String?
|
|
||||||
get() { mWebAdfsId = mWebAdfsId ?: loginStore.getLoginData("webAdfsId", null); return mWebAdfsId }
|
|
||||||
set(value) { loginStore.putLoginData("webAdfsId", value); mWebAdfsId = value }
|
|
||||||
private var mWebAdfsId: String? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A domain override for ADFS Light.
|
|
||||||
*/
|
|
||||||
var webAdfsDomain: String?
|
|
||||||
get() { mWebAdfsDomain = mWebAdfsDomain ?: loginStore.getLoginData("webAdfsDomain", null); return mWebAdfsDomain }
|
|
||||||
set(value) { loginStore.putLoginData("webAdfsDomain", value); mWebAdfsDomain = value }
|
|
||||||
private var mWebAdfsDomain: String? = null
|
|
||||||
|
|
||||||
var webIsHttpCufs: Boolean
|
|
||||||
get() { mWebIsHttpCufs = mWebIsHttpCufs ?: loginStore.getLoginData("webIsHttpCufs", false); return mWebIsHttpCufs ?: false }
|
|
||||||
set(value) { loginStore.putLoginData("webIsHttpCufs", value); mWebIsHttpCufs = value }
|
|
||||||
private var mWebIsHttpCufs: Boolean? = null
|
|
||||||
|
|
||||||
var webIsScopedAdfs: Boolean
|
|
||||||
get() { mWebIsScopedAdfs = mWebIsScopedAdfs ?: loginStore.getLoginData("webIsScopedAdfs", false); return mWebIsScopedAdfs ?: false }
|
|
||||||
set(value) { loginStore.putLoginData("webIsScopedAdfs", value); mWebIsScopedAdfs = value }
|
|
||||||
private var mWebIsScopedAdfs: Boolean? = null
|
|
||||||
|
|
||||||
var webEmail: String?
|
var webEmail: String?
|
||||||
get() { mWebEmail = mWebEmail ?: loginStore.getLoginData("webEmail", null); return mWebEmail }
|
get() { mWebEmail = mWebEmail ?: loginStore.getLoginData("webEmail", null); return mWebEmail }
|
||||||
@ -359,24 +287,24 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
* If the time passes, the certificate needs to be POSTed again (if valid)
|
* If the time passes, the certificate needs to be POSTed again (if valid)
|
||||||
* or re-generated.
|
* or re-generated.
|
||||||
*/
|
*/
|
||||||
var webExpiryTime: Long
|
var webExpiryTime: Map<String, String?> = mapOf()
|
||||||
get() { mWebExpiryTime = mWebExpiryTime ?: profile?.getStudentData("webExpiryTime", 0L); return mWebExpiryTime ?: 0L }
|
get() { mWebExpiryTime = mWebExpiryTime ?: loginStore.getLoginData("webExpiryTime", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mWebExpiryTime ?: mapOf() }
|
||||||
set(value) { profile?.putStudentData("webExpiryTime", value); mWebExpiryTime = value }
|
set(value) { loginStore.putLoginData("webExpiryTime", app.gson.toJson(value)); mWebExpiryTime = value }
|
||||||
private var mWebExpiryTime: Long? = null
|
private var mWebExpiryTime: Map<String, String?>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EfebSsoAuthCookie retrieved after posting a certificate
|
* EfebSsoAuthCookie retrieved after posting a certificate
|
||||||
*/
|
*/
|
||||||
var webAuthCookie: String?
|
var webAuthCookie: Map<String, String?> = mapOf()
|
||||||
get() { mWebAuthCookie = mWebAuthCookie ?: profile?.getStudentData("webAuthCookie", null); return mWebAuthCookie }
|
get() { mWebAuthCookie = mWebAuthCookie ?: loginStore.getLoginData("webAuthCookie", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mWebAuthCookie ?: mapOf() }
|
||||||
set(value) { profile?.putStudentData("webAuthCookie", value); mWebAuthCookie = value }
|
set(value) { loginStore.putLoginData("webAuthCookie", app.gson.toJson(value)); mWebAuthCookie = value }
|
||||||
private var mWebAuthCookie: String? = null
|
private var mWebAuthCookie: Map<String, String?>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Permissions needed to get JSONs from home page
|
* Permissions needed to get JSONs from home page
|
||||||
*/
|
*/
|
||||||
var webPermissions: String?
|
var webPermissions: Map<String, String?> = mapOf()
|
||||||
get() { mWebPermissions = mWebPermissions ?: profile?.getStudentData("webPermissions", null); return mWebPermissions }
|
get() { mWebPermissions = mWebPermissions ?: loginStore.getLoginData("webPermissions", null)?.let { app.gson.fromJson(it, field.toMutableMap()::class.java) }; return mWebPermissions ?: mapOf() }
|
||||||
set(value) { profile?.putStudentData("webPermissions", value); mWebPermissions = value }
|
set(value) { loginStore.putLoginData("webPermissions", app.gson.toJson(value)); mWebPermissions = value }
|
||||||
private var mWebPermissions: String? = null
|
private var mWebPermissions: Map<String, String?>? = null
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,8 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.helper.OneDriveDownloadAttachment
|
import pl.szczodrzynski.edziennik.data.api.edziennik.helper.OneDriveDownloadAttachment
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiAttachments
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiMessagesChangeStatus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.VulcanApiSendMessage
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.VulcanHebeMessagesChangeStatus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.VulcanHebeMessagesChangeStatus
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.VulcanHebeSendMessage
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.firstlogin.VulcanFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.firstlogin.VulcanFirstLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLogin
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||||
@ -68,6 +66,11 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun login(loginMethodId: Int? = null, afterLogin: (() -> Unit)? = null) {
|
private fun login(loginMethodId: Int? = null, afterLogin: (() -> Unit)? = null) {
|
||||||
|
if (data.loginStore.mode == LOGIN_MODE_VULCAN_API) {
|
||||||
|
data.error(TAG, ERROR_VULCAN_API_DEPRECATED)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
|
d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
|
||||||
if (internalErrorList.isNotEmpty()) {
|
if (internalErrorList.isNotEmpty()) {
|
||||||
d(TAG, " - Internal errors:")
|
d(TAG, " - Internal errors:")
|
||||||
@ -92,7 +95,6 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getMessage(message: MessageFull) {
|
override fun getMessage(message: MessageFull) {
|
||||||
if (loginStore.mode != LOGIN_MODE_VULCAN_API) {
|
|
||||||
login(LOGIN_METHOD_VULCAN_HEBE) {
|
login(LOGIN_METHOD_VULCAN_HEBE) {
|
||||||
if (message.seen) {
|
if (message.seen) {
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
||||||
@ -103,40 +105,11 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
completed()
|
completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
login(LOGIN_METHOD_VULCAN_API) {
|
|
||||||
if (message.attachmentIds != null) {
|
|
||||||
VulcanApiMessagesChangeStatus(data, message) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
return@login
|
|
||||||
}
|
|
||||||
val list = data.app.db.messageDao().getAllNow(data.profileId)
|
|
||||||
VulcanApiAttachments(data, list, message, MessageFull::class) { _ ->
|
|
||||||
list.forEach {
|
|
||||||
if (it.attachmentIds == null)
|
|
||||||
it.attachmentIds = mutableListOf()
|
|
||||||
data.messageList.add(it)
|
|
||||||
}
|
|
||||||
data.messageListReplace = true
|
|
||||||
|
|
||||||
if (message.seen) {
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(message))
|
|
||||||
completed()
|
|
||||||
return@VulcanApiAttachments
|
|
||||||
}
|
|
||||||
VulcanApiMessagesChangeStatus(data, message) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sendMessage(recipients: List<Teacher>, subject: String, text: String) {
|
override fun sendMessage(recipients: List<Teacher>, subject: String, text: String) {
|
||||||
login(LOGIN_METHOD_VULCAN_API) {
|
login(LOGIN_METHOD_VULCAN_HEBE) {
|
||||||
VulcanApiSendMessage(data, recipients, subject, text) {
|
VulcanHebeSendMessage(data, recipients, subject, text) {
|
||||||
completed()
|
completed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,20 +163,11 @@ class Vulcan(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getEvent(eventFull: EventFull) {
|
override fun getEvent(eventFull: EventFull) {
|
||||||
login(LOGIN_METHOD_VULCAN_API) {
|
eventFull.homeworkBody = ""
|
||||||
val list = data.app.db.eventDao().getAllNow(data.profileId).filter { !it.addedManually }
|
|
||||||
VulcanApiAttachments(data, list, eventFull, EventFull::class) { _ ->
|
|
||||||
list.forEach {
|
|
||||||
it.homeworkBody = ""
|
|
||||||
data.eventList.add(it)
|
|
||||||
}
|
|
||||||
data.eventListReplace = true
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(EventGetEvent(eventFull))
|
EventBus.getDefault().postSticky(EventGetEvent(eventFull))
|
||||||
completed()
|
completed()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun firstLogin() { VulcanFirstLogin(data) { completed() } }
|
override fun firstLogin() { VulcanFirstLogin(data) { completed() } }
|
||||||
override fun cancel() {
|
override fun cancel() {
|
||||||
|
@ -7,77 +7,49 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan
|
|||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
||||||
|
|
||||||
const val ENDPOINT_VULCAN_API_UPDATE_SEMESTER = 1000
|
|
||||||
const val ENDPOINT_VULCAN_API_PUSH_CONFIG = 1005
|
|
||||||
const val ENDPOINT_VULCAN_API_DICTIONARIES = 1010
|
|
||||||
const val ENDPOINT_VULCAN_API_TIMETABLE = 1020
|
|
||||||
const val ENDPOINT_VULCAN_API_EVENTS = 1030
|
|
||||||
const val ENDPOINT_VULCAN_API_GRADES = 1040
|
|
||||||
const val ENDPOINT_VULCAN_API_GRADES_SUMMARY = 1050
|
|
||||||
const val ENDPOINT_VULCAN_API_HOMEWORK = 1060
|
|
||||||
const val ENDPOINT_VULCAN_API_NOTICES = 1070
|
|
||||||
const val ENDPOINT_VULCAN_API_ATTENDANCE = 1080
|
|
||||||
const val ENDPOINT_VULCAN_API_MESSAGES_INBOX = 1090
|
|
||||||
const val ENDPOINT_VULCAN_API_MESSAGES_SENT = 1100
|
|
||||||
const val ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS = 2010
|
const val ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS = 2010
|
||||||
|
|
||||||
const val ENDPOINT_VULCAN_HEBE_MAIN = 3000
|
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 = 3010
|
||||||
const val ENDPOINT_VULCAN_HEBE_TIMETABLE = 3020
|
const val ENDPOINT_VULCAN_HEBE_TIMETABLE = 3020
|
||||||
const val ENDPOINT_VULCAN_HEBE_EXAMS = 3030
|
const val ENDPOINT_VULCAN_HEBE_EXAMS = 3030
|
||||||
const val ENDPOINT_VULCAN_HEBE_GRADES = 3040
|
const val ENDPOINT_VULCAN_HEBE_GRADES = 3040
|
||||||
|
const val ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY = 3050
|
||||||
const val ENDPOINT_VULCAN_HEBE_HOMEWORK = 3060
|
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_ATTENDANCE = 3080
|
||||||
const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3090
|
const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3090
|
||||||
const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3100
|
const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3100
|
||||||
|
const val ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER = 3200
|
||||||
|
|
||||||
val VulcanFeatures = listOf(
|
val VulcanFeatures = listOf(
|
||||||
// timetable
|
// timetable
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_TIMETABLE, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_TIMETABLE to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_TIMETABLE, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_TIMETABLE, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_TIMETABLE to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_TIMETABLE to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// agenda
|
// agenda
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_AGENDA, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_EVENTS to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_AGENDA, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_AGENDA, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_EXAMS to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_EXAMS to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// grades
|
// grades
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_GRADES, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_GRADES, listOf(
|
||||||
ENDPOINT_VULCAN_API_GRADES to LOGIN_METHOD_VULCAN_API,
|
ENDPOINT_VULCAN_HEBE_GRADES to LOGIN_METHOD_VULCAN_HEBE,
|
||||||
ENDPOINT_VULCAN_API_GRADES_SUMMARY to LOGIN_METHOD_VULCAN_API
|
ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_GRADES, listOf(
|
|
||||||
ENDPOINT_VULCAN_HEBE_GRADES to LOGIN_METHOD_VULCAN_HEBE
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// homework
|
// homework
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_HOMEWORK, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_HOMEWORK to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_HOMEWORK, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_HOMEWORK, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_HOMEWORK to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_HOMEWORK to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// behaviour
|
// behaviour
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_BEHAVIOUR, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_BEHAVIOUR, listOf(
|
||||||
ENDPOINT_VULCAN_API_NOTICES to LOGIN_METHOD_VULCAN_API
|
ENDPOINT_VULCAN_HEBE_NOTICES to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// attendance
|
// attendance
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_ATTENDANCE, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_ATTENDANCE to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_ATTENDANCE, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_ATTENDANCE, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_ATTENDANCE to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_ATTENDANCE to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
// messages
|
// messages
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_MESSAGES_INBOX, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_MESSAGES_INBOX to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_MESSAGES_SENT, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_MESSAGES_SENT to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_MESSAGES_INBOX, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_MESSAGES_INBOX, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)),
|
||||||
@ -87,8 +59,8 @@ val VulcanFeatures = listOf(
|
|||||||
|
|
||||||
// push config
|
// push config
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_PUSH_CONFIG, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_PUSH_CONFIG, listOf(
|
||||||
ENDPOINT_VULCAN_API_PUSH_CONFIG to LOGIN_METHOD_VULCAN_API
|
ENDPOINT_VULCAN_HEBE_PUSH_CONFIG to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)).withShouldSync { data ->
|
), listOf(LOGIN_METHOD_VULCAN_HEBE)).withShouldSync { data ->
|
||||||
!data.app.config.sync.tokenVulcanList.contains(data.profileId)
|
!data.app.config.sync.tokenVulcanList.contains(data.profileId)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -97,39 +69,20 @@ val VulcanFeatures = listOf(
|
|||||||
*/
|
*/
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_LUCKY_NUMBER, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_LUCKY_NUMBER, listOf(
|
||||||
ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS to LOGIN_METHOD_VULCAN_WEB_MAIN
|
ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS to LOGIN_METHOD_VULCAN_WEB_MAIN
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB_MAIN)).withShouldSync { data -> data.shouldSyncLuckyNumber() },
|
), listOf(LOGIN_METHOD_VULCAN_WEB_MAIN))
|
||||||
|
.withShouldSync { data -> data.shouldSyncLuckyNumber() }
|
||||||
|
.withPriority(2),
|
||||||
|
/**
|
||||||
|
* Lucky number - using Hebe API
|
||||||
|
*/
|
||||||
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_LUCKY_NUMBER, listOf(
|
||||||
|
ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER to LOGIN_METHOD_VULCAN_HEBE
|
||||||
|
), listOf(LOGIN_METHOD_VULCAN_HEBE))
|
||||||
|
.withShouldSync { data -> data.shouldSyncLuckyNumber() }
|
||||||
|
.withPriority(1),
|
||||||
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
|
|
||||||
ENDPOINT_VULCAN_API_UPDATE_SEMESTER to LOGIN_METHOD_VULCAN_API,
|
|
||||||
ENDPOINT_VULCAN_API_DICTIONARIES to LOGIN_METHOD_VULCAN_API
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_API)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
|
Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_MAIN to LOGIN_METHOD_VULCAN_HEBE,
|
ENDPOINT_VULCAN_HEBE_MAIN to LOGIN_METHOD_VULCAN_HEBE,
|
||||||
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE
|
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE
|
||||||
), listOf(LOGIN_METHOD_VULCAN_HEBE))
|
), listOf(LOGIN_METHOD_VULCAN_HEBE))
|
||||||
/*Feature(LOGIN_TYPE_VULCAN, FEATURE_STUDENT_INFO, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_STUDENT_NUMBER, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_SCHOOL_INFO, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_CLASS_INFO, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_TEAM_INFO, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_TEACHERS, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_SUBJECTS, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),
|
|
||||||
Feature(LOGIN_TYPE_VULCAN, FEATURE_CLASSROOMS, listOf(
|
|
||||||
ENDPOINT_VULCAN_API to LOGIN_METHOD_VULCAN_WEB
|
|
||||||
), listOf(LOGIN_METHOD_VULCAN_WEB)),*/
|
|
||||||
|
|
||||||
)
|
)
|
||||||
|
@ -1,132 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-19
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import im.wangchao.mhttp.Request
|
|
||||||
import im.wangchao.mhttp.Response
|
|
||||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|
||||||
import io.github.wulkanowy.signer.android.signContent
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import java.net.HttpURLConnection
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
open class VulcanApi(open val data: DataVulcan, open val lastSync: Long?) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApi"
|
|
||||||
}
|
|
||||||
|
|
||||||
val profileId
|
|
||||||
get() = data.profile?.id ?: -1
|
|
||||||
|
|
||||||
val profile
|
|
||||||
get() = data.profile
|
|
||||||
|
|
||||||
fun apiGet(
|
|
||||||
tag: String,
|
|
||||||
endpoint: String,
|
|
||||||
method: Int = POST,
|
|
||||||
parameters: Map<String, Any> = emptyMap(),
|
|
||||||
baseUrl: Boolean = false,
|
|
||||||
onSuccess: (json: JsonObject, response: Response?) -> Unit
|
|
||||||
) {
|
|
||||||
val url = "${if (baseUrl) data.apiUrl else data.fullApiUrl}$endpoint"
|
|
||||||
|
|
||||||
d(tag, "Request: Vulcan/Api - $url")
|
|
||||||
|
|
||||||
val finalPayload = JsonObject()
|
|
||||||
parameters.map { (name, value) ->
|
|
||||||
when (value) {
|
|
||||||
is JsonObject -> finalPayload.add(name, value)
|
|
||||||
is JsonArray -> finalPayload.add(name, value)
|
|
||||||
is String -> finalPayload.addProperty(name, value)
|
|
||||||
is Int -> finalPayload.addProperty(name, value)
|
|
||||||
is Long -> finalPayload.addProperty(name, value)
|
|
||||||
is Float -> finalPayload.addProperty(name, value)
|
|
||||||
is Char -> finalPayload.addProperty(name, value)
|
|
||||||
is Boolean -> finalPayload.addProperty(name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finalPayload.addProperty("RemoteMobileTimeKey", System.currentTimeMillis() / 1000)
|
|
||||||
finalPayload.addProperty("TimeKey", System.currentTimeMillis() / 1000 - 1)
|
|
||||||
finalPayload.addProperty("RequestId", UUID.randomUUID().toString())
|
|
||||||
finalPayload.addProperty("RemoteMobileAppVersion", VULCAN_API_APP_VERSION)
|
|
||||||
finalPayload.addProperty("RemoteMobileAppName", VULCAN_API_APP_NAME)
|
|
||||||
|
|
||||||
val callback = object : JsonCallbackHandler() {
|
|
||||||
override fun onSuccess(json: JsonObject?, response: Response?) {
|
|
||||||
if (json == null && response?.parserErrorBody == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response?.code() ?: 200 != 200) {
|
|
||||||
when (response?.code()) {
|
|
||||||
503 -> ERROR_VULCAN_API_MAINTENANCE
|
|
||||||
400 -> ERROR_VULCAN_API_BAD_REQUEST
|
|
||||||
else -> ERROR_VULCAN_API_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(tag, errorCode)
|
|
||||||
.withResponse(response)
|
|
||||||
.withApiResponse(json?.toString() ?: response?.parserErrorBody))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (json == null) {
|
|
||||||
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(json, response)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_VULCAN_API_REQUEST)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(e)
|
|
||||||
.withApiResponse(json))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url(url)
|
|
||||||
.userAgent(VULCAN_API_USER_AGENT)
|
|
||||||
.addHeader("RequestCertificateKey", data.apiFingerprint[data.symbol])
|
|
||||||
.addHeader("RequestSignatureValue",
|
|
||||||
try {
|
|
||||||
signContent(
|
|
||||||
data.apiPrivateKey[data.symbol] ?: "",
|
|
||||||
finalPayload.toString()
|
|
||||||
)
|
|
||||||
} catch (e: Exception) {e.printStackTrace();""})
|
|
||||||
.apply {
|
|
||||||
when (method) {
|
|
||||||
GET -> get()
|
|
||||||
POST -> post()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.setJsonBody(finalPayload)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_FORBIDDEN)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
|
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_UNAVAILABLE)
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,10 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_API_DEPRECATED
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_MODE_VULCAN_API
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.*
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.*
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.web.VulcanWebLuckyNumber
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.web.VulcanWebLuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
@ -22,17 +19,18 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
private var firstSemesterSync = false
|
private var firstSemesterSync = false
|
||||||
private val firstSemesterSyncExclude = listOf(
|
private val firstSemesterSyncExclude = listOf(
|
||||||
ENDPOINT_VULCAN_HEBE_MAIN,
|
ENDPOINT_VULCAN_HEBE_MAIN,
|
||||||
|
ENDPOINT_VULCAN_HEBE_PUSH_CONFIG,
|
||||||
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK,
|
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK,
|
||||||
ENDPOINT_VULCAN_HEBE_TIMETABLE,
|
ENDPOINT_VULCAN_HEBE_TIMETABLE,
|
||||||
|
ENDPOINT_VULCAN_HEBE_EXAMS,
|
||||||
|
ENDPOINT_VULCAN_HEBE_HOMEWORK,
|
||||||
|
ENDPOINT_VULCAN_HEBE_NOTICES,
|
||||||
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX,
|
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX,
|
||||||
ENDPOINT_VULCAN_HEBE_MESSAGES_SENT
|
ENDPOINT_VULCAN_HEBE_MESSAGES_SENT,
|
||||||
|
ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER
|
||||||
)
|
)
|
||||||
|
|
||||||
init { run {
|
init {
|
||||||
if (data.loginStore.mode == LOGIN_MODE_VULCAN_API) {
|
|
||||||
data.error(TAG, ERROR_VULCAN_API_DEPRECATED)
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
if (data.studentSemesterNumber == 2 && data.profile?.empty != false) {
|
if (data.studentSemesterNumber == 2 && data.profile?.empty != false) {
|
||||||
firstSemesterSync = true
|
firstSemesterSync = true
|
||||||
// set to sync 1st semester first
|
// set to sync 1st semester first
|
||||||
@ -47,7 +45,7 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
}
|
}
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
|
|
||||||
private fun nextEndpoint(onSuccess: () -> Unit) {
|
private fun nextEndpoint(onSuccess: () -> Unit) {
|
||||||
if (data.targetEndpointIds.isEmpty()) {
|
if (data.targetEndpointIds.isEmpty()) {
|
||||||
@ -83,54 +81,6 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
ENDPOINT_VULCAN_API_UPDATE_SEMESTER -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
|
|
||||||
VulcanApiUpdateSemester(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_PUSH_CONFIG -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_push_config)
|
|
||||||
VulcanApiPushConfig(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_DICTIONARIES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_dictionaries)
|
|
||||||
VulcanApiDictionaries(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_GRADES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
|
||||||
VulcanApiGrades(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_GRADES_SUMMARY -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
|
||||||
VulcanApiProposedGrades(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_EVENTS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
|
||||||
VulcanApiEvents(data, isHomework = false, lastSync = lastSync, onSuccess = onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_HOMEWORK -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
|
||||||
VulcanApiEvents(data, isHomework = true, lastSync = lastSync, onSuccess = onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_NOTICES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
|
||||||
VulcanApiNotices(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_ATTENDANCE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
|
||||||
VulcanApiAttendance(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_TIMETABLE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
|
||||||
VulcanApiTimetable(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_MESSAGES_INBOX -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
|
||||||
VulcanApiMessagesInbox(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_API_MESSAGES_SENT -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
|
||||||
VulcanApiMessagesSent(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS -> {
|
ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
VulcanWebLuckyNumber(data, lastSync, onSuccess)
|
VulcanWebLuckyNumber(data, lastSync, onSuccess)
|
||||||
@ -148,6 +98,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
onSuccess(ENDPOINT_VULCAN_HEBE_MAIN)
|
onSuccess(ENDPOINT_VULCAN_HEBE_MAIN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ENDPOINT_VULCAN_HEBE_PUSH_CONFIG -> {
|
||||||
|
data.startProgress(R.string.edziennik_progress_endpoint_push_config)
|
||||||
|
VulcanHebePushConfig(data, lastSync, onSuccess)
|
||||||
|
}
|
||||||
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK -> {
|
ENDPOINT_VULCAN_HEBE_ADDRESSBOOK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
||||||
VulcanHebeAddressbook(data, lastSync, onSuccess)
|
VulcanHebeAddressbook(data, lastSync, onSuccess)
|
||||||
@ -164,10 +118,22 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
VulcanHebeGrades(data, lastSync, onSuccess)
|
VulcanHebeGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY -> {
|
||||||
|
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
||||||
|
VulcanHebeGradeSummary(data, lastSync, onSuccess)
|
||||||
|
}
|
||||||
ENDPOINT_VULCAN_HEBE_HOMEWORK -> {
|
ENDPOINT_VULCAN_HEBE_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
VulcanHebeHomework(data, lastSync, onSuccess)
|
VulcanHebeHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
ENDPOINT_VULCAN_HEBE_NOTICES -> {
|
||||||
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
|
VulcanHebeNotices(data, lastSync, onSuccess)
|
||||||
|
}
|
||||||
|
ENDPOINT_VULCAN_HEBE_ATTENDANCE -> {
|
||||||
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
|
VulcanHebeAttendance(data, lastSync, onSuccess)
|
||||||
|
}
|
||||||
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX -> {
|
ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
||||||
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_RECEIVED)
|
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_RECEIVED)
|
||||||
@ -176,9 +142,9 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
||||||
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_SENT)
|
VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_SENT)
|
||||||
}
|
}
|
||||||
ENDPOINT_VULCAN_HEBE_ATTENDANCE -> {
|
ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
VulcanHebeAttendance(data, lastSync, onSuccess)
|
VulcanHebeLuckyNumber(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
else -> onSuccess(endpointId)
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-20.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -42,7 +46,11 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
val profile
|
val profile
|
||||||
get() = data.profile
|
get() = data.profile
|
||||||
|
|
||||||
fun getDateTime(json: JsonObject?, key: String, default: Long = System.currentTimeMillis()): Long {
|
fun getDateTime(
|
||||||
|
json: JsonObject?,
|
||||||
|
key: String,
|
||||||
|
default: Long = System.currentTimeMillis()
|
||||||
|
): Long {
|
||||||
val date = json.getJsonObject(key)
|
val date = json.getJsonObject(key)
|
||||||
return date.getLong("Timestamp") ?: return default
|
return date.getLong("Timestamp") ?: return default
|
||||||
}
|
}
|
||||||
@ -142,6 +150,18 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
2
|
2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isCurrentYear(date: Date): Boolean {
|
||||||
|
return profile?.let { profile ->
|
||||||
|
return@let date >= profile.dateSemester1Start
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isCurrentYear(dateTime: Long): Boolean {
|
||||||
|
return profile?.let { profile ->
|
||||||
|
return@let dateTime >= profile.dateSemester1Start.inMillis
|
||||||
|
} ?: false
|
||||||
|
}
|
||||||
|
|
||||||
inline fun <reified T> apiRequest(
|
inline fun <reified T> apiRequest(
|
||||||
tag: String,
|
tag: String,
|
||||||
endpoint: String,
|
endpoint: String,
|
||||||
@ -193,25 +213,54 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
val callback = object : JsonCallbackHandler() {
|
val callback = object : JsonCallbackHandler() {
|
||||||
override fun onSuccess(json: JsonObject?, response: Response?) {
|
override fun onSuccess(json: JsonObject?, response: Response?) {
|
||||||
if (json == null) {
|
if (json == null) {
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
data.error(
|
||||||
|
ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val status = json.getJsonObject("Status")
|
val status = json.getJsonObject("Status")
|
||||||
if (status?.getInt("Code") != 0) {
|
val statusCode = status?.getInt("Code") ?: 0
|
||||||
data.error(ApiError(tag, ERROR_VULCAN_HEBE_OTHER)
|
if (statusCode != 0) {
|
||||||
|
val statusMessage = status?.getString("Message")
|
||||||
|
val errorCode = when (statusCode) {
|
||||||
|
-1 -> ERROR_VULCAN_HEBE_SERVER_ERROR
|
||||||
|
100 -> ERROR_VULCAN_HEBE_SIGNATURE_ERROR
|
||||||
|
101 -> ERROR_VULCAN_HEBE_INVALID_PAYLOAD
|
||||||
|
106 -> ERROR_VULCAN_HEBE_FIREBASE_ERROR
|
||||||
|
108 -> ERROR_VULCAN_HEBE_CERTIFICATE_GONE
|
||||||
|
200 -> when (true) {
|
||||||
|
statusMessage?.contains("Class") -> ERROR_LOGIN_VULCAN_NO_PUPILS
|
||||||
|
statusMessage?.contains("Token") -> ERROR_LOGIN_VULCAN_INVALID_TOKEN
|
||||||
|
else -> ERROR_VULCAN_HEBE_ENTITY_NOT_FOUND
|
||||||
|
}
|
||||||
|
201 -> ERROR_LOGIN_VULCAN_EXPIRED_TOKEN
|
||||||
|
203 -> when (json.getJsonObject("Envelope").getInt("AvailableRetries")) {
|
||||||
|
2 -> ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING
|
||||||
|
1 -> ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING
|
||||||
|
else -> ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING
|
||||||
|
}
|
||||||
|
204 -> ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING
|
||||||
|
else -> ERROR_VULCAN_HEBE_OTHER
|
||||||
|
}
|
||||||
|
data.error(
|
||||||
|
ApiError(tag, errorCode)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
.withApiResponse(json.toString()))
|
.withApiResponse(json.toString())
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val envelope = when (T::class.java) {
|
val envelope = if (json.get("Envelope").isJsonNull && null is T)
|
||||||
|
null as T
|
||||||
|
else when (T::class.java) {
|
||||||
JsonObject::class.java -> json.getJsonObject("Envelope") as T
|
JsonObject::class.java -> json.getJsonObject("Envelope") as T
|
||||||
JsonArray::class.java -> json.getJsonArray("Envelope") as T
|
JsonArray::class.java -> json.getJsonArray("Envelope") as T
|
||||||
java.lang.Boolean::class.java -> json.getBoolean("Envelope") as T
|
java.lang.Boolean::class.java -> json.getBoolean("Envelope") as T
|
||||||
else -> {
|
else -> {
|
||||||
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
|
data.error(
|
||||||
|
ApiError(tag, ERROR_RESPONSE_EMPTY)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
.withApiResponse(json)
|
.withApiResponse(json)
|
||||||
)
|
)
|
||||||
@ -222,7 +271,8 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
try {
|
try {
|
||||||
onSuccess(envelope, response)
|
onSuccess(envelope, response)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
data.error(ApiError(tag, EXCEPTION_VULCAN_HEBE_REQUEST)
|
data.error(
|
||||||
|
ApiError(tag, EXCEPTION_VULCAN_HEBE_REQUEST)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
.withThrowable(e)
|
.withThrowable(e)
|
||||||
.withApiResponse(json)
|
.withApiResponse(json)
|
||||||
@ -231,7 +281,8 @@ 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?) {
|
||||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
data.error(
|
||||||
|
ApiError(tag, ERROR_REQUEST_FAILURE)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
.withThrowable(throwable)
|
.withThrowable(throwable)
|
||||||
)
|
)
|
||||||
@ -347,10 +398,15 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
if (folder != null)
|
if (folder != null)
|
||||||
query["folder"] = folder.toString()
|
query["folder"] = folder.toString()
|
||||||
|
|
||||||
|
val semester1Start = profile?.dateSemester1Start?.inMillis
|
||||||
|
|
||||||
query["lastId"] = "-2147483648" // don't ask, it's just Vulcan
|
query["lastId"] = "-2147483648" // don't ask, it's just Vulcan
|
||||||
query["pageSize"] = "500"
|
query["pageSize"] = "500"
|
||||||
query["lastSyncDate"] = LocalDateTime
|
query["lastSyncDate"] = LocalDateTime
|
||||||
.ofInstant(Instant.ofEpochMilli(lastSync ?: 0), ZoneId.systemDefault())
|
.ofInstant(
|
||||||
|
Instant.ofEpochMilli(lastSync ?: semester1Start ?: 0),
|
||||||
|
ZoneId.systemDefault()
|
||||||
|
)
|
||||||
.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) { json: JsonArray, response ->
|
||||||
|
@ -11,12 +11,11 @@ import im.wangchao.mhttp.Request
|
|||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import pl.droidsonroids.jspoon.Jspoon
|
import pl.droidsonroids.jspoon.Jspoon
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.CufsCertificate
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.CufsCertificate
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.isNotNullNorBlank
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -83,10 +82,12 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
onResult(symbol, STATE_NO_REGISTER)
|
onResult(symbol, STATE_NO_REGISTER)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!validateCallback(text, response, jsonResponse = false)) {
|
if (!validateCallback(symbol, text, response, jsonResponse = false)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.webExpiryTime = Date.fromIso(certificate.expiryDate) / 1000L
|
data.webExpiryTime = data.webExpiryTime.toMutableMap().also { map ->
|
||||||
|
map[symbol] = (Date.fromIso(certificate.expiryDate) / 1000L).toString()
|
||||||
|
}
|
||||||
onResult(symbol, STATE_SUCCESS)
|
onResult(symbol, STATE_SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
fun getStartPage(symbol: String = data.symbol ?: "default", postErrors: Boolean = true, onSuccess: (html: String, schoolSymbols: List<String>) -> Unit) {
|
fun getStartPage(symbol: String = data.symbol ?: "default", postErrors: Boolean = true, onSuccess: (html: String, schoolSymbols: List<String>) -> Unit) {
|
||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
override fun onSuccess(text: String?, response: Response?) {
|
||||||
if (!validateCallback(text, response, jsonResponse = false) || text == null) {
|
if (!validateCallback(symbol, text, response, jsonResponse = false) || text == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +137,30 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.webPermissions = Regexes.VULCAN_WEB_PERMISSIONS.find(text)?.let { it[1] }
|
data.webPermissions = data.webPermissions.toMutableMap().also { map ->
|
||||||
|
val permissions = Regexes.VULCAN_WEB_PERMISSIONS.find(text)?.let { it[1] }
|
||||||
|
if (permissions?.isNotBlank() == true) {
|
||||||
|
val studentId = permissions.split("|")
|
||||||
|
.getOrNull(0)
|
||||||
|
?.base64DecodeToString()
|
||||||
|
?.toJsonObject()
|
||||||
|
?.getJsonArray("AuthInfos")
|
||||||
|
?.asJsonObjectList()
|
||||||
|
?.flatMap { authInfo ->
|
||||||
|
authInfo.getJsonArray("UczenIds")
|
||||||
|
?.map { it.asInt }
|
||||||
|
?: listOf()
|
||||||
|
}
|
||||||
|
?.firstOrNull()
|
||||||
|
?.toString()
|
||||||
|
data.app.cookieJar.set(
|
||||||
|
data.webHost ?: "vulcan.net.pl",
|
||||||
|
"idBiezacyUczen",
|
||||||
|
studentId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
map[symbol] = permissions
|
||||||
|
}
|
||||||
|
|
||||||
val schoolSymbols = mutableListOf<String>()
|
val schoolSymbols = mutableListOf<String>()
|
||||||
val clientUrl = "://uonetplus-uczen.${data.webHost}/$symbol/"
|
val clientUrl = "://uonetplus-uczen.${data.webHost}/$symbol/"
|
||||||
@ -144,7 +168,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
var count = 0
|
var count = 0
|
||||||
while (clientIndex != -1 && count < 100) {
|
while (clientIndex != -1 && count < 100) {
|
||||||
val startIndex = clientIndex + clientUrl.length
|
val startIndex = clientIndex + clientUrl.length
|
||||||
val endIndex = text.indexOf('/', startIndex = startIndex)
|
val endIndex = text.indexOfAny(charArrayOf('"', '/'), startIndex = startIndex)
|
||||||
val schoolSymbol = text.substring(startIndex, endIndex)
|
val schoolSymbol = text.substring(startIndex, endIndex)
|
||||||
schoolSymbols += schoolSymbol
|
schoolSymbols += schoolSymbol
|
||||||
clientIndex = text.indexOf(clientUrl, startIndex = endIndex)
|
clientIndex = text.indexOf(clientUrl, startIndex = endIndex)
|
||||||
@ -186,7 +210,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateCallback(text: String?, response: Response?, jsonResponse: Boolean = true): Boolean {
|
private fun validateCallback(symbol: String, text: String?, response: Response?, jsonResponse: Boolean = true): Boolean {
|
||||||
if (text == null) {
|
if (text == null) {
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
||||||
.withResponse(response))
|
.withResponse(response))
|
||||||
@ -207,11 +231,13 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
|
|
||||||
val cookies = data.app.cookieJar.getAll(data.webHost ?: "vulcan.net.pl")
|
val cookies = data.app.cookieJar.getAll(data.webHost ?: "vulcan.net.pl")
|
||||||
val authCookie = cookies["EfebSsoAuthCookie"]
|
val authCookie = cookies["EfebSsoAuthCookie"]
|
||||||
if ((authCookie == null || authCookie == "null") && data.webAuthCookie != null) {
|
if ((authCookie == null || authCookie == "null") && data.webAuthCookie[symbol] != null) {
|
||||||
data.app.cookieJar.set(data.webHost ?: "vulcan.net.pl", "EfebSsoAuthCookie", data.webAuthCookie)
|
data.app.cookieJar.set(data.webHost ?: "vulcan.net.pl", "EfebSsoAuthCookie", data.webAuthCookie[symbol])
|
||||||
|
}
|
||||||
|
else if (authCookie.isNotNullNorBlank() && authCookie != "null" && authCookie != data.webAuthCookie[symbol]) {
|
||||||
|
data.webAuthCookie = data.webAuthCookie.toMutableMap().also { map ->
|
||||||
|
map[symbol] = authCookie
|
||||||
}
|
}
|
||||||
else if (authCookie.isNotNullNorBlank() && authCookie != "null" && authCookie != data.webAuthCookie) {
|
|
||||||
data.webAuthCookie = authCookie
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -250,7 +276,7 @@ open class VulcanWebMain(open val data: DataVulcan, open val lastSync: Long?) {
|
|||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
override fun onSuccess(text: String?, response: Response?) {
|
||||||
if (!validateCallback(text, response))
|
if (!validateCallback(data.symbol ?: "default", text, response))
|
||||||
return
|
return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -1,124 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2020-4-6.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.asJsonObjectList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.getLong
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
class VulcanApiAttachments(override val data: DataVulcan,
|
|
||||||
val list: List<*>,
|
|
||||||
val owner: Any?,
|
|
||||||
val ownerClass: KClass<*>,
|
|
||||||
val onSuccess: (list: List<*>) -> Unit
|
|
||||||
) : VulcanApi(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiAttachments"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
val endpoint = when (ownerClass) {
|
|
||||||
MessageFull::class -> VULCAN_API_ENDPOINT_MESSAGES_ATTACHMENTS
|
|
||||||
EventFull::class -> VULCAN_API_ENDPOINT_HOMEWORK_ATTACHMENTS
|
|
||||||
else -> null
|
|
||||||
} ?: return@run
|
|
||||||
|
|
||||||
val idName = when (ownerClass) {
|
|
||||||
MessageFull::class -> "IdWiadomosc"
|
|
||||||
EventFull::class -> "IdZadanieDomowe"
|
|
||||||
else -> null
|
|
||||||
} ?: return@run
|
|
||||||
|
|
||||||
val startDate = profile?.getSemesterStart(profile?.currentSemester ?: 1)?.inUnix ?: 0
|
|
||||||
val endDate = Date.getToday().stepForward(0, 1, 0).inUnix
|
|
||||||
|
|
||||||
apiGet(TAG, endpoint, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to startDate,
|
|
||||||
"DataKoncowa" to endDate,
|
|
||||||
"LoginId" to data.studentLoginId,
|
|
||||||
"IdUczen" to data.studentId
|
|
||||||
)) { json, _ ->
|
|
||||||
|
|
||||||
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { attachment ->
|
|
||||||
val id = attachment.getLong("Id") ?: return@forEach
|
|
||||||
val itemId = attachment.getLong(idName) ?: return@forEach
|
|
||||||
val url = attachment.getString("Url") ?: return@forEach
|
|
||||||
val fileName = "${attachment.getString("NazwaPliku")}:$url"
|
|
||||||
|
|
||||||
list.forEach {
|
|
||||||
if (it is MessageFull
|
|
||||||
&& it.profileId == profileId
|
|
||||||
&& it.id == itemId
|
|
||||||
&& it.attachmentIds?.contains(id) != true) {
|
|
||||||
if (it.attachmentIds == null)
|
|
||||||
it.attachmentIds = mutableListOf()
|
|
||||||
if (it.attachmentNames == null)
|
|
||||||
it.attachmentNames = mutableListOf()
|
|
||||||
it.attachmentIds?.add(id)
|
|
||||||
it.attachmentNames?.add(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it is EventFull
|
|
||||||
&& it.profileId == profileId
|
|
||||||
&& it.id == itemId
|
|
||||||
&& it.attachmentIds?.contains(id) != true) {
|
|
||||||
if (it.attachmentIds == null)
|
|
||||||
it.attachmentIds = mutableListOf()
|
|
||||||
if (it.attachmentNames == null)
|
|
||||||
it.attachmentNames = mutableListOf()
|
|
||||||
it.attachmentIds?.add(id)
|
|
||||||
it.attachmentNames?.add(fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (owner is MessageFull
|
|
||||||
&& it is MessageFull
|
|
||||||
&& owner.profileId == it.profileId
|
|
||||||
&& owner.id == it.id) {
|
|
||||||
owner.attachmentIds = it.attachmentIds
|
|
||||||
owner.attachmentNames = it.attachmentNames
|
|
||||||
}
|
|
||||||
|
|
||||||
if (owner is EventFull
|
|
||||||
&& it is EventFull
|
|
||||||
&& owner.profileId == it.profileId
|
|
||||||
&& owner.id == it.id) {
|
|
||||||
owner.attachmentIds = it.attachmentIds
|
|
||||||
owner.attachmentNames = it.attachmentNames
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (owner is MessageFull) {
|
|
||||||
list.forEach {
|
|
||||||
(it as? MessageFull)?.let { message ->
|
|
||||||
data.messageList.add(message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.messageListReplace = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (owner is EventFull) {
|
|
||||||
list.forEach {
|
|
||||||
(it as? EventFull)?.let { it1 ->
|
|
||||||
it1.homeworkBody = ""
|
|
||||||
data.eventList.add(it1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data.eventListReplace = true
|
|
||||||
}*/
|
|
||||||
|
|
||||||
onSuccess(list)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import androidx.core.util.isEmpty
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.Companion.TYPE_PRESENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class VulcanApiAttendance(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiAttendance"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
if (data.attendanceTypes.isEmpty()) {
|
|
||||||
data.db.attendanceTypeDao().getAllNow(profileId).toSparseArray(data.attendanceTypes) { it.id }
|
|
||||||
}
|
|
||||||
|
|
||||||
val semesterId = data.studentSemesterId
|
|
||||||
val semesterNumber = data.studentSemesterNumber
|
|
||||||
if (semesterNumber == 2 && lastSync ?: 0 < profile.dateSemester1Start.inMillis) {
|
|
||||||
getAttendance(profile, semesterId - 1, semesterNumber - 1) {
|
|
||||||
getAttendance(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
getAttendance(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_ATTENDANCE) }
|
|
||||||
|
|
||||||
private fun finish() {
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_ATTENDANCE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_ATTENDANCE)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAttendance(profile: Profile, semesterId: Int, semesterNumber: Int, onSuccess: () -> Unit) {
|
|
||||||
val startDate = profile.getSemesterStart(semesterNumber).stringY_m_d
|
|
||||||
val endDate = profile.getSemesterEnd(semesterNumber).stringY_m_d
|
|
||||||
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_ATTENDANCE, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to startDate,
|
|
||||||
"DataKoncowa" to endDate,
|
|
||||||
"IdOddzial" to data.studentClassId,
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOkresKlasyfikacyjny" to semesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
json.getJsonObject("Data")?.getJsonArray("Frekwencje")?.forEach { attendanceEl ->
|
|
||||||
val attendance = attendanceEl.asJsonObject
|
|
||||||
|
|
||||||
val type = data.attendanceTypes.get(attendance.getLong("IdKategoria") ?: return@forEach)
|
|
||||||
?: return@forEach
|
|
||||||
|
|
||||||
val id = (attendance.getInt("Dzien") ?: 0) + (attendance.getInt("Numer") ?: 0)
|
|
||||||
|
|
||||||
val lessonDateMillis = Date.fromY_m_d(attendance.getString("DzienTekst")).inMillis
|
|
||||||
val lessonDate = Date.fromMillis(lessonDateMillis)
|
|
||||||
val startTime = data.lessonRanges.get(attendance.getInt("Numer") ?: 0)?.startTime
|
|
||||||
|
|
||||||
val lessonSemester = semesterNumber
|
|
||||||
|
|
||||||
val attendanceObject = Attendance(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id.toLong(),
|
|
||||||
baseType = type.baseType,
|
|
||||||
typeName = type.typeName,
|
|
||||||
typeShort = type.typeShort,
|
|
||||||
typeSymbol = type.typeSymbol,
|
|
||||||
typeColor = type.typeColor,
|
|
||||||
date = lessonDate,
|
|
||||||
startTime = startTime,
|
|
||||||
semester = lessonSemester,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = attendance.getLong("IdPrzedmiot") ?: -1,
|
|
||||||
addedDate = lessonDate.combineWith(startTime)
|
|
||||||
).also {
|
|
||||||
it.lessonNumber = attendance.getInt("Numer")
|
|
||||||
it.isCounted = it.baseType != Attendance.TYPE_RELEASED
|
|
||||||
}
|
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
|
||||||
if (type.baseType != TYPE_PRESENT) {
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_ATTENDANCE,
|
|
||||||
attendanceObject.id,
|
|
||||||
profile.empty || type.baseType == Attendance.TYPE_PRESENT_CUSTOM || type.baseType == Attendance.TYPE_UNKNOWN,
|
|
||||||
profile.empty || type.baseType == Attendance.TYPE_PRESENT_CUSTOM || type.baseType == Attendance.TYPE_UNKNOWN
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-20
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_DICTIONARIES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_DICTIONARIES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
|
||||||
|
|
||||||
class VulcanApiDictionaries(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiDictionaries"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_DICTIONARIES) { json, _ ->
|
|
||||||
val elements = json.getJsonObject("Data")
|
|
||||||
|
|
||||||
elements?.getJsonArray("Pracownicy")?.forEach { saveTeacher(it.asJsonObject) }
|
|
||||||
elements?.getJsonArray("Przedmioty")?.forEach { saveSubject(it.asJsonObject) }
|
|
||||||
elements?.getJsonArray("PoryLekcji")?.forEach { saveLessonRange(it.asJsonObject) }
|
|
||||||
elements?.getJsonArray("KategorieOcen")?.forEach { saveGradeCategory(it.asJsonObject) }
|
|
||||||
elements?.getJsonArray("KategorieUwag")?.forEach { saveNoticeType(it.asJsonObject) }
|
|
||||||
elements?.getJsonArray("KategorieFrekwencji")?.forEach { saveAttendanceType(it.asJsonObject) }
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_DICTIONARIES, 4 * DAY)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_DICTIONARIES)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveTeacher(teacher: JsonObject) {
|
|
||||||
val id = teacher.getLong("Id") ?: return
|
|
||||||
val name = teacher.getString("Imie") ?: ""
|
|
||||||
val surname = teacher.getString("Nazwisko") ?: ""
|
|
||||||
val loginId = teacher.getString("LoginId") ?: "-1"
|
|
||||||
|
|
||||||
val teacherObject = Teacher(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
surname,
|
|
||||||
loginId
|
|
||||||
)
|
|
||||||
|
|
||||||
data.teacherList.put(id, teacherObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveSubject(subject: JsonObject) {
|
|
||||||
val id = subject.getLong("Id") ?: return
|
|
||||||
val longName = subject.getString("Nazwa") ?: ""
|
|
||||||
val shortName = subject.getString("Kod") ?: ""
|
|
||||||
|
|
||||||
val subjectObject = Subject(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
longName,
|
|
||||||
shortName
|
|
||||||
)
|
|
||||||
|
|
||||||
data.subjectList.put(id, subjectObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveLessonRange(lessonRange: JsonObject) {
|
|
||||||
val lessonNumber = lessonRange.getInt("Numer") ?: return
|
|
||||||
val startTime = lessonRange.getString("PoczatekTekst")?.let { Time.fromH_m(it) } ?: return
|
|
||||||
val endTime = lessonRange.getString("KoniecTekst")?.let { Time.fromH_m(it) } ?: return
|
|
||||||
|
|
||||||
val lessonRangeObject = LessonRange(
|
|
||||||
profileId,
|
|
||||||
lessonNumber,
|
|
||||||
startTime,
|
|
||||||
endTime
|
|
||||||
)
|
|
||||||
|
|
||||||
data.lessonRanges.put(lessonNumber, lessonRangeObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveGradeCategory(gradeCategory: JsonObject) {
|
|
||||||
val id = gradeCategory.getLong("Id") ?: return
|
|
||||||
val name = gradeCategory.getString("Nazwa") ?: ""
|
|
||||||
|
|
||||||
val gradeCategoryObject = GradeCategory(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
0.0f,
|
|
||||||
-1,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeCategories.put(id, gradeCategoryObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveNoticeType(noticeType: JsonObject) {
|
|
||||||
val id = noticeType.getLong("Id") ?: return
|
|
||||||
val name = noticeType.getString("Nazwa") ?: ""
|
|
||||||
|
|
||||||
val noticeTypeObject = NoticeType(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
name
|
|
||||||
)
|
|
||||||
|
|
||||||
data.noticeTypes.put(id, noticeTypeObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveAttendanceType(attendanceType: JsonObject) {
|
|
||||||
val id = attendanceType.getLong("Id") ?: return
|
|
||||||
val typeName = attendanceType.getString("Nazwa") ?: ""
|
|
||||||
|
|
||||||
val absent = attendanceType.getBoolean("Nieobecnosc") ?: false
|
|
||||||
val excused = attendanceType.getBoolean("Usprawiedliwione") ?: false
|
|
||||||
val baseType = if (absent) {
|
|
||||||
if (excused)
|
|
||||||
Attendance.TYPE_ABSENT_EXCUSED
|
|
||||||
else
|
|
||||||
Attendance.TYPE_ABSENT
|
|
||||||
} else {
|
|
||||||
val belated = attendanceType.getBoolean("Spoznienie") ?: false
|
|
||||||
val released = attendanceType.getBoolean("Zwolnienie") ?: false
|
|
||||||
val present = attendanceType.getBoolean("Obecnosc") ?: true
|
|
||||||
if (belated)
|
|
||||||
if (excused)
|
|
||||||
Attendance.TYPE_BELATED_EXCUSED
|
|
||||||
else
|
|
||||||
Attendance.TYPE_BELATED
|
|
||||||
else if (released)
|
|
||||||
Attendance.TYPE_RELEASED
|
|
||||||
else if (present)
|
|
||||||
Attendance.TYPE_PRESENT
|
|
||||||
else
|
|
||||||
Attendance.TYPE_UNKNOWN
|
|
||||||
}
|
|
||||||
|
|
||||||
val (typeColor, typeSymbol) = when (id.toInt()) {
|
|
||||||
1 -> 0xffffffff to "●" // obecność
|
|
||||||
2 -> 0xffffa687 to "—" // nieobecność
|
|
||||||
3 -> 0xfffcc150 to "u" // nieobecność usprawiedliwiona
|
|
||||||
4 -> 0xffede049 to "s" // spóźnienie
|
|
||||||
5 -> 0xffbbdd5f to "su" // spóźnienie usprawiedliwione
|
|
||||||
6 -> 0xffa9c9fd to "ns" // nieobecny z przyczyn szkolnych
|
|
||||||
7 -> 0xffddbbe5 to "z" // zwolniony
|
|
||||||
8 -> 0xffffffff to "" // usunięty wpis
|
|
||||||
else -> null to "?"
|
|
||||||
}
|
|
||||||
|
|
||||||
val typeShort = when (id.toInt()) {
|
|
||||||
6 -> "ns" // nieobecny z przyczyn szkolnych
|
|
||||||
8 -> "" // usunięty wpis
|
|
||||||
else -> data.app.attendanceManager.getTypeShort(baseType)
|
|
||||||
}
|
|
||||||
|
|
||||||
val attendanceTypeObject = AttendanceType(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
baseType,
|
|
||||||
typeName,
|
|
||||||
typeShort,
|
|
||||||
typeSymbol,
|
|
||||||
typeColor?.toInt()
|
|
||||||
)
|
|
||||||
|
|
||||||
data.attendanceTypes.put(id, attendanceTypeObject)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,133 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-20
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_EVENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_EVENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getBoolean
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.getLong
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class VulcanApiEvents(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
private val isHomework: Boolean,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiEvents"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val semesterId = data.studentSemesterId
|
|
||||||
val semesterNumber = data.studentSemesterNumber
|
|
||||||
if (semesterNumber == 2 && lastSync ?: 0 < profile.dateSemester1Start.inMillis) {
|
|
||||||
getEvents(profile, semesterId - 1, semesterNumber - 1) {
|
|
||||||
getEvents(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
getEvents(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} ?: onSuccess(if (isHomework) ENDPOINT_VULCAN_API_HOMEWORK else ENDPOINT_VULCAN_API_EVENTS) }
|
|
||||||
|
|
||||||
private fun finish() {
|
|
||||||
when (isHomework) {
|
|
||||||
true -> {
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_HOMEWORK, SYNC_ALWAYS)
|
|
||||||
}
|
|
||||||
false -> {
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_EVENTS, SYNC_ALWAYS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onSuccess(if (isHomework) ENDPOINT_VULCAN_API_HOMEWORK else ENDPOINT_VULCAN_API_EVENTS)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getEvents(profile: Profile, semesterId: Int, semesterNumber: Int, onSuccess: () -> Unit) {
|
|
||||||
val startDate = when (profile.empty) {
|
|
||||||
true -> profile.getSemesterStart(semesterNumber).stringY_m_d
|
|
||||||
else -> Date.getToday().stepForward(0, -1, 0).stringY_m_d
|
|
||||||
}
|
|
||||||
val endDate = profile.getSemesterEnd(semesterNumber).stringY_m_d
|
|
||||||
|
|
||||||
val endpoint = when (isHomework) {
|
|
||||||
true -> VULCAN_API_ENDPOINT_HOMEWORK
|
|
||||||
else -> VULCAN_API_ENDPOINT_EVENTS
|
|
||||||
}
|
|
||||||
apiGet(TAG, endpoint, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to startDate,
|
|
||||||
"DataKoncowa" to endDate,
|
|
||||||
"IdOddzial" to data.studentClassId,
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOkresKlasyfikacyjny" to semesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
val events = json.getJsonArray("Data")
|
|
||||||
|
|
||||||
events?.forEach { eventEl ->
|
|
||||||
val event = eventEl.asJsonObject
|
|
||||||
|
|
||||||
val id = event?.getLong("Id") ?: return@forEach
|
|
||||||
val eventDate = Date.fromY_m_d(event.getString("DataTekst") ?: return@forEach)
|
|
||||||
val subjectId = event.getLong("IdPrzedmiot") ?: -1
|
|
||||||
val teacherId = event.getLong("IdPracownik") ?: -1
|
|
||||||
val topic = event.getString("Opis")?.trim() ?: ""
|
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
|
||||||
|
|
||||||
val type = when (isHomework) {
|
|
||||||
true -> Event.TYPE_HOMEWORK
|
|
||||||
else -> when (event.getBoolean("Rodzaj")) {
|
|
||||||
false -> Event.TYPE_SHORT_QUIZ
|
|
||||||
else -> Event.TYPE_EXAM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val teamId = event.getLong("IdOddzial") ?: data.teamClass?.id ?: -1
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = eventDate,
|
|
||||||
time = startTime,
|
|
||||||
topic = topic,
|
|
||||||
color = null,
|
|
||||||
type = type,
|
|
||||||
teacherId = teacherId,
|
|
||||||
subjectId = subjectId,
|
|
||||||
teamId = teamId
|
|
||||||
)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
if (isHomework) Metadata.TYPE_HOMEWORK else Metadata.TYPE_EVENT,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-19
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import java.text.DecimalFormat
|
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class VulcanApiGrades(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiGrades"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val semesterId = data.studentSemesterId
|
|
||||||
val semesterNumber = data.studentSemesterNumber
|
|
||||||
if (semesterNumber == 2 && lastSync ?: 0 < profile.dateSemester1Start.inMillis) {
|
|
||||||
getGrades(profile, semesterId - 1, semesterNumber - 1) {
|
|
||||||
getGrades(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
getGrades(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_GRADES) }
|
|
||||||
|
|
||||||
private fun finish() {
|
|
||||||
data.toRemove.add(DataRemoveModel.Grades.semesterWithType(data.studentSemesterNumber, TYPE_NORMAL))
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_GRADES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_GRADES)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGrades(profile: Profile, semesterId: Int, semesterNumber: Int, onSuccess: () -> Unit) {
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_GRADES, parameters = mapOf(
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOkresKlasyfikacyjny" to semesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
val grades = json.getJsonArray("Data")
|
|
||||||
|
|
||||||
grades?.forEach { gradeEl ->
|
|
||||||
val grade = gradeEl.asJsonObject
|
|
||||||
|
|
||||||
val id = grade.getLong("Id") ?: return@forEach
|
|
||||||
val categoryId = grade.getLong("IdKategoria") ?: -1
|
|
||||||
val category = data.gradeCategories.singleOrNull{ it.categoryId == categoryId }?.text
|
|
||||||
?: ""
|
|
||||||
val teacherId = grade.getLong("IdPracownikD") ?: -1
|
|
||||||
val subjectId = grade.getLong("IdPrzedmiot") ?: -1
|
|
||||||
val description = grade.getString("Opis")
|
|
||||||
val comment = grade.getString("Komentarz")
|
|
||||||
var value = grade.getFloat("Wartosc")
|
|
||||||
var weight = grade.getFloat("WagaOceny") ?: 0.0f
|
|
||||||
val modificatorValue = grade.getFloat("WagaModyfikatora")
|
|
||||||
val numerator = grade.getFloat("Licznik")
|
|
||||||
val denominator = grade.getFloat("Mianownik")
|
|
||||||
val addedDate = (grade.getLong("DataModyfikacji") ?: return@forEach) * 1000
|
|
||||||
|
|
||||||
var finalDescription = ""
|
|
||||||
|
|
||||||
var name = when (numerator != null && denominator != null) {
|
|
||||||
true -> {
|
|
||||||
value = numerator / denominator
|
|
||||||
finalDescription += DecimalFormat("#.##").format(numerator) +
|
|
||||||
"/" + DecimalFormat("#.##").format(denominator)
|
|
||||||
weight = 0.0f
|
|
||||||
(value * 100).roundToInt().toString() + "%"
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (value != null) modificatorValue?.also { value += it }
|
|
||||||
else weight = 0.0f
|
|
||||||
|
|
||||||
grade.getString("Wpis") ?: ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comment?.also {
|
|
||||||
if (name == "") name = it
|
|
||||||
else finalDescription = (if (finalDescription == "") "" else " ") + it
|
|
||||||
}
|
|
||||||
|
|
||||||
description?.also {
|
|
||||||
finalDescription = (if (finalDescription == "") "" else " - ") + it
|
|
||||||
}
|
|
||||||
|
|
||||||
val color = when (name) {
|
|
||||||
"1-", "1", "1+" -> 0xffd65757
|
|
||||||
"2-", "2", "2+" -> 0xff9071b3
|
|
||||||
"3-", "3", "3+" -> 0xffd2ab24
|
|
||||||
"4-", "4", "4+" -> 0xff50b6d6
|
|
||||||
"5-", "5", "5+" -> 0xff2cbd92
|
|
||||||
"6-", "6", "6+" -> 0xff91b43c
|
|
||||||
else -> 0xff3D5F9C
|
|
||||||
}.toInt()
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
name = name,
|
|
||||||
type = TYPE_NORMAL,
|
|
||||||
value = value ?: 0.0f,
|
|
||||||
weight = weight,
|
|
||||||
color = color,
|
|
||||||
category = category,
|
|
||||||
description = finalDescription,
|
|
||||||
comment = null,
|
|
||||||
semester = semesterNumber,
|
|
||||||
teacherId = teacherId,
|
|
||||||
subjectId = subjectId,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-12
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
|
||||||
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.full.MessageFull
|
|
||||||
|
|
||||||
class VulcanApiMessagesChangeStatus(override val data: DataVulcan,
|
|
||||||
private val messageObject: MessageFull,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : VulcanApi(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiMessagesChangeStatus"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_MESSAGES_CHANGE_STATUS, parameters = mapOf(
|
|
||||||
"WiadomoscId" to messageObject.id,
|
|
||||||
"FolderWiadomosci" to "Odebrane",
|
|
||||||
"Status" to "Widoczna",
|
|
||||||
"LoginId" to data.studentLoginId,
|
|
||||||
"IdUczen" to data.studentId
|
|
||||||
)) { _, _ ->
|
|
||||||
|
|
||||||
if (!messageObject.seen) {
|
|
||||||
data.setSeenMetadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_MESSAGE,
|
|
||||||
messageObject.id,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
))
|
|
||||||
|
|
||||||
messageObject.seen = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (messageObject.type != TYPE_SENT) {
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
|
||||||
profileId,
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
System.currentTimeMillis(),
|
|
||||||
messageObject.id
|
|
||||||
)
|
|
||||||
|
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(MessageGetEvent(messageObject))
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-01
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_RECEIVED
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_INBOX
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import kotlin.text.replace
|
|
||||||
|
|
||||||
class VulcanApiMessagesInbox(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiMessagesInbox"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val startDate = when (profile.empty) {
|
|
||||||
true -> profile.getSemesterStart(profile.currentSemester).inUnix
|
|
||||||
else -> Date.getToday().stepForward(0, -2, 0).inUnix
|
|
||||||
}
|
|
||||||
val endDate = Date.getToday().stepForward(0, 1, 0).inUnix
|
|
||||||
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_MESSAGES_RECEIVED, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to startDate,
|
|
||||||
"DataKoncowa" to endDate,
|
|
||||||
"LoginId" to data.studentLoginId,
|
|
||||||
"IdUczen" to data.studentId
|
|
||||||
)) { json, _ ->
|
|
||||||
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { message ->
|
|
||||||
val id = message.getLong("WiadomoscId") ?: return@forEach
|
|
||||||
val subject = message.getString("Tytul") ?: ""
|
|
||||||
val body = message.getString("Tresc") ?: ""
|
|
||||||
|
|
||||||
val senderLoginId = message.getString("NadawcaId") ?: return@forEach
|
|
||||||
val senderId = data.teacherList.singleOrNull { it.loginId == senderLoginId }?.id ?: {
|
|
||||||
|
|
||||||
val senderName = message.getString("Nadawca") ?: ""
|
|
||||||
|
|
||||||
senderName.splitName()?.let { (senderLastName, senderFirstName) ->
|
|
||||||
val teacherObject = Teacher(
|
|
||||||
profileId,
|
|
||||||
-1 * Utils.crc16(senderName.toByteArray()).toLong(),
|
|
||||||
senderFirstName,
|
|
||||||
senderLastName,
|
|
||||||
senderLoginId
|
|
||||||
)
|
|
||||||
data.teacherList.put(teacherObject.id, teacherObject)
|
|
||||||
teacherObject.id
|
|
||||||
}
|
|
||||||
}.invoke()
|
|
||||||
|
|
||||||
val sentDate = message.getLong("DataWyslaniaUnixEpoch")?.let { it * 1000 }
|
|
||||||
?: -1
|
|
||||||
val readDate = message.getLong("DataPrzeczytaniaUnixEpoch")?.let { it * 1000 }
|
|
||||||
?: -1
|
|
||||||
|
|
||||||
val messageObject = Message(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
type = TYPE_RECEIVED,
|
|
||||||
subject = subject,
|
|
||||||
body = body.replace("\n", "<br>"),
|
|
||||||
senderId = senderId,
|
|
||||||
addedDate = sentDate
|
|
||||||
)
|
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
|
||||||
profileId,
|
|
||||||
-1,
|
|
||||||
-1,
|
|
||||||
readDate,
|
|
||||||
id
|
|
||||||
)
|
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
|
||||||
data.setSeenMetadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_MESSAGE,
|
|
||||||
id,
|
|
||||||
readDate > 0,
|
|
||||||
readDate > 0
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_MESSAGES_INBOX)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_MESSAGES_INBOX)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-5
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_SENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_MESSAGES_SENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
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.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import kotlin.text.replace
|
|
||||||
|
|
||||||
class VulcanApiMessagesSent(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiMessagesSent"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val startDate = when (profile.empty) {
|
|
||||||
true -> profile.getSemesterStart(profile.currentSemester).inUnix
|
|
||||||
else -> Date.getToday().stepForward(0, -2, 0).inUnix
|
|
||||||
}
|
|
||||||
val endDate = Date.getToday().stepForward(0, 1, 0).inUnix
|
|
||||||
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_MESSAGES_SENT, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to startDate,
|
|
||||||
"DataKoncowa" to endDate,
|
|
||||||
"LoginId" to data.studentLoginId,
|
|
||||||
"IdUczen" to data.studentId
|
|
||||||
)) { json, _ ->
|
|
||||||
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { message ->
|
|
||||||
val id = message.getLong("WiadomoscId") ?: return@forEach
|
|
||||||
val subject = message.getString("Tytul") ?: ""
|
|
||||||
val body = message.getString("Tresc") ?: ""
|
|
||||||
val readBy = message.getInt("Przeczytane") ?: 0
|
|
||||||
val unreadBy = message.getInt("Nieprzeczytane") ?: 0
|
|
||||||
val sentDate = message.getLong("DataWyslaniaUnixEpoch")?.let { it * 1000 } ?: -1
|
|
||||||
|
|
||||||
message.getJsonArray("Adresaci")?.asJsonObjectList()
|
|
||||||
?.onEach { receiver ->
|
|
||||||
|
|
||||||
val receiverLoginId = receiver.getString("LoginId")
|
|
||||||
?: return@onEach
|
|
||||||
val receiverId = data.teacherList.singleOrNull { it.loginId == receiverLoginId }?.id
|
|
||||||
?: {
|
|
||||||
val receiverName = receiver.getString("Nazwa") ?: ""
|
|
||||||
|
|
||||||
receiverName.splitName()?.let { (receiverLastName, receiverFirstName) ->
|
|
||||||
val teacherObject = Teacher(
|
|
||||||
profileId,
|
|
||||||
-1 * Utils.crc16(receiverName.toByteArray()).toLong(),
|
|
||||||
receiverFirstName,
|
|
||||||
receiverLastName,
|
|
||||||
receiverLoginId
|
|
||||||
)
|
|
||||||
data.teacherList.put(teacherObject.id, teacherObject)
|
|
||||||
teacherObject.id
|
|
||||||
}
|
|
||||||
}.invoke() ?: -1
|
|
||||||
|
|
||||||
val readDate: Long = when (readBy) {
|
|
||||||
0 -> 0
|
|
||||||
else -> when (unreadBy) {
|
|
||||||
0 -> 1
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val messageRecipientObject = MessageRecipient(
|
|
||||||
profileId,
|
|
||||||
receiverId,
|
|
||||||
-1,
|
|
||||||
readDate,
|
|
||||||
id
|
|
||||||
)
|
|
||||||
|
|
||||||
data.messageRecipientList.add(messageRecipientObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
val messageObject = Message(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
type = TYPE_SENT,
|
|
||||||
subject = subject,
|
|
||||||
body = body.replace("\n", "<br>"),
|
|
||||||
senderId = null,
|
|
||||||
addedDate = sentDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
|
||||||
data.setSeenMetadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_MESSAGE,
|
|
||||||
id,
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_MESSAGES_SENT, 1 * DAY, DRAWER_ITEM_MESSAGES)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_MESSAGES_SENT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-23
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import androidx.core.util.isEmpty
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_NOTICES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_NOTICES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.getLong
|
|
||||||
import pl.szczodrzynski.edziennik.getString
|
|
||||||
import pl.szczodrzynski.edziennik.toSparseArray
|
|
||||||
|
|
||||||
class VulcanApiNotices(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiNotices"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
if (data.noticeTypes.isEmpty()) {
|
|
||||||
data.db.noticeTypeDao().getAllNow(profileId).toSparseArray(data.noticeTypes) { it.id }
|
|
||||||
}
|
|
||||||
|
|
||||||
val semesterId = data.studentSemesterId
|
|
||||||
val semesterNumber = data.studentSemesterNumber
|
|
||||||
if (semesterNumber == 2 && lastSync ?: 0 < profile.dateSemester1Start.inMillis) {
|
|
||||||
getNotices(profile, semesterId - 1, semesterNumber - 1) {
|
|
||||||
getNotices(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
getNotices(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_NOTICES) }
|
|
||||||
|
|
||||||
private fun finish() {
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_NOTICES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_NOTICES)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getNotices(profile: Profile, semesterId: Int, semesterNumber: Int, onSuccess: () -> Unit) {
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_NOTICES, parameters = mapOf(
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOkresKlasyfikacyjny" to data.studentSemesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
json.getJsonArray("Data")?.forEach { noticeEl ->
|
|
||||||
val notice = noticeEl.asJsonObject
|
|
||||||
|
|
||||||
val id = notice.getLong("Id") ?: return@forEach
|
|
||||||
val text = notice.getString("TrescUwagi") ?: return@forEach
|
|
||||||
val teacherId = notice.getLong("IdPracownik") ?: -1
|
|
||||||
val addedDate = notice.getLong("DataModyfikacji")?.times(1000) ?: System.currentTimeMillis()
|
|
||||||
|
|
||||||
val categoryId = notice.getLong("IdKategoriaUwag") ?: -1
|
|
||||||
val categoryText = data.noticeTypes[categoryId]?.name ?: ""
|
|
||||||
|
|
||||||
val noticeObject = Notice(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
type = Notice.TYPE_NEUTRAL,
|
|
||||||
semester = profile.currentSemester,
|
|
||||||
text = text,
|
|
||||||
category = categoryText,
|
|
||||||
points = null,
|
|
||||||
teacherId = teacherId,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.noticeList.add(noticeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_NOTICE,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.HOUR
|
|
||||||
import pl.szczodrzynski.edziennik.asJsonObjectList
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_GRADES_PROPOSITIONS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_GRADES_SUMMARY
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
|
|
||||||
class VulcanApiProposedGrades(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiProposedGrades"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val semesterId = data.studentSemesterId
|
|
||||||
val semesterNumber = data.studentSemesterNumber
|
|
||||||
if (semesterNumber == 2 && lastSync ?: 0 < profile.dateSemester1Start.inMillis) {
|
|
||||||
getProposedGrades(profile, semesterId - 1, semesterNumber - 1) {
|
|
||||||
getProposedGrades(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
getProposedGrades(profile, semesterId, semesterNumber) {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_GRADES_SUMMARY) }
|
|
||||||
|
|
||||||
private fun finish() {
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_GRADES_SUMMARY, 6*HOUR)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_GRADES_SUMMARY)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getProposedGrades(profile: Profile, semesterId: Int, semesterNumber: Int, onSuccess: () -> Unit) {
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_GRADES_PROPOSITIONS, parameters = mapOf(
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOkresKlasyfikacyjny" to semesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
val grades = json.getJsonObject("Data")
|
|
||||||
|
|
||||||
grades.getJsonArray("OcenyPrzewidywane")?.let {
|
|
||||||
processGradeList(it, semesterNumber, isFinal = false)
|
|
||||||
}
|
|
||||||
|
|
||||||
grades.getJsonArray("OcenyKlasyfikacyjne")?.let {
|
|
||||||
processGradeList(it, semesterNumber, isFinal = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processGradeList(grades: JsonArray, semesterNumber: Int, isFinal: Boolean) {
|
|
||||||
grades.asJsonObjectList().forEach { grade ->
|
|
||||||
val name = grade.get("Wpis").asString
|
|
||||||
val value = Utils.getGradeValue(name)
|
|
||||||
val subjectId = grade.get("IdPrzedmiot").asLong
|
|
||||||
|
|
||||||
val id = subjectId * -100 - semesterNumber
|
|
||||||
|
|
||||||
val color = Utils.getVulcanGradeColor(name)
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
name = name,
|
|
||||||
type = if (semesterNumber == 1) {
|
|
||||||
if (isFinal) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER1_PROPOSED
|
|
||||||
} else {
|
|
||||||
if (isFinal) TYPE_SEMESTER2_FINAL else TYPE_SEMESTER2_PROPOSED
|
|
||||||
},
|
|
||||||
value = value,
|
|
||||||
weight = 0f,
|
|
||||||
color = color,
|
|
||||||
category = "",
|
|
||||||
description = null,
|
|
||||||
comment = null,
|
|
||||||
semester = semesterNumber,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subjectId
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
gradeObject.id,
|
|
||||||
data.profile?.empty ?: false,
|
|
||||||
data.profile?.empty ?: false
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2020-2-20.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_PUSH
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_PUSH_CONFIG
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
|
|
||||||
class VulcanApiPushConfig(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiPushConfig"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.app.config.sync.tokenVulcan?.also { tokenVulcan ->
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_PUSH, parameters = mapOf(
|
|
||||||
"Token" to tokenVulcan,
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"PushOcena" to true,
|
|
||||||
"PushFrekwencja" to true,
|
|
||||||
"PushUwaga" to true,
|
|
||||||
"PushWiadomosc" to true
|
|
||||||
)) { _, _ ->
|
|
||||||
// sync always: this endpoint has .shouldSync set
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_PUSH_CONFIG, SYNC_ALWAYS)
|
|
||||||
data.app.config.sync.tokenVulcanList =
|
|
||||||
data.app.config.sync.tokenVulcanList + profileId
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_PUSH_CONFIG)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_PUSH_CONFIG) }
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-12-29.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_MESSAGES_ADD
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
|
|
||||||
class VulcanApiSendMessage(override val data: DataVulcan,
|
|
||||||
val recipients: List<Teacher>,
|
|
||||||
val subject: String,
|
|
||||||
val text: String,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : VulcanApi(data, null) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "VulcanApiSendMessage"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
val recipientsArray = JsonArray()
|
|
||||||
for (teacher in recipients) {
|
|
||||||
teacher.loginId?.let {
|
|
||||||
recipientsArray += JsonObject(
|
|
||||||
"LoginId" to it,
|
|
||||||
"Nazwa" to "${teacher.fullNameLastFirst} - pracownik"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val params = mapOf(
|
|
||||||
"NadawcaWiadomosci" to (profile?.accountName ?: profile?.studentNameLong ?: ""),
|
|
||||||
"Tytul" to subject,
|
|
||||||
"Tresc" to text,
|
|
||||||
"Adresaci" to recipientsArray,
|
|
||||||
"LoginId" to data.studentLoginId,
|
|
||||||
"IdUczen" to data.studentId
|
|
||||||
)
|
|
||||||
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_MESSAGES_ADD, parameters = params) { json, _ ->
|
|
||||||
val messageId = json.getJsonObject("Data").getLong("WiadomoscId")
|
|
||||||
|
|
||||||
if (messageId == null) {
|
|
||||||
// TODO error
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
VulcanApiMessagesSent(data, null) {
|
|
||||||
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
|
|
||||||
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(event)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-10-20
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
|
|
||||||
class VulcanApiTemplate(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApi"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
/* data.profile?.also { profile ->
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_) { json, _ ->
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_, SYNC_ALWAYS)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-11-13
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import androidx.core.util.set
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.VULCAN_SHIFT_ANNOTATION
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.*
|
|
||||||
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,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiTimetable"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
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 weekStart = Date.fromY_m_d(getDate)
|
|
||||||
val weekEnd = weekStart.clone().stepForward(0, 0, 6)
|
|
||||||
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_TIMETABLE, parameters = mapOf(
|
|
||||||
"DataPoczatkowa" to weekStart.stringY_m_d,
|
|
||||||
"DataKoncowa" to weekEnd.stringY_m_d,
|
|
||||||
"IdUczen" to data.studentId,
|
|
||||||
"IdOddzial" to data.studentClassId,
|
|
||||||
"IdOkresKlasyfikacyjny" to data.studentSemesterId
|
|
||||||
)) { json, _ ->
|
|
||||||
val dates = mutableSetOf<Int>()
|
|
||||||
val lessons = mutableListOf<Lesson>()
|
|
||||||
|
|
||||||
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson ->
|
|
||||||
if (lesson.getBoolean("PlanUcznia") != true)
|
|
||||||
return@forEach
|
|
||||||
val lessonDate = Date.fromY_m_d(lesson.getString("DzienTekst"))
|
|
||||||
val lessonNumber = lesson.getInt("NumerLekcji")
|
|
||||||
val lessonRange = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }
|
|
||||||
val startTime = lessonRange?.startTime
|
|
||||||
val endTime = lessonRange?.endTime
|
|
||||||
val teacherId = lesson.getLong("IdPracownik")
|
|
||||||
val classroom = lesson.getString("Sala")
|
|
||||||
|
|
||||||
val oldTeacherId = lesson.getLong("IdPracownikOld")
|
|
||||||
|
|
||||||
val changeAnnotation = lesson.getString("AdnotacjaOZmianie") ?: ""
|
|
||||||
val type = when {
|
|
||||||
changeAnnotation.startsWith("(przeniesiona z") -> Lesson.TYPE_SHIFTED_TARGET
|
|
||||||
changeAnnotation.startsWith("(przeniesiona na") -> Lesson.TYPE_SHIFTED_SOURCE
|
|
||||||
changeAnnotation.startsWith("(zastępstwo") -> Lesson.TYPE_CHANGE
|
|
||||||
lesson.getBoolean("PrzekreslonaNazwa") == true -> Lesson.TYPE_CANCELLED
|
|
||||||
else -> Lesson.TYPE_NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
val teamId = lesson.getString("PodzialSkrot")?.let { teamName ->
|
|
||||||
val name = "${data.teamClass?.name} $teamName"
|
|
||||||
val id = name.crc16().toLong()
|
|
||||||
var team = data.teamList.singleOrNull { it.name == name }
|
|
||||||
if (team == null) {
|
|
||||||
team = Team(
|
|
||||||
profileId,
|
|
||||||
id,
|
|
||||||
name,
|
|
||||||
Team.TYPE_VIRTUAL,
|
|
||||||
"${data.schoolCode}:$name",
|
|
||||||
teacherId ?: oldTeacherId ?: -1
|
|
||||||
)
|
|
||||||
data.teamList[id] = team
|
|
||||||
}
|
|
||||||
team.id
|
|
||||||
} ?: data.teamClass?.id ?: -1
|
|
||||||
|
|
||||||
val subjectId = lesson.getLong("IdPrzedmiot").let { id ->
|
|
||||||
// get the specified subject name
|
|
||||||
val subjectName = lesson.getString("PrzedmiotNazwa") ?: ""
|
|
||||||
|
|
||||||
val condition = when (id) {
|
|
||||||
// "special" subject - e.g. one time classes, a trip, etc.
|
|
||||||
0L -> { subject: Subject -> subject.longName == subjectName }
|
|
||||||
// normal subject, check if it exists
|
|
||||||
else -> { subject: Subject -> subject.id == id }
|
|
||||||
}
|
|
||||||
|
|
||||||
data.subjectList.singleOrNull(condition)?.id ?: {
|
|
||||||
/**
|
|
||||||
* CREATE A NEW SUBJECT IF IT DOESN'T EXIST
|
|
||||||
*/
|
|
||||||
|
|
||||||
val subjectObject = Subject(
|
|
||||||
profileId,
|
|
||||||
if (id == null || id == 0L)
|
|
||||||
-1 * crc16(subjectName.toByteArray()).toLong()
|
|
||||||
else
|
|
||||||
id,
|
|
||||||
subjectName,
|
|
||||||
subjectName
|
|
||||||
)
|
|
||||||
data.subjectList.put(subjectObject.id, subjectObject)
|
|
||||||
subjectObject.id
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
val lessonObject = Lesson(profileId, -1).apply {
|
|
||||||
this.type = type
|
|
||||||
|
|
||||||
when (type) {
|
|
||||||
Lesson.TYPE_NORMAL, Lesson.TYPE_CHANGE, Lesson.TYPE_SHIFTED_TARGET -> {
|
|
||||||
this.date = lessonDate
|
|
||||||
this.lessonNumber = lessonNumber
|
|
||||||
this.startTime = startTime
|
|
||||||
this.endTime = endTime
|
|
||||||
this.subjectId = subjectId
|
|
||||||
this.teacherId = teacherId
|
|
||||||
this.teamId = teamId
|
|
||||||
this.classroom = classroom
|
|
||||||
|
|
||||||
this.oldTeacherId = oldTeacherId
|
|
||||||
}
|
|
||||||
|
|
||||||
Lesson.TYPE_CANCELLED, Lesson.TYPE_SHIFTED_SOURCE -> {
|
|
||||||
this.oldDate = lessonDate
|
|
||||||
this.oldLessonNumber = lessonNumber
|
|
||||||
this.oldStartTime = startTime
|
|
||||||
this.oldEndTime = endTime
|
|
||||||
this.oldSubjectId = subjectId
|
|
||||||
this.oldTeacherId = teacherId
|
|
||||||
this.oldTeamId = teamId
|
|
||||||
this.oldClassroom = classroom
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Lesson.TYPE_SHIFTED_SOURCE || type == Lesson.TYPE_SHIFTED_TARGET) {
|
|
||||||
val shift = VULCAN_SHIFT_ANNOTATION.find(changeAnnotation)
|
|
||||||
val oldLessonNumber = shift?.get(2)?.toInt()
|
|
||||||
val oldLessonDate = shift?.get(3)?.let { Date.fromd_m_Y(it) }
|
|
||||||
|
|
||||||
val oldLessonRange = data.lessonRanges.singleOrNull { it.lessonNumber == oldLessonNumber }
|
|
||||||
val oldStartTime = oldLessonRange?.startTime
|
|
||||||
val oldEndTime = oldLessonRange?.endTime
|
|
||||||
|
|
||||||
when (type) {
|
|
||||||
Lesson.TYPE_SHIFTED_SOURCE -> {
|
|
||||||
this.lessonNumber = oldLessonNumber
|
|
||||||
this.date = oldLessonDate
|
|
||||||
this.startTime = oldStartTime
|
|
||||||
this.endTime = oldEndTime
|
|
||||||
}
|
|
||||||
|
|
||||||
Lesson.TYPE_SHIFTED_TARGET -> {
|
|
||||||
this.oldLessonNumber = oldLessonNumber
|
|
||||||
this.oldDate = oldLessonDate
|
|
||||||
this.oldStartTime = oldStartTime
|
|
||||||
this.oldEndTime = oldEndTime
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.id = buildId()
|
|
||||||
}
|
|
||||||
|
|
||||||
val seen = profile.empty || lessonDate < Date.getToday()
|
|
||||||
|
|
||||||
if (type != Lesson.TYPE_NORMAL) {
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_LESSON_CHANGE,
|
|
||||||
lessonObject.id,
|
|
||||||
seen,
|
|
||||||
seen
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
dates.add(lessonDate.value)
|
|
||||||
lessons.add(lessonObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
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.lessonList.addAll(lessons)
|
|
||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_TIMETABLE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_TIMETABLE)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2020-2-1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_NO_STUDENTS_IN_ACCOUNT
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_API_ENDPOINT_STUDENT_LIST
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_API_UPDATE_SEMESTER
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class VulcanApiUpdateSemester(override val data: DataVulcan,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : VulcanApi(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "VulcanApiUpdateSemester"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
apiGet(TAG, VULCAN_API_ENDPOINT_STUDENT_LIST, baseUrl = true) { json, response ->
|
|
||||||
val students = json.getJsonArray("Data")
|
|
||||||
|
|
||||||
if (students == null || students.isEmpty()) {
|
|
||||||
data.error(ApiError(TAG, ERROR_NO_STUDENTS_IN_ACCOUNT)
|
|
||||||
.withResponse(response)
|
|
||||||
.withApiResponse(json))
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
students.asJsonObjectList().firstOrNull {
|
|
||||||
it.getInt("Id") == data.studentId
|
|
||||||
}?.let { student ->
|
|
||||||
val studentClassId = student.getInt("IdOddzial") ?: return@let
|
|
||||||
val studentClassName = student.getString("OkresPoziom").toString() + (student.getString("OddzialSymbol") ?: return@let)
|
|
||||||
val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny") ?: return@let
|
|
||||||
|
|
||||||
val currentSemesterStartDate = student.getLong("OkresDataOd") ?: return@let
|
|
||||||
val currentSemesterEndDate = (student.getLong("OkresDataDo") ?: return@let) + 86400
|
|
||||||
val studentSemesterNumber = student.getInt("OkresNumer") ?: return@let
|
|
||||||
|
|
||||||
var dateSemester1Start: Date? = null
|
|
||||||
var dateSemester2Start: Date? = null
|
|
||||||
var dateYearEnd: Date? = null
|
|
||||||
when (studentSemesterNumber) {
|
|
||||||
1 -> {
|
|
||||||
dateSemester1Start = Date.fromMillis(currentSemesterStartDate * 1000)
|
|
||||||
dateSemester2Start = Date.fromMillis(currentSemesterEndDate * 1000)
|
|
||||||
}
|
|
||||||
2 -> {
|
|
||||||
dateSemester2Start = Date.fromMillis(currentSemesterStartDate * 1000)
|
|
||||||
dateYearEnd = Date.fromMillis(currentSemesterEndDate * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.studentClassId = studentClassId
|
|
||||||
data.studentSemesterId = studentSemesterId
|
|
||||||
data.studentSemesterNumber = studentSemesterNumber
|
|
||||||
data.profile.studentData["semester${studentSemesterNumber}Id"] = studentSemesterId
|
|
||||||
data.currentSemesterEndDate = currentSemesterEndDate
|
|
||||||
profile.studentClassName = studentClassName
|
|
||||||
dateSemester1Start?.let {
|
|
||||||
profile.dateSemester1Start = it
|
|
||||||
profile.studentSchoolYearStart = it.year
|
|
||||||
}
|
|
||||||
dateSemester2Start?.let { profile.dateSemester2Start = it }
|
|
||||||
dateYearEnd?.let { profile.dateYearEnd = it }
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_VULCAN_API_UPDATE_SEMESTER, if (data.studentSemesterNumber == 2) 7*DAY else 2*DAY)
|
|
||||||
onSuccess(ENDPOINT_VULCAN_API_UPDATE_SEMESTER)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_VULCAN_API_UPDATE_SEMESTER) }
|
|
||||||
}
|
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-20.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
enum class HebeFilterType(val endpoint: String) {
|
enum class HebeFilterType(val endpoint: String) {
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import androidx.core.util.set
|
import androidx.core.util.set
|
||||||
|
@ -85,6 +85,7 @@ class VulcanHebeAttendance(
|
|||||||
subjectId = subjectId,
|
subjectId = subjectId,
|
||||||
addedDate = addedDate
|
addedDate = addedDate
|
||||||
).also {
|
).also {
|
||||||
|
it.lessonTopic = attendance.getString("Topic")
|
||||||
it.lessonNumber = lessonNumber
|
it.lessonNumber = lessonNumber
|
||||||
it.isCounted = isCounted
|
it.isCounted = isCounted
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
@ -36,6 +40,8 @@ class VulcanHebeExams(
|
|||||||
?: -1
|
?: -1
|
||||||
val topic = exam.getString("Content")?.trim() ?: ""
|
val topic = exam.getString("Content")?.trim() ?: ""
|
||||||
|
|
||||||
|
if (!isCurrentYear(eventDate)) return@forEach
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
|
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.DAY
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
|
||||||
|
class VulcanHebeGradeSummary(
|
||||||
|
override val data: DataVulcan,
|
||||||
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : VulcanHebe(data, lastSync) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanHebeGradeSummary"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val entries = mapOf(
|
||||||
|
"Entry_1" to
|
||||||
|
if (data.studentSemesterNumber == 1)
|
||||||
|
Grade.TYPE_SEMESTER1_PROPOSED
|
||||||
|
else Grade.TYPE_SEMESTER2_PROPOSED,
|
||||||
|
"Entry_2" to
|
||||||
|
if (data.studentSemesterNumber == 1)
|
||||||
|
Grade.TYPE_SEMESTER1_FINAL
|
||||||
|
else Grade.TYPE_SEMESTER2_FINAL
|
||||||
|
)
|
||||||
|
|
||||||
|
apiGetList(
|
||||||
|
TAG,
|
||||||
|
VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY,
|
||||||
|
HebeFilterType.BY_PUPIL,
|
||||||
|
lastSync = lastSync
|
||||||
|
) { list, _ ->
|
||||||
|
list.forEach { grade ->
|
||||||
|
val subjectId = getSubjectId(grade, "Subject") ?: return@forEach
|
||||||
|
val addedDate = getDateTime(grade, "DateModify")
|
||||||
|
|
||||||
|
entries.onEach { (key, type) ->
|
||||||
|
val id = subjectId * -100 - type
|
||||||
|
val entry = grade.getString(key) ?: return@onEach
|
||||||
|
val value = Utils.getGradeValue(entry)
|
||||||
|
val color = Utils.getVulcanGradeColor(entry)
|
||||||
|
|
||||||
|
val gradeObject = Grade(
|
||||||
|
profileId = profileId,
|
||||||
|
id = id,
|
||||||
|
name = entry,
|
||||||
|
type = type,
|
||||||
|
value = value,
|
||||||
|
weight = 0f,
|
||||||
|
color = color,
|
||||||
|
category = "",
|
||||||
|
description = null,
|
||||||
|
comment = null,
|
||||||
|
semester = data.studentSemesterNumber,
|
||||||
|
teacherId = -1,
|
||||||
|
subjectId = subjectId,
|
||||||
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
|
data.gradeList.add(gradeObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_GRADE,
|
||||||
|
id,
|
||||||
|
profile?.empty ?: true,
|
||||||
|
profile?.empty ?: true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setSyncNext(ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY, 1 * DAY)
|
||||||
|
onSuccess(ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-20.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.asJsonObjectList
|
||||||
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_HOMEWORK
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_HOMEWORK
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_HOMEWORK
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_HOMEWORK
|
||||||
@ -7,8 +12,10 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
import pl.szczodrzynski.edziennik.getJsonArray
|
||||||
import pl.szczodrzynski.edziennik.getLong
|
import pl.szczodrzynski.edziennik.getLong
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
|
||||||
class VulcanHebeHomework(
|
class VulcanHebeHomework(
|
||||||
override val data: DataVulcan,
|
override val data: DataVulcan,
|
||||||
@ -34,6 +41,8 @@ class VulcanHebeHomework(
|
|||||||
val teamId = data.teamClass?.id ?: -1
|
val teamId = data.teamClass?.id ?: -1
|
||||||
val topic = exam.getString("Content")?.trim() ?: ""
|
val topic = exam.getString("Content")?.trim() ?: ""
|
||||||
|
|
||||||
|
if (!isCurrentYear(eventDate)) return@forEach
|
||||||
|
|
||||||
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
val lessonList = data.db.timetableDao().getAllForDateNow(profileId, eventDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
|
|
||||||
@ -50,6 +59,22 @@ class VulcanHebeHomework(
|
|||||||
teamId = teamId
|
teamId = teamId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val attachments = exam.getJsonArray("Attachments")
|
||||||
|
?.asJsonObjectList()
|
||||||
|
?: return@forEach
|
||||||
|
|
||||||
|
for (attachment in attachments) {
|
||||||
|
val fileName = attachment.getString("Name") ?: continue
|
||||||
|
val url = attachment.getString("Link") ?: continue
|
||||||
|
val attachmentName = "$fileName:$url"
|
||||||
|
val attachmentId = Utils.crc32(attachmentName.toByteArray())
|
||||||
|
|
||||||
|
eventObject.addAttachment(
|
||||||
|
id = attachmentId,
|
||||||
|
name = attachmentName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
data.eventList.add(eventObject)
|
||||||
data.metadataList.add(
|
data.metadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
import pl.szczodrzynski.edziennik.getInt
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
|
class VulcanHebeLuckyNumber(
|
||||||
|
override val data: DataVulcan,
|
||||||
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : VulcanHebe(data, lastSync) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanHebeLuckyNumber"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
apiGet(
|
||||||
|
TAG,
|
||||||
|
VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER,
|
||||||
|
query = mapOf(
|
||||||
|
"constituentId" to data.studentConstituentId.toString(),
|
||||||
|
"day" to Date.getToday().stringY_m_d
|
||||||
|
)
|
||||||
|
) { lucky: JsonObject?, _ ->
|
||||||
|
// sync tomorrow if lucky number set or is weekend or afternoon
|
||||||
|
var nextSync = Date.getToday().stepForward(0, 0, 1).inMillis
|
||||||
|
if (lucky == null) {
|
||||||
|
if (Date.getToday().weekDay <= Week.FRIDAY && Time.getNow().hour < 12) {
|
||||||
|
// working days morning, sync always
|
||||||
|
nextSync = SYNC_ALWAYS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val luckyNumberDate = Date.fromY_m_d(lucky.getString("Day")) ?: Date.getToday()
|
||||||
|
val luckyNumber = lucky.getInt("Number") ?: -1
|
||||||
|
val luckyNumberObject = LuckyNumber(
|
||||||
|
profileId = profileId,
|
||||||
|
date = luckyNumberDate,
|
||||||
|
number = luckyNumber
|
||||||
|
)
|
||||||
|
|
||||||
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
|
luckyNumberObject.date.value.toLong(),
|
||||||
|
true,
|
||||||
|
profile?.empty ?: false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setSyncNext(ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER, syncAt = nextSync)
|
||||||
|
onSuccess(ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-20.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import androidx.core.util.set
|
import androidx.core.util.set
|
||||||
@ -13,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.*
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED
|
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_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.navlib.crc16
|
import pl.szczodrzynski.navlib.crc16
|
||||||
import kotlin.text.replace
|
import kotlin.text.replace
|
||||||
|
|
||||||
@ -76,6 +81,8 @@ class VulcanHebeMessages(
|
|||||||
val sentDate = getDateTime(message, "DateSent")
|
val sentDate = getDateTime(message, "DateSent")
|
||||||
val readDate = getDateTime(message, "DateRead", default = 0)
|
val readDate = getDateTime(message, "DateRead", default = 0)
|
||||||
|
|
||||||
|
if (!isCurrentYear(sentDate)) return@forEach
|
||||||
|
|
||||||
val messageObject = Message(
|
val messageObject = Message(
|
||||||
profileId = profileId,
|
profileId = profileId,
|
||||||
id = id,
|
id = id,
|
||||||
@ -104,6 +111,23 @@ class VulcanHebeMessages(
|
|||||||
data.messageRecipientList.add(messageRecipientObject)
|
data.messageRecipientList.add(messageRecipientObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val attachments = message.getJsonArray("Attachments")
|
||||||
|
?.asJsonObjectList()
|
||||||
|
?: return@forEach
|
||||||
|
|
||||||
|
for (attachment in attachments) {
|
||||||
|
val fileName = attachment.getString("Name") ?: continue
|
||||||
|
val url = attachment.getString("Link") ?: continue
|
||||||
|
val attachmentName = "$fileName:$url"
|
||||||
|
val attachmentId = Utils.crc32(attachmentName.toByteArray())
|
||||||
|
|
||||||
|
messageObject.addAttachment(
|
||||||
|
id = attachmentId,
|
||||||
|
name = attachmentName,
|
||||||
|
size = -1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
data.messageList.add(messageObject)
|
data.messageList.add(messageObject)
|
||||||
data.setSeenMetadataList.add(
|
data.setSeenMetadataList.add(
|
||||||
Metadata(
|
Metadata(
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kacper Ziubryniewicz 2021-2-22
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_NOTICES
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_NOTICES
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
|
||||||
|
class VulcanHebeNotices(
|
||||||
|
override val data: DataVulcan,
|
||||||
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : VulcanHebe(data, lastSync) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanHebeNotices"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
apiGetList(
|
||||||
|
TAG,
|
||||||
|
VULCAN_HEBE_ENDPOINT_NOTICES,
|
||||||
|
HebeFilterType.BY_PUPIL,
|
||||||
|
lastSync = lastSync
|
||||||
|
) { list, _ ->
|
||||||
|
list.forEach { notice ->
|
||||||
|
val id = notice.getLong("Id") ?: return@forEach
|
||||||
|
val type = when (notice.getBoolean("Positive")) {
|
||||||
|
true -> Notice.TYPE_POSITIVE
|
||||||
|
else -> Notice.TYPE_NEUTRAL
|
||||||
|
}
|
||||||
|
val date = getDate(notice, "DateValid") ?: return@forEach
|
||||||
|
val semester = profile?.dateToSemester(date) ?: return@forEach
|
||||||
|
val text = notice.getString("Content") ?: ""
|
||||||
|
val category = notice.getJsonObject("Category")?.getString("Name")
|
||||||
|
val points = notice.getFloat("Points")
|
||||||
|
val teacherId = getTeacherId(notice, "Creator") ?: -1
|
||||||
|
val addedDate = getDateTime(notice, "DateModify")
|
||||||
|
|
||||||
|
if (!isCurrentYear(date)) return@forEach
|
||||||
|
|
||||||
|
val noticeObject = Notice(
|
||||||
|
profileId = profileId,
|
||||||
|
id = id,
|
||||||
|
type = type,
|
||||||
|
semester = semester,
|
||||||
|
text = text,
|
||||||
|
category = category,
|
||||||
|
points = points,
|
||||||
|
teacherId = teacherId,
|
||||||
|
addedDate = addedDate
|
||||||
|
)
|
||||||
|
|
||||||
|
data.noticeList.add(noticeObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_NOTICE,
|
||||||
|
id,
|
||||||
|
profile?.empty ?: true,
|
||||||
|
profile?.empty ?: true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.setSyncNext(ENDPOINT_VULCAN_HEBE_NOTICES, SYNC_ALWAYS)
|
||||||
|
onSuccess(ENDPOINT_VULCAN_HEBE_NOTICES)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import com.google.gson.JsonPrimitive
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_PUSH_ALL
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_PUSH_CONFIG
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
|
||||||
|
class VulcanHebePushConfig(
|
||||||
|
override val data: DataVulcan,
|
||||||
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : VulcanHebe(data, lastSync) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanHebePushConfig"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
apiPost(
|
||||||
|
TAG,
|
||||||
|
VULCAN_HEBE_ENDPOINT_PUSH_ALL,
|
||||||
|
payload = JsonPrimitive("on")
|
||||||
|
) { _: Boolean, _ ->
|
||||||
|
// sync always: this endpoint has .shouldSync set
|
||||||
|
data.setSyncNext(ENDPOINT_VULCAN_HEBE_PUSH_CONFIG, SYNC_ALWAYS)
|
||||||
|
data.app.config.sync.tokenVulcanList =
|
||||||
|
data.app.config.sync.tokenVulcanList + profileId
|
||||||
|
onSuccess(ENDPOINT_VULCAN_HEBE_PUSH_CONFIG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-22.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_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.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
|
||||||
|
class VulcanHebeSendMessage(
|
||||||
|
override val data: DataVulcan,
|
||||||
|
val recipients: List<Teacher>,
|
||||||
|
val subject: String,
|
||||||
|
val text: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : VulcanHebe(data, null) {
|
||||||
|
companion object {
|
||||||
|
const val TAG = "VulcanHebeSendMessage"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val recipientsArray = JsonArray()
|
||||||
|
recipients.forEach { teacher ->
|
||||||
|
recipientsArray += JsonObject(
|
||||||
|
"Address" to teacher.fullNameLastFirst,
|
||||||
|
"LoginId" to (teacher.loginId?.toIntOrNull() ?: return@forEach),
|
||||||
|
"Initials" to teacher.initialsLastFirst,
|
||||||
|
"AddressHash" to teacher.fullNameLastFirst.sha1Hex()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val senderName = (profile?.accountName ?: profile?.studentNameLong)
|
||||||
|
?.swapFirstLastName() ?: ""
|
||||||
|
val sender = JsonObject(
|
||||||
|
"Address" to senderName,
|
||||||
|
"LoginId" to data.studentLoginId.toString(),
|
||||||
|
"Initials" to senderName.getNameInitials(),
|
||||||
|
"AddressHash" to senderName.sha1Hex()
|
||||||
|
)
|
||||||
|
|
||||||
|
apiPost(
|
||||||
|
TAG,
|
||||||
|
VULCAN_HEBE_ENDPOINT_MESSAGES_SEND,
|
||||||
|
payload = JsonObject(
|
||||||
|
"Status" to 1,
|
||||||
|
"Sender" to sender,
|
||||||
|
"DateSent" to null,
|
||||||
|
"DateRead" to null,
|
||||||
|
"Content" to text,
|
||||||
|
"Receiver" to recipientsArray,
|
||||||
|
"Id" to 0,
|
||||||
|
"Subject" to subject,
|
||||||
|
"Attachments" to null,
|
||||||
|
"Self" to null
|
||||||
|
)
|
||||||
|
) { json: JsonObject, _ ->
|
||||||
|
val messageId = json.getLong("Id")
|
||||||
|
|
||||||
|
if (messageId == null) {
|
||||||
|
// TODO error
|
||||||
|
return@apiPost
|
||||||
|
}
|
||||||
|
|
||||||
|
VulcanHebeMessages(data, null) {
|
||||||
|
val message = data.messageList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == messageId }
|
||||||
|
val event = MessageSentEvent(data.profileId, message, message?.addedDate)
|
||||||
|
|
||||||
|
EventBus.getDefault().postSticky(event)
|
||||||
|
onSuccess()
|
||||||
|
}.getMessages(Message.TYPE_SENT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
@ -8,25 +8,21 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanWebMain
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanWebMain
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.VulcanHebeMain
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.VulcanHebeMain
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.CufsCertificate
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.CufsCertificate
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginApi
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginHebe
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login.VulcanLoginWebMain
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
|
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
|
class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "VulcanFirstLogin"
|
const val TAG = "VulcanFirstLogin"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val api = VulcanApi(data, null)
|
|
||||||
private val web = VulcanWebMain(data, null)
|
private val web = VulcanWebMain(data, null)
|
||||||
private val hebe = VulcanHebe(data, null)
|
private val hebe = VulcanHebe(data, null)
|
||||||
private val profileList = mutableListOf<Profile>()
|
private val profileList = mutableListOf<Profile>()
|
||||||
@ -54,12 +50,6 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
checkSymbol(certificate)
|
checkSymbol(certificate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (data.loginStore.mode == LOGIN_MODE_VULCAN_API) {
|
|
||||||
registerDevice {
|
|
||||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
registerDeviceHebe {
|
registerDeviceHebe {
|
||||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
||||||
@ -118,96 +108,6 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerDevice(onSuccess: () -> Unit) {
|
|
||||||
VulcanLoginApi(data) {
|
|
||||||
api.apiGet(TAG, VULCAN_API_ENDPOINT_STUDENT_LIST, baseUrl = true) { json, _ ->
|
|
||||||
val students = json.getJsonArray("Data")
|
|
||||||
|
|
||||||
if (students == null || students.isEmpty()) {
|
|
||||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(listOf(), data.loginStore))
|
|
||||||
onSuccess()
|
|
||||||
return@apiGet
|
|
||||||
}
|
|
||||||
|
|
||||||
students.forEach { studentEl ->
|
|
||||||
val student = studentEl.asJsonObject
|
|
||||||
|
|
||||||
val schoolSymbol = student.getString("JednostkaSprawozdawczaSymbol") ?: return@forEach
|
|
||||||
val schoolShort = student.getString("JednostkaSprawozdawczaSkrot") ?: return@forEach
|
|
||||||
val schoolCode = "${data.symbol}_$schoolSymbol"
|
|
||||||
val studentId = student.getInt("Id") ?: return@forEach
|
|
||||||
val studentLoginId = student.getInt("UzytkownikLoginId") ?: return@forEach
|
|
||||||
val studentClassId = student.getInt("IdOddzial") ?: return@forEach
|
|
||||||
val studentClassName = student.getString("OkresPoziom").toString() + (student.getString("OddzialSymbol") ?: return@forEach)
|
|
||||||
val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny") ?: return@forEach
|
|
||||||
val studentFirstName = student.getString("Imie") ?: ""
|
|
||||||
val studentLastName = student.getString("Nazwisko") ?: ""
|
|
||||||
val studentNameLong = "$studentFirstName $studentLastName".fixName()
|
|
||||||
val studentNameShort = "$studentFirstName ${studentLastName[0]}.".fixName()
|
|
||||||
|
|
||||||
val userLogin = student.getString("UzytkownikLogin") ?: ""
|
|
||||||
val currentSemesterStartDate = student.getLong("OkresDataOd") ?: return@forEach
|
|
||||||
val currentSemesterEndDate = (student.getLong("OkresDataDo") ?: return@forEach) + 86400
|
|
||||||
val studentSemesterNumber = student.getInt("OkresNumer") ?: return@forEach
|
|
||||||
|
|
||||||
val isParent = student.getString("UzytkownikRola") == "opiekun"
|
|
||||||
val accountName = if (isParent)
|
|
||||||
student.getString("UzytkownikNazwa")?.swapFirstLastName()?.fixName()
|
|
||||||
else null
|
|
||||||
|
|
||||||
var dateSemester1Start: Date? = null
|
|
||||||
var dateSemester2Start: Date? = null
|
|
||||||
var dateYearEnd: Date? = null
|
|
||||||
when (studentSemesterNumber) {
|
|
||||||
1 -> {
|
|
||||||
dateSemester1Start = Date.fromMillis(currentSemesterStartDate * 1000)
|
|
||||||
dateSemester2Start = Date.fromMillis(currentSemesterEndDate * 1000)
|
|
||||||
}
|
|
||||||
2 -> {
|
|
||||||
dateSemester2Start = Date.fromMillis(currentSemesterStartDate * 1000)
|
|
||||||
dateYearEnd = Date.fromMillis(currentSemesterEndDate * 1000)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val profile = Profile(
|
|
||||||
firstProfileId++,
|
|
||||||
loginStoreId,
|
|
||||||
LOGIN_TYPE_VULCAN,
|
|
||||||
studentNameLong,
|
|
||||||
userLogin,
|
|
||||||
studentNameLong,
|
|
||||||
studentNameShort,
|
|
||||||
accountName
|
|
||||||
).apply {
|
|
||||||
this.studentClassName = studentClassName
|
|
||||||
studentData["symbol"] = data.symbol
|
|
||||||
|
|
||||||
studentData["studentId"] = studentId
|
|
||||||
studentData["studentLoginId"] = studentLoginId
|
|
||||||
studentData["studentClassId"] = studentClassId
|
|
||||||
studentData["studentSemesterId"] = studentSemesterId
|
|
||||||
studentData["studentSemesterNumber"] = studentSemesterNumber
|
|
||||||
studentData["semester${studentSemesterNumber}Id"] = studentSemesterId
|
|
||||||
studentData["schoolSymbol"] = schoolSymbol
|
|
||||||
studentData["schoolShort"] = schoolShort
|
|
||||||
studentData["schoolName"] = schoolCode
|
|
||||||
studentData["currentSemesterEndDate"] = currentSemesterEndDate
|
|
||||||
}
|
|
||||||
dateSemester1Start?.let {
|
|
||||||
profile.dateSemester1Start = it
|
|
||||||
profile.studentSchoolYearStart = it.year
|
|
||||||
}
|
|
||||||
dateSemester2Start?.let { profile.dateSemester2Start = it }
|
|
||||||
dateYearEnd?.let { profile.dateYearEnd = it }
|
|
||||||
|
|
||||||
profileList.add(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun registerDeviceHebe(onSuccess: () -> Unit) {
|
private fun registerDeviceHebe(onSuccess: () -> Unit) {
|
||||||
VulcanLoginHebe(data) {
|
VulcanLoginHebe(data) {
|
||||||
VulcanHebeMain(data).getStudents(
|
VulcanHebeMain(data).getStudents(
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_API
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_HEBE
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_HEBE
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_WEB_MAIN
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_VULCAN_WEB_MAIN
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan
|
||||||
@ -51,10 +50,6 @@ class VulcanLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
data.startProgress(R.string.edziennik_progress_login_vulcan_web_main)
|
data.startProgress(R.string.edziennik_progress_login_vulcan_web_main)
|
||||||
VulcanLoginWebMain(data) { onSuccess(loginMethodId) }
|
VulcanLoginWebMain(data) { onSuccess(loginMethodId) }
|
||||||
}
|
}
|
||||||
LOGIN_METHOD_VULCAN_API -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_login_vulcan_api)
|
|
||||||
VulcanLoginApi(data) { onSuccess(loginMethodId) }
|
|
||||||
}
|
|
||||||
LOGIN_METHOD_VULCAN_HEBE -> {
|
LOGIN_METHOD_VULCAN_HEBE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_login_vulcan_api)
|
data.startProgress(R.string.edziennik_progress_login_vulcan_api)
|
||||||
VulcanLoginHebe(data) { onSuccess(loginMethodId) }
|
VulcanLoginHebe(data) { onSuccess(loginMethodId) }
|
||||||
|
@ -1,226 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-10-6.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import im.wangchao.mhttp.Request
|
|
||||||
import im.wangchao.mhttp.Response
|
|
||||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|
||||||
import io.github.wulkanowy.signer.android.getPrivateKeyFromCert
|
|
||||||
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.api.VulcanApiUpdateSemester
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import java.net.HttpURLConnection.HTTP_BAD_REQUEST
|
|
||||||
import java.util.*
|
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "VulcanLoginApi"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (data.studentSemesterNumber == 1 && data.semester1Id == 0)
|
|
||||||
data.semester1Id = data.studentSemesterNumber
|
|
||||||
if (data.studentSemesterNumber == 2 && data.semester2Id == 0)
|
|
||||||
data.semester2Id = data.studentSemesterNumber
|
|
||||||
|
|
||||||
copyFromLoginStore()
|
|
||||||
|
|
||||||
if (data.profile != null && data.isApiLoginValid()) {
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (data.apiFingerprint[data.symbol].isNotNullNorEmpty()
|
|
||||||
&& data.apiPrivateKey[data.symbol].isNotNullNorEmpty()
|
|
||||||
&& data.symbol.isNotNullNorEmpty()) {
|
|
||||||
// (see data.isApiLoginValid())
|
|
||||||
// the semester end date is over
|
|
||||||
VulcanApiUpdateSemester(data, null) { onSuccess() }
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.symbol.isNotNullNorEmpty() && data.apiToken[data.symbol].isNotNullNorEmpty() && data.apiPin[data.symbol].isNotNullNorEmpty()) {
|
|
||||||
loginWithToken()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun copyFromLoginStore() {
|
|
||||||
data.loginStore.data.apply {
|
|
||||||
// < v4.0 - PFX to Private Key migration
|
|
||||||
if (has("certificatePfx")) {
|
|
||||||
try {
|
|
||||||
val privateKey = getPrivateKeyFromCert(
|
|
||||||
if (data.apiToken[data.symbol]?.get(0) == 'F') VULCAN_API_PASSWORD_FAKELOG else VULCAN_API_PASSWORD,
|
|
||||||
getString("certificatePfx") ?: ""
|
|
||||||
)
|
|
||||||
data.apiPrivateKey = mapOf(
|
|
||||||
data.symbol to privateKey
|
|
||||||
)
|
|
||||||
remove("certificatePfx")
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4.0 - new login form - copy user input to profile
|
|
||||||
if (has("symbol")) {
|
|
||||||
data.symbol = getString("symbol")
|
|
||||||
remove("symbol")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4.0 - before Vulcan Web impl - migrate from strings to Map of Symbol to String
|
|
||||||
if (has("deviceSymbol")) {
|
|
||||||
data.symbol = getString("deviceSymbol")
|
|
||||||
remove("deviceSymbol")
|
|
||||||
}
|
|
||||||
if (has("certificateKey")) {
|
|
||||||
data.apiFingerprint = data.apiFingerprint.toMutableMap().also {
|
|
||||||
it[data.symbol] = getString("certificateKey")
|
|
||||||
}
|
|
||||||
remove("certificateKey")
|
|
||||||
}
|
|
||||||
if (has("certificatePrivate")) {
|
|
||||||
data.apiPrivateKey = data.apiPrivateKey.toMutableMap().also {
|
|
||||||
it[data.symbol] = getString("certificatePrivate")
|
|
||||||
}
|
|
||||||
remove("certificatePrivate")
|
|
||||||
}
|
|
||||||
|
|
||||||
// map form inputs to the symbol
|
|
||||||
if (has("deviceToken")) {
|
|
||||||
data.apiToken = data.apiToken.toMutableMap().also {
|
|
||||||
it[data.symbol] = getString("deviceToken")
|
|
||||||
}
|
|
||||||
remove("deviceToken")
|
|
||||||
}
|
|
||||||
if (has("devicePin")) {
|
|
||||||
data.apiPin = data.apiPin.toMutableMap().also {
|
|
||||||
it[data.symbol] = getString("devicePin")
|
|
||||||
}
|
|
||||||
remove("devicePin")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loginWithToken() {
|
|
||||||
d(TAG, "Request: Vulcan/Login/Api - ${data.apiUrl}/$VULCAN_API_ENDPOINT_CERTIFICATE")
|
|
||||||
|
|
||||||
val callback = object : JsonCallbackHandler() {
|
|
||||||
override fun onSuccess(json: JsonObject?, response: Response?) {
|
|
||||||
if (json == null) {
|
|
||||||
if (response?.code() == HTTP_BAD_REQUEST) {
|
|
||||||
data.error(TAG, ERROR_LOGIN_VULCAN_INVALID_SYMBOL, response)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var tokenStatus = json.getString("TokenStatus")
|
|
||||||
if (tokenStatus == "Null" || tokenStatus == "CertGenerated")
|
|
||||||
tokenStatus = null
|
|
||||||
val error = tokenStatus ?: json.getString("Message")
|
|
||||||
error?.let { code ->
|
|
||||||
when (code) {
|
|
||||||
"TokenNotFound" -> ERROR_LOGIN_VULCAN_INVALID_TOKEN
|
|
||||||
"TokenDead" -> ERROR_LOGIN_VULCAN_EXPIRED_TOKEN
|
|
||||||
"WrongPIN" -> {
|
|
||||||
Pattern.compile("Liczba pozostałych prób: ([0-9])", Pattern.DOTALL).matcher(tokenStatus).let { matcher ->
|
|
||||||
if (matcher.matches())
|
|
||||||
ERROR_LOGIN_VULCAN_INVALID_PIN + 1 + matcher.group(1).toInt()
|
|
||||||
else
|
|
||||||
ERROR_LOGIN_VULCAN_INVALID_PIN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"Broken" -> ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING
|
|
||||||
"OnlyKindergarten" -> ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN
|
|
||||||
"NoPupils" -> ERROR_LOGIN_VULCAN_NO_PUPILS
|
|
||||||
else -> ERROR_LOGIN_VULCAN_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(json)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val cert = json.getJsonObject("TokenCert")
|
|
||||||
if (cert == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_VULCAN_OTHER)
|
|
||||||
.withApiResponse(json)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val privateKey = getPrivateKeyFromCert(
|
|
||||||
if (data.apiToken[data.symbol]?.get(0) == 'F') VULCAN_API_PASSWORD_FAKELOG else VULCAN_API_PASSWORD,
|
|
||||||
cert.getString("CertyfikatPfx") ?: ""
|
|
||||||
)
|
|
||||||
|
|
||||||
data.apiFingerprint = data.apiFingerprint.toMutableMap().also {
|
|
||||||
it[data.symbol] = cert.getString("CertyfikatKlucz")
|
|
||||||
}
|
|
||||||
data.apiToken = data.apiToken.toMutableMap().also {
|
|
||||||
it[data.symbol] = it[data.symbol]?.substring(0, 3)
|
|
||||||
}
|
|
||||||
data.apiPrivateKey = data.apiPrivateKey.toMutableMap().also {
|
|
||||||
it[data.symbol] = privateKey
|
|
||||||
}
|
|
||||||
data.loginStore.removeLoginData("certificatePfx")
|
|
||||||
data.loginStore.removeLoginData("apiPin")
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val szkolnyApi = SzkolnyApi(data.app)
|
|
||||||
val firebaseToken = szkolnyApi.runCatching({
|
|
||||||
getFirebaseToken("vulcan")
|
|
||||||
}, onError = {
|
|
||||||
// screw errors
|
|
||||||
}) ?: data.app.config.sync.tokenVulcan
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("${data.apiUrl}$VULCAN_API_ENDPOINT_CERTIFICATE")
|
|
||||||
.userAgent(VULCAN_API_USER_AGENT)
|
|
||||||
.addHeader("RequestMobileType", "RegisterDevice")
|
|
||||||
.addParameter("PIN", data.apiPin[data.symbol])
|
|
||||||
.addParameter("TokenKey", data.apiToken[data.symbol])
|
|
||||||
.addParameter("DeviceId", data.buildDeviceId())
|
|
||||||
.addParameter("DeviceName", VULCAN_API_DEVICE_NAME)
|
|
||||||
.addParameter("DeviceNameUser", "")
|
|
||||||
.addParameter("DeviceDescription", "")
|
|
||||||
.addParameter("DeviceSystemType", "Android")
|
|
||||||
.addParameter("DeviceSystemVersion", Build.VERSION.RELEASE)
|
|
||||||
.addParameter("RemoteMobileTimeKey", currentTimeUnix())
|
|
||||||
.addParameter("TimeKey", currentTimeUnix() - 1)
|
|
||||||
.addParameter("RequestId", UUID.randomUUID().toString())
|
|
||||||
.addParameter("AppVersion", VULCAN_API_APP_VERSION)
|
|
||||||
.addParameter("RemoteMobileAppVersion", VULCAN_API_APP_VERSION)
|
|
||||||
.addParameter("RemoteMobileAppName", VULCAN_API_APP_NAME)
|
|
||||||
.addParameter("FirebaseTokenKey", firebaseToken ?: "")
|
|
||||||
.postJson()
|
|
||||||
.allowErrorCode(HTTP_BAD_REQUEST)
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-20.
|
||||||
|
*/
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
|
package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.login
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
@ -28,7 +32,7 @@ class VulcanLoginHebe(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
|
|
||||||
copyFromLoginStore()
|
copyFromLoginStore()
|
||||||
|
|
||||||
if (data.profile != null && data.isApiLoginValid()) {
|
if (data.profile != null && data.isHebeLoginValid()) {
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.getString
|
|||||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.fslogin.FSLogin
|
import pl.szczodrzynski.fslogin.FSLogin
|
||||||
import pl.szczodrzynski.fslogin.realm.CufsRealm
|
import pl.szczodrzynski.fslogin.realm.toRealm
|
||||||
|
|
||||||
class VulcanLoginWebMain(val data: DataVulcan, val onSuccess: () -> Unit) {
|
class VulcanLoginWebMain(val data: DataVulcan, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -30,8 +30,7 @@ class VulcanLoginWebMain(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (data.symbol.isNotNullNorEmpty()
|
if (data.symbol.isNotNullNorEmpty()
|
||||||
&& data.webType.isNotNullNorEmpty()
|
&& data.webRealmData != null
|
||||||
&& data.webHost.isNotNullNorEmpty()
|
|
||||||
&& (data.webEmail.isNotNullNorEmpty() || data.webUsername.isNotNullNorEmpty())
|
&& (data.webEmail.isNotNullNorEmpty() || data.webUsername.isNotNullNorEmpty())
|
||||||
&& data.webPassword.isNotNullNorEmpty()) {
|
&& data.webPassword.isNotNullNorEmpty()) {
|
||||||
try {
|
try {
|
||||||
@ -56,32 +55,28 @@ class VulcanLoginWebMain(val data: DataVulcan, val onSuccess: () -> Unit) {
|
|||||||
data.symbol = getString("symbol")
|
data.symbol = getString("symbol")
|
||||||
remove("symbol")
|
remove("symbol")
|
||||||
}
|
}
|
||||||
|
// 4.6 - form inputs renamed
|
||||||
|
if (has("email")) {
|
||||||
|
data.webEmail = getString("email")
|
||||||
|
remove("email")
|
||||||
|
}
|
||||||
|
if (has("username")) {
|
||||||
|
data.webUsername = getString("username")
|
||||||
|
remove("username")
|
||||||
|
}
|
||||||
|
if (has("password")) {
|
||||||
|
data.webPassword = getString("password")
|
||||||
|
remove("password")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.symbol == null && data.webRealmData != null) {
|
||||||
|
data.symbol = data.webRealmData?.symbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loginWithCredentials(): Boolean {
|
private fun loginWithCredentials(): Boolean {
|
||||||
val realm = when (data.webType) {
|
val realm = data.webRealmData?.toRealm() ?: return false
|
||||||
"cufs" -> CufsRealm(
|
|
||||||
host = data.webHost ?: return false,
|
|
||||||
symbol = data.symbol ?: "default",
|
|
||||||
httpCufs = data.webIsHttpCufs
|
|
||||||
)
|
|
||||||
"adfs" -> CufsRealm(
|
|
||||||
host = data.webHost ?: return false,
|
|
||||||
symbol = data.symbol ?: "default",
|
|
||||||
httpCufs = data.webIsHttpCufs
|
|
||||||
).toAdfsRealm(id = data.webAdfsId ?: return false)
|
|
||||||
"adfslight" -> CufsRealm(
|
|
||||||
host = data.webHost ?: return false,
|
|
||||||
symbol = data.symbol ?: "default",
|
|
||||||
httpCufs = data.webIsHttpCufs
|
|
||||||
).toAdfsLightRealm(
|
|
||||||
id = data.webAdfsId ?: return false,
|
|
||||||
domain = data.webAdfsDomain ?: "adfslight",
|
|
||||||
isScoped = data.webIsScopedAdfs
|
|
||||||
)
|
|
||||||
else -> return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val certificate = web.readCertificate()?.let { web.parseCertificate(it) }
|
val certificate = web.readCertificate()?.let { web.parseCertificate(it) }
|
||||||
if (certificate != null && Date.fromIso(certificate.expiryDate) > System.currentTimeMillis()) {
|
if (certificate != null && Date.fromIso(certificate.expiryDate) > System.currentTimeMillis()) {
|
||||||
|
@ -88,11 +88,13 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
withContext(Dispatchers.Default) { block.invoke(this@SzkolnyApi) }
|
withContext(Dispatchers.Default) { block.invoke(this@SzkolnyApi) }
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
catch (e: Exception) {
|
||||||
|
withContext(coroutineContext) {
|
||||||
ErrorDetailsDialog(
|
ErrorDetailsDialog(
|
||||||
activity,
|
activity,
|
||||||
listOf(e.toApiError(TAG)),
|
listOf(e.toApiError(TAG)),
|
||||||
R.string.error_occured
|
R.string.error_occured
|
||||||
)
|
)
|
||||||
|
}
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -348,8 +350,8 @@ class SzkolnyApi(val app: App) : CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun getPlatforms(registerName: String): List<LoginInfo.Platform> {
|
fun getRealms(registerName: String): List<LoginInfo.Platform> {
|
||||||
val response = api.appLoginPlatforms(registerName).execute()
|
val response = api.fsLoginRealms(registerName).execute()
|
||||||
|
|
||||||
return parseResponse(response)
|
return parseResponse(response)
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,12 @@ interface SzkolnyService {
|
|||||||
@POST("feedbackMessage")
|
@POST("feedbackMessage")
|
||||||
fun feedbackMessage(@Body request: FeedbackMessageRequest): Call<ApiResponse<FeedbackMessageResponse>>
|
fun feedbackMessage(@Body request: FeedbackMessageRequest): Call<ApiResponse<FeedbackMessageResponse>>
|
||||||
|
|
||||||
@GET("appLogin/platforms/{registerName}")
|
|
||||||
fun appLoginPlatforms(@Path("registerName") registerName: String): Call<ApiResponse<List<LoginInfo.Platform>>>
|
|
||||||
|
|
||||||
@GET("firebase/token/{registerName}")
|
@GET("firebase/token/{registerName}")
|
||||||
fun firebaseToken(@Path("registerName") registerName: String): Call<ApiResponse<String>>
|
fun firebaseToken(@Path("registerName") registerName: String): Call<ApiResponse<String>>
|
||||||
|
|
||||||
@GET("registerAvailability")
|
@GET("registerAvailability")
|
||||||
fun registerAvailability(): Call<ApiResponse<Map<String, RegisterAvailabilityStatus>>>
|
fun registerAvailability(): Call<ApiResponse<Map<String, RegisterAvailabilityStatus>>>
|
||||||
|
|
||||||
|
@GET("fsLogin/{registerName}")
|
||||||
|
fun fsLoginRealms(@Path("registerName") registerName: String): Call<ApiResponse<List<LoginInfo.Platform>>>
|
||||||
}
|
}
|
||||||
|
@ -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.MTIzNDU2Nzg5MD5LwH9bSc===.$param2".sha256()
|
return "$param1.MTIzNDU2Nzg5MDgzuDTD2K===.$param2".sha256()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.data.db.migration.*
|
|||||||
LibrusLesson::class,
|
LibrusLesson::class,
|
||||||
TimetableManual::class,
|
TimetableManual::class,
|
||||||
Metadata::class
|
Metadata::class
|
||||||
], version = 89)
|
], version = 91)
|
||||||
@TypeConverters(
|
@TypeConverters(
|
||||||
ConverterTime::class,
|
ConverterTime::class,
|
||||||
ConverterDate::class,
|
ConverterDate::class,
|
||||||
@ -174,7 +174,9 @@ abstract class AppDb : RoomDatabase() {
|
|||||||
Migration86(),
|
Migration86(),
|
||||||
Migration87(),
|
Migration87(),
|
||||||
Migration88(),
|
Migration88(),
|
||||||
Migration89()
|
Migration89(),
|
||||||
|
Migration90(),
|
||||||
|
Migration91()
|
||||||
).allowMainThreadQueries().build()
|
).allowMainThreadQueries().build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +93,25 @@ open class Event(
|
|||||||
var attachmentIds: MutableList<Long>? = null
|
var attachmentIds: MutableList<Long>? = null
|
||||||
var attachmentNames: MutableList<String>? = null
|
var attachmentNames: MutableList<String>? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attachment
|
||||||
|
* @param id attachment ID
|
||||||
|
* @param name file name incl. extension
|
||||||
|
* @return a Event to which the attachment has been added
|
||||||
|
*/
|
||||||
|
fun addAttachment(id: Long, name: String): Event {
|
||||||
|
if (attachmentIds == null) attachmentIds = mutableListOf()
|
||||||
|
if (attachmentNames == null) attachmentNames = mutableListOf()
|
||||||
|
attachmentIds?.add(id)
|
||||||
|
attachmentNames?.add(name)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearAttachments() {
|
||||||
|
attachmentIds = null
|
||||||
|
attachmentNames = null
|
||||||
|
}
|
||||||
|
|
||||||
@Ignore
|
@Ignore
|
||||||
var showAsUnseen: Boolean? = null
|
var showAsUnseen: Boolean? = null
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ class LoginStore(
|
|||||||
is Long -> putLoginData(key, o)
|
is Long -> putLoginData(key, o)
|
||||||
is Float -> putLoginData(key, o)
|
is Float -> putLoginData(key, o)
|
||||||
is Boolean -> putLoginData(key, o)
|
is Boolean -> putLoginData(key, o)
|
||||||
|
is Bundle -> putLoginData(key, o.toJsonObject())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,9 @@ open class Profile(
|
|||||||
dateSemester2Start.year -= diff
|
dateSemester2Start.year -= diff
|
||||||
dateYearEnd.year -= diff
|
dateYearEnd.year -= diff
|
||||||
}
|
}
|
||||||
return Date.getToday() >= dateYearEnd && Date.getToday().year > studentSchoolYearStart
|
return App.config.archiverEnabled
|
||||||
|
&& Date.getToday() >= dateYearEnd
|
||||||
|
&& Date.getToday().year > studentSchoolYearStart
|
||||||
}
|
}
|
||||||
fun isBeforeYear() = false && Date.getToday() < dateSemester1Start
|
fun isBeforeYear() = false && Date.getToday() < dateSemester1Start
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import androidx.room.Entity
|
|||||||
import androidx.room.Ignore
|
import androidx.room.Ignore
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.fixName
|
import pl.szczodrzynski.edziennik.fixName
|
||||||
|
import pl.szczodrzynski.edziennik.getNameInitials
|
||||||
import pl.szczodrzynski.edziennik.join
|
import pl.szczodrzynski.edziennik.join
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -180,6 +181,9 @@ open class Teacher {
|
|||||||
@delegate:Ignore
|
@delegate:Ignore
|
||||||
val fullNameLastFirst by lazy { "$surname $name".fixName() }
|
val fullNameLastFirst by lazy { "$surname $name".fixName() }
|
||||||
|
|
||||||
|
@delegate:Ignore
|
||||||
|
val initialsLastFirst by lazy { fullNameLastFirst.getNameInitials() }
|
||||||
|
|
||||||
val shortName: String
|
val shortName: String
|
||||||
get() = (if (name == null || name?.length == 0) "" else name!![0].toString()) + "." + surname
|
get() = (if (name == null || name?.length == 0) "" else name!![0].toString()) + "." + surname
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-26.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.migration
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration90 : Migration(89, 90) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
// get all profiles using Vulcan/Hebe
|
||||||
|
database.execSQL("CREATE TABLE _90_ids (id INTEGER NOT NULL);")
|
||||||
|
database.execSQL("INSERT INTO _90_ids SELECT profileId FROM profiles JOIN loginStores USING(loginStoreId) WHERE loginStores.loginStoreType = 4 AND loginStores.loginStoreMode != 0;")
|
||||||
|
|
||||||
|
// force full sync when updating from <4.6
|
||||||
|
database.execSQL("DELETE FROM endpointTimers WHERE profileId IN (SELECT id FROM _90_ids);")
|
||||||
|
database.execSQL("UPDATE profiles SET empty = 1 WHERE profileId IN (SELECT id FROM _90_ids);")
|
||||||
|
// remove messages and events to re-download attachments and remove older than current school year
|
||||||
|
database.execSQL("DELETE FROM messages WHERE profileId IN (SELECT id FROM _90_ids);")
|
||||||
|
database.execSQL("DELETE FROM events WHERE profileId IN (SELECT id FROM _90_ids) AND eventAddedManually = 0;")
|
||||||
|
// remove older data
|
||||||
|
database.execSQL("DELETE FROM notices WHERE profileId IN (SELECT id FROM _90_ids);")
|
||||||
|
|
||||||
|
// fix for v4.5 users who logged in using Vulcan/Web
|
||||||
|
database.execSQL("UPDATE loginStores SET loginStoreMode = 2 WHERE loginStoreType = 4 AND loginStoreMode = 1;")
|
||||||
|
|
||||||
|
database.execSQL("DROP TABLE _90_ids;")
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2021-2-26.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.db.migration
|
||||||
|
|
||||||
|
import androidx.room.migration.Migration
|
||||||
|
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||||
|
|
||||||
|
class Migration91 : Migration(90, 91) {
|
||||||
|
override fun migrate(database: SupportSQLiteDatabase) {
|
||||||
|
// get all profiles using Vulcan/Hebe
|
||||||
|
database.execSQL("CREATE TABLE _91_ids (id INTEGER NOT NULL);")
|
||||||
|
database.execSQL("INSERT INTO _91_ids SELECT profileId FROM profiles JOIN loginStores USING(loginStoreId) WHERE loginStores.loginStoreType = 1;")
|
||||||
|
|
||||||
|
// force attendance sync - mobidziennik
|
||||||
|
// after enabling counting the e-attendance to statistics
|
||||||
|
database.execSQL("DELETE FROM endpointTimers WHERE profileId IN (SELECT id FROM _91_ids) AND endpointId = 2050;")
|
||||||
|
database.execSQL("UPDATE attendances SET attendanceIsCounted = 1 WHERE profileId IN (SELECT id FROM _91_ids);")
|
||||||
|
database.execSQL("UPDATE attendances SET attendanceBaseType = 2 WHERE profileId IN (SELECT id FROM _91_ids) AND attendanceTypeSymbol = ?;",
|
||||||
|
arrayOf("+ₑ"))
|
||||||
|
|
||||||
|
database.execSQL("DROP TABLE _91_ids;")
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@ class SzkolnyVulcanFirebase(val app: App, val profiles: List<Profile>, val messa
|
|||||||
val data = message.data.getString("data")?.toJsonObject() ?: return@run
|
val data = message.data.getString("data")?.toJsonObject() ?: return@run
|
||||||
val type = data.getString("table") ?: return@run
|
val type = data.getString("table") ?: return@run
|
||||||
val studentId = data.getInt("pupilid")
|
val studentId = data.getInt("pupilid")
|
||||||
|
val loginId = data.getInt("loginid")
|
||||||
|
|
||||||
/* pl.vulcan.uonetmobile.auxilary.enums.CDCPushEnum */
|
/* pl.vulcan.uonetmobile.auxilary.enums.CDCPushEnum */
|
||||||
val viewIdPair = when (type.toLowerCase(Locale.ROOT)) {
|
val viewIdPair = when (type.toLowerCase(Locale.ROOT)) {
|
||||||
@ -42,8 +43,9 @@ class SzkolnyVulcanFirebase(val app: App, val profiles: List<Profile>, val messa
|
|||||||
}
|
}
|
||||||
|
|
||||||
val tasks = profiles.filter {
|
val tasks = profiles.filter {
|
||||||
it.loginStoreType == LOGIN_TYPE_VULCAN &&
|
it.loginStoreType == LOGIN_TYPE_VULCAN
|
||||||
it.getStudentData("studentId", 0) == studentId
|
&& (it.getStudentData("studentId", 0) == studentId
|
||||||
|
|| it.getStudentData("studentLoginId", 0) == loginId)
|
||||||
}.map {
|
}.map {
|
||||||
EdziennikTask.syncProfile(it.id, listOf(viewIdPair))
|
EdziennikTask.syncProfile(it.id, listOf(viewIdPair))
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,8 @@ import kotlin.coroutines.CoroutineContext
|
|||||||
class ProfileRemoveDialog(
|
class ProfileRemoveDialog(
|
||||||
val activity: MainActivity,
|
val activity: MainActivity,
|
||||||
val profileId: Int,
|
val profileId: Int,
|
||||||
val profileName: String
|
val profileName: String,
|
||||||
|
val noProfileRemoval: Boolean = false
|
||||||
) : CoroutineScope {
|
) : CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "ProfileRemoveDialog"
|
private const val TAG = "ProfileRemoveDialog"
|
||||||
@ -52,7 +53,6 @@ class ProfileRemoveDialog(
|
|||||||
app.db.attendanceDao().clear(profileId)
|
app.db.attendanceDao().clear(profileId)
|
||||||
app.db.attendanceTypeDao().clear(profileId)
|
app.db.attendanceTypeDao().clear(profileId)
|
||||||
app.db.classroomDao().clear(profileId)
|
app.db.classroomDao().clear(profileId)
|
||||||
app.db.configDao().clear(profileId)
|
|
||||||
app.db.endpointTimerDao().clear(profileId)
|
app.db.endpointTimerDao().clear(profileId)
|
||||||
app.db.eventDao().clear(profileId)
|
app.db.eventDao().clear(profileId)
|
||||||
app.db.eventTypeDao().clear(profileId)
|
app.db.eventTypeDao().clear(profileId)
|
||||||
@ -65,23 +65,27 @@ class ProfileRemoveDialog(
|
|||||||
app.db.messageRecipientDao().clear(profileId)
|
app.db.messageRecipientDao().clear(profileId)
|
||||||
app.db.noticeDao().clear(profileId)
|
app.db.noticeDao().clear(profileId)
|
||||||
app.db.noticeTypeDao().clear(profileId)
|
app.db.noticeTypeDao().clear(profileId)
|
||||||
app.db.noticeTypeDao().clear(profileId)
|
|
||||||
app.db.notificationDao().clear(profileId)
|
app.db.notificationDao().clear(profileId)
|
||||||
app.db.subjectDao().clear(profileId)
|
app.db.subjectDao().clear(profileId)
|
||||||
app.db.teacherAbsenceDao().clear(profileId)
|
app.db.teacherAbsenceDao().clear(profileId)
|
||||||
app.db.teacherAbsenceDao().clear(profileId)
|
|
||||||
app.db.teacherAbsenceTypeDao().clear(profileId)
|
app.db.teacherAbsenceTypeDao().clear(profileId)
|
||||||
app.db.teacherDao().clear(profileId)
|
app.db.teacherDao().clear(profileId)
|
||||||
app.db.teamDao().clear(profileId)
|
app.db.teamDao().clear(profileId)
|
||||||
app.db.timetableDao().clear(profileId)
|
app.db.timetableDao().clear(profileId)
|
||||||
|
|
||||||
|
app.db.metadataDao().deleteAll(profileId)
|
||||||
|
|
||||||
|
if (noProfileRemoval)
|
||||||
|
return@async
|
||||||
|
|
||||||
|
app.db.configDao().clear(profileId)
|
||||||
|
|
||||||
val loginStoreId = profileObject.loginStoreId
|
val loginStoreId = profileObject.loginStoreId
|
||||||
val profilesUsingLoginStore = app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
val profilesUsingLoginStore = app.db.profileDao().getIdsByLoginStoreIdNow(loginStoreId)
|
||||||
if (profilesUsingLoginStore.size == 1) {
|
if (profilesUsingLoginStore.size == 1) {
|
||||||
app.db.loginStoreDao().remove(loginStoreId)
|
app.db.loginStoreDao().remove(loginStoreId)
|
||||||
}
|
}
|
||||||
app.db.profileDao().remove(profileId)
|
app.db.profileDao().remove(profileId)
|
||||||
app.db.metadataDao().deleteAll(profileId)
|
|
||||||
|
|
||||||
if (App.profileId == profileId) {
|
if (App.profileId == profileId) {
|
||||||
app.profileLoadLast { }
|
app.profileLoadLast { }
|
||||||
|
@ -26,6 +26,7 @@ import pl.szczodrzynski.edziennik.ui.modules.debug.models.LabJsonObject
|
|||||||
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonArrayViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonArrayViewHolder
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonElementViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonElementViewHolder
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonObjectViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonObjectViewHolder
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.debug.viewholder.JsonSubObjectViewHolder
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
import pl.szczodrzynski.edziennik.ui.modules.grades.models.ExpandableItemModel
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
import pl.szczodrzynski.edziennik.ui.modules.grades.viewholder.BindableViewHolder
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
@ -35,14 +36,20 @@ class LabJsonAdapter(
|
|||||||
var onJsonElementClick: ((item: LabJsonElement) -> Unit)? = null
|
var onJsonElementClick: ((item: LabJsonElement) -> Unit)? = null
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), CoroutineScope {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "AttendanceAdapter"
|
private const val TAG = "LabJsonAdapter"
|
||||||
private const val ITEM_TYPE_OBJECT = 0
|
private const val ITEM_TYPE_OBJECT = 0
|
||||||
private const val ITEM_TYPE_ARRAY = 1
|
private const val ITEM_TYPE_SUB_OBJECT = 1
|
||||||
private const val ITEM_TYPE_ELEMENT = 2
|
private const val ITEM_TYPE_ARRAY = 2
|
||||||
|
private const val ITEM_TYPE_ELEMENT = 3
|
||||||
const val STATE_CLOSED = 0
|
const val STATE_CLOSED = 0
|
||||||
const val STATE_OPENED = 1
|
const val STATE_OPENED = 1
|
||||||
|
|
||||||
fun expand(item: Any, level: Int): MutableList<Any> {
|
fun expand(item: Any, level: Int): MutableList<Any> {
|
||||||
|
val path = when (item) {
|
||||||
|
is LabJsonObject -> item.key + ":"
|
||||||
|
is LabJsonArray -> item.key + ":"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
val json = when (item) {
|
val json = when (item) {
|
||||||
is LabJsonObject -> item.jsonObject
|
is LabJsonObject -> item.jsonObject
|
||||||
is LabJsonArray -> item.jsonArray
|
is LabJsonArray -> item.jsonArray
|
||||||
@ -53,17 +60,16 @@ class LabJsonAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return when (json) {
|
return when (json) {
|
||||||
is JsonObject -> json.entrySet().mapNotNull { wrap(it.key, it.value, level) }
|
is JsonObject -> json.entrySet().mapNotNull { wrap(path + it.key, it.value, level) }
|
||||||
is JsonArray -> json.mapIndexedNotNull { index, jsonElement -> wrap(index.toString(), jsonElement, level) }
|
is JsonArray -> json.mapIndexedNotNull { index, jsonElement -> wrap(path + index.toString(), jsonElement, level) }
|
||||||
else -> listOf(LabJsonElement("?", json, level))
|
else -> listOf(LabJsonElement("$path?", json, level))
|
||||||
}.toMutableList()
|
}.toMutableList()
|
||||||
}
|
}
|
||||||
fun wrap(key: String, item: JsonElement, level: Int = 0): Any? {
|
fun wrap(key: String, item: JsonElement, level: Int = 0): Any {
|
||||||
return when (item) {
|
return when (item) {
|
||||||
is JsonObject -> LabJsonObject(key, item, level + 1)
|
is JsonObject -> LabJsonObject(key, item, level + 1)
|
||||||
is JsonArray -> LabJsonArray(key, item, level + 1)
|
is JsonArray -> LabJsonArray(key, item, level + 1)
|
||||||
is JsonElement -> LabJsonElement(key, item, level + 1)
|
else -> LabJsonElement(key, item, level + 1)
|
||||||
else -> null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +86,7 @@ class LabJsonAdapter(
|
|||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
return when (viewType) {
|
return when (viewType) {
|
||||||
ITEM_TYPE_OBJECT -> JsonObjectViewHolder(inflater, parent)
|
ITEM_TYPE_OBJECT -> JsonObjectViewHolder(inflater, parent)
|
||||||
|
ITEM_TYPE_SUB_OBJECT -> JsonSubObjectViewHolder(inflater, parent)
|
||||||
ITEM_TYPE_ARRAY -> JsonArrayViewHolder(inflater, parent)
|
ITEM_TYPE_ARRAY -> JsonArrayViewHolder(inflater, parent)
|
||||||
ITEM_TYPE_ELEMENT -> JsonElementViewHolder(inflater, parent)
|
ITEM_TYPE_ELEMENT -> JsonElementViewHolder(inflater, parent)
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
@ -87,8 +94,10 @@ class LabJsonAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return when (items[position]) {
|
return when (val item = items[position]) {
|
||||||
is LabJsonObject -> ITEM_TYPE_OBJECT
|
is LabJsonObject ->
|
||||||
|
if (item.level == 1) ITEM_TYPE_OBJECT
|
||||||
|
else ITEM_TYPE_SUB_OBJECT
|
||||||
is LabJsonArray -> ITEM_TYPE_ARRAY
|
is LabJsonArray -> ITEM_TYPE_ARRAY
|
||||||
is LabJsonElement -> ITEM_TYPE_ELEMENT
|
is LabJsonElement -> ITEM_TYPE_ELEMENT
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
@ -118,7 +127,7 @@ class LabJsonAdapter(
|
|||||||
View.ROTATION,
|
View.ROTATION,
|
||||||
if (model.state == STATE_CLOSED) 0f else 180f,
|
if (model.state == STATE_CLOSED) 0f else 180f,
|
||||||
if (model.state == STATE_CLOSED) 180f else 0f
|
if (model.state == STATE_CLOSED) 180f else 0f
|
||||||
).setDuration(200).start();
|
).setDuration(200).start()
|
||||||
}
|
}
|
||||||
|
|
||||||
// hide the preview, show summary
|
// hide the preview, show summary
|
||||||
@ -143,7 +152,9 @@ class LabJsonAdapter(
|
|||||||
var end: Int = items.size
|
var end: Int = items.size
|
||||||
for (i in start until items.size) {
|
for (i in start until items.size) {
|
||||||
val model1 = items[i]
|
val model1 = items[i]
|
||||||
val level = (model1 as? ExpandableItemModel<*>)?.level ?: 3
|
val level = (model1 as? ExpandableItemModel<*>)?.level
|
||||||
|
?: (model1 as? LabJsonElement)?.level
|
||||||
|
?: model.level
|
||||||
if (level <= model.level) {
|
if (level <= model.level) {
|
||||||
end = i
|
end = i
|
||||||
break
|
break
|
||||||
@ -170,6 +181,7 @@ class LabJsonAdapter(
|
|||||||
|
|
||||||
val viewType = when (holder) {
|
val viewType = when (holder) {
|
||||||
is JsonObjectViewHolder -> ITEM_TYPE_OBJECT
|
is JsonObjectViewHolder -> ITEM_TYPE_OBJECT
|
||||||
|
is JsonSubObjectViewHolder -> ITEM_TYPE_SUB_OBJECT
|
||||||
is JsonArrayViewHolder -> ITEM_TYPE_ARRAY
|
is JsonArrayViewHolder -> ITEM_TYPE_ARRAY
|
||||||
is JsonElementViewHolder -> ITEM_TYPE_ELEMENT
|
is JsonElementViewHolder -> ITEM_TYPE_ELEMENT
|
||||||
else -> throw IllegalArgumentException("Incorrect viewType")
|
else -> throw IllegalArgumentException("Incorrect viewType")
|
||||||
@ -180,6 +192,7 @@ class LabJsonAdapter(
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
holder is JsonObjectViewHolder && item is LabJsonObject -> holder.onBind(activity, app, item, position, this)
|
holder is JsonObjectViewHolder && item is LabJsonObject -> holder.onBind(activity, app, item, position, this)
|
||||||
|
holder is JsonSubObjectViewHolder && item is LabJsonObject -> holder.onBind(activity, app, item, position, this)
|
||||||
holder is JsonArrayViewHolder && item is LabJsonArray -> holder.onBind(activity, app, item, position, this)
|
holder is JsonArrayViewHolder && item is LabJsonArray -> holder.onBind(activity, app, item, position, this)
|
||||||
holder is JsonElementViewHolder && item is LabJsonElement -> holder.onBind(activity, app, item, position, this)
|
holder is JsonElementViewHolder && item is LabJsonElement -> holder.onBind(activity, app, item, position, this)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import kotlinx.coroutines.launch
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding
|
import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||||
import pl.szczodrzynski.fslogin.decode
|
import pl.szczodrzynski.fslogin.decode
|
||||||
@ -45,6 +46,8 @@ class LabPageFragment : LazyFragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPageCreated(): Boolean {
|
override fun onPageCreated(): Boolean {
|
||||||
|
b.app = app
|
||||||
|
|
||||||
b.last10unseen.onClick {
|
b.last10unseen.onClick {
|
||||||
launch(Dispatchers.Default) {
|
launch(Dispatchers.Default) {
|
||||||
val events = app.db.eventDao().getAllNow(App.profileId)
|
val events = app.db.eventDao().getAllNow(App.profileId)
|
||||||
@ -59,6 +62,15 @@ class LabPageFragment : LazyFragment(), CoroutineScope {
|
|||||||
app.db.teacherDao().query(SimpleSQLiteQuery("UPDATE teachers SET teacherSurname = \"\" WHERE profileId = ${App.profileId}"))
|
app.db.teacherDao().query(SimpleSQLiteQuery("UPDATE teachers SET teacherSurname = \"\" WHERE profileId = ${App.profileId}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b.fullSync.onClick {
|
||||||
|
app.db.query(SimpleSQLiteQuery("UPDATE profiles SET empty = 1 WHERE profileId = ${App.profileId}"))
|
||||||
|
app.db.query(SimpleSQLiteQuery("DELETE FROM endpointTimers WHERE profileId = ${App.profileId}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
b.clearProfile.onClick {
|
||||||
|
ProfileRemoveDialog(activity, App.profileId, "FAKE", noProfileRemoval = true)
|
||||||
|
}
|
||||||
|
|
||||||
b.removeHomework.onClick {
|
b.removeHomework.onClick {
|
||||||
app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}")
|
app.db.eventDao().getRawNow("UPDATE events SET homeworkBody = NULL WHERE profileId = ${App.profileId}")
|
||||||
}
|
}
|
||||||
|
@ -10,16 +10,14 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.gson.JsonObject
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
|
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
|
||||||
import pl.szczodrzynski.edziennik.startCoroutineTimer
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
import pl.szczodrzynski.edziennik.ui.modules.base.lazypager.LazyFragment
|
||||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
@ -38,6 +36,10 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
|
|||||||
get() = job + Dispatchers.Main
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
// local/private variables go here
|
// local/private variables go here
|
||||||
|
private lateinit var adapter: LabJsonAdapter
|
||||||
|
private val loginStore by lazy {
|
||||||
|
app.db.loginStoreDao().getByIdNow(app.profile.loginStoreId)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
activity = (getActivity() as MainActivity?) ?: return null
|
activity = (getActivity() as MainActivity?) ?: return null
|
||||||
@ -48,22 +50,96 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||||
val adapter = LabJsonAdapter(activity)
|
adapter = LabJsonAdapter(activity, onJsonElementClick = { item ->
|
||||||
val json = JsonObject().also { json ->
|
try {
|
||||||
json.add("app.profile", app.profile.studentData)
|
var parent: Any = Unit
|
||||||
json.add("app.config", JsonParser().parse(app.gson.toJson(app.config.values)))
|
var obj: Any = Unit
|
||||||
EdziennikTask.profile?.let {
|
var objName: String = ""
|
||||||
json.add("API.profile", it.studentData)
|
item.key.split(":").forEach { el ->
|
||||||
} ?: {
|
parent = obj
|
||||||
json.addProperty("API.profile", "null")
|
obj = when (el) {
|
||||||
}()
|
"App.profile" -> app.profile
|
||||||
EdziennikTask.loginStore?.let {
|
"App.profile.studentData" -> app.profile.studentData
|
||||||
json.add("API.loginStore", it.data)
|
"App.profile.loginStore" -> loginStore?.data ?: JsonObject()
|
||||||
} ?: {
|
"App.config" -> app.config.values
|
||||||
json.addProperty("API.loginStore", "null")
|
else -> when (obj) {
|
||||||
}()
|
is JsonObject -> (obj as JsonObject).get(el)
|
||||||
|
is JsonArray -> (obj as JsonArray).get(el.toInt())
|
||||||
|
is HashMap<*, *> -> (obj as HashMap<String, String?>)[el].toString()
|
||||||
|
else -> {
|
||||||
|
val field = obj::class.java.getDeclaredField(el)
|
||||||
|
field.isAccessible = true
|
||||||
|
field.get(obj) ?: return@forEach
|
||||||
}
|
}
|
||||||
adapter.items = LabJsonAdapter.expand(json, 0)
|
}
|
||||||
|
}
|
||||||
|
objName = el
|
||||||
|
}
|
||||||
|
|
||||||
|
val objVal = obj
|
||||||
|
val value = when (objVal) {
|
||||||
|
is JsonPrimitive -> when {
|
||||||
|
objVal.isString -> objVal.asString
|
||||||
|
objVal.isNumber -> objVal.asNumber.toString()
|
||||||
|
objVal.isBoolean -> objVal.asBoolean.toString()
|
||||||
|
else -> objVal.asString
|
||||||
|
}
|
||||||
|
else -> objVal.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialDialog.Builder(activity)
|
||||||
|
.input("value", value, false) { _, input ->
|
||||||
|
val input = input.toString()
|
||||||
|
when (parent) {
|
||||||
|
is JsonObject -> {
|
||||||
|
val v = objVal as JsonPrimitive
|
||||||
|
when {
|
||||||
|
v.isString -> (parent as JsonObject)[objName] = input
|
||||||
|
v.isNumber -> (parent as JsonObject)[objName] = input.toLong()
|
||||||
|
v.isBoolean -> (parent as JsonObject)[objName] = input.toBoolean()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is JsonArray -> {
|
||||||
|
|
||||||
|
}
|
||||||
|
is HashMap<*, *> -> app.config.set(objName, input)
|
||||||
|
else -> {
|
||||||
|
val field = parent::class.java.getDeclaredField(objName)
|
||||||
|
field.isAccessible = true
|
||||||
|
val newVal = when (objVal) {
|
||||||
|
is Int -> input.toInt()
|
||||||
|
is Boolean -> input.toBoolean()
|
||||||
|
is Float -> input.toFloat()
|
||||||
|
is Char -> input.toCharArray()[0]
|
||||||
|
is String -> input
|
||||||
|
is Long -> input.toLong()
|
||||||
|
is Double -> input.toDouble()
|
||||||
|
else -> input
|
||||||
|
}
|
||||||
|
field.set(parent, newVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when (item.key.substringBefore(":")) {
|
||||||
|
"App.profile" -> app.profileSave()
|
||||||
|
"App.profile.studentData" -> app.profileSave()
|
||||||
|
"App.profile.loginStore" -> app.db.loginStoreDao().add(loginStore)
|
||||||
|
}
|
||||||
|
|
||||||
|
showJson()
|
||||||
|
|
||||||
|
}
|
||||||
|
.title(item.key)
|
||||||
|
.positiveText(R.string.ok)
|
||||||
|
.negativeText(R.string.cancel)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
activity.error(ApiError.fromThrowable(TAG, e))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
showJson()
|
||||||
|
|
||||||
b.list.adapter = adapter
|
b.list.adapter = adapter
|
||||||
b.list.apply {
|
b.list.apply {
|
||||||
@ -79,4 +155,15 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
|
|||||||
b.noData.isVisible = false
|
b.noData.isVisible = false
|
||||||
|
|
||||||
}; return true }
|
}; return true }
|
||||||
|
|
||||||
|
private fun showJson() {
|
||||||
|
val json = JsonObject().also { json ->
|
||||||
|
json.add("App.profile", app.gson.toJsonTree(app.profile))
|
||||||
|
json.add("App.profile.studentData", app.profile.studentData)
|
||||||
|
json.add("App.profile.loginStore", loginStore?.data ?: JsonObject())
|
||||||
|
json.add("App.config", JsonParser().parse(app.gson.toJson(app.config.values)))
|
||||||
|
}
|
||||||
|
adapter.items = LabJsonAdapter.expand(json, 0)
|
||||||
|
adapter.notifyDataSetChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user