diff --git a/app/build.gradle b/app/build.gradle index 7635b8c1..2c525d23 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -82,9 +82,6 @@ android { defaultConfig { vectorDrawables.useSupportLibrary = true } - lintOptions { - checkReleaseBuilds = false - } buildFeatures { dataBinding = true viewBinding = true @@ -98,7 +95,9 @@ android { jvmTarget = "1.8" } packagingOptions { - exclude 'META-INF/library-core_release.kotlin_module' + resources { + excludes += ['META-INF/library-core_release.kotlin_module'] + } } externalNativeBuild { cmake { @@ -106,6 +105,9 @@ android { version "3.10.2" } } + lint { + checkReleaseBuilds false + } } tasks.whenTaskAdded { task -> @@ -140,28 +142,29 @@ dependencies { // Language cores implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation "androidx.multidex:multidex:2.0.1" coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:1.1.5" // Android Jetpack - implementation "androidx.appcompat:appcompat:1.3.1" + implementation "androidx.appcompat:appcompat:1.5.1" implementation "androidx.cardview:cardview:1.0.0" - implementation "androidx.constraintlayout:constraintlayout:2.1.1" - implementation "androidx.core:core-ktx:1.6.0" - implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1" - implementation "androidx.navigation:navigation-fragment-ktx:2.3.5" + implementation "androidx.constraintlayout:constraintlayout:2.1.4" + implementation "androidx.core:core-ktx:1.9.0" + implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.5.1" + implementation "androidx.navigation:navigation-fragment-ktx:2.5.2" implementation "androidx.recyclerview:recyclerview:1.2.1" - implementation "androidx.room:room-runtime:2.3.0" - implementation "androidx.work:work-runtime-ktx:2.6.0" - kapt "androidx.room:room-compiler:2.3.0" + implementation "androidx.room:room-runtime:2.4.3" + implementation "androidx.work:work-runtime-ktx:2.7.1" + kapt "androidx.room:room-compiler:2.4.3" // Google design libs - implementation "com.google.android.material:material:1.4.0" + implementation "com.google.android.material:material:1.6.1" implementation "com.google.android.flexbox:flexbox:3.0.0" // Play Services/Firebase implementation "com.google.android.gms:play-services-wearable:17.1.0" - implementation "com.google.firebase:firebase-core:19.0.2" - implementation "com.google.firebase:firebase-crashlytics:18.2.3" + implementation("com.google.firebase:firebase-core") { version { strictly "19.0.2" } } + implementation "com.google.firebase:firebase-crashlytics:18.2.13" implementation("com.google.firebase:firebase-messaging") { version { strictly "20.1.3" } } // OkHttp, Retrofit, Gson, Jsoup diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c710c6b8..2635faf7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,7 @@ android:configChanges="orientation|screenSize" android:label="@string/app_name" android:launchMode="singleTop" + android:exported="true" android:theme="@style/SplashTheme"> @@ -66,6 +67,7 @@ android:configChanges="orientation|keyboardHidden" android:excludeFromRecents="true" android:noHistory="true" + android:exported="true" android:theme="@style/AppTheme.Dark.NoDisplay"> @@ -73,7 +75,8 @@ + android:label="@string/widget_timetable_title" + android:exported="true"> @@ -88,10 +91,12 @@ android:configChanges="orientation|keyboardHidden" android:excludeFromRecents="true" android:noHistory="true" + android:exported="true" android:theme="@style/AppTheme.Dark.NoDisplay" /> + android:label="@string/widget_notifications_title" + android:exported="true"> @@ -104,7 +109,8 @@ android:permission="android.permission.BIND_REMOTEVIEWS" /> + android:label="@string/widget_lucky_number_title" + android:exported="true"> @@ -124,29 +130,36 @@ - - + + + android:enabled="true" + android:exported="true"> - + diff --git a/app/src/main/assets/pl-changelog.html b/app/src/main/assets/pl-changelog.html index b0792712..3164d7dc 100644 --- a/app/src/main/assets/pl-changelog.html +++ b/app/src/main/assets/pl-changelog.html @@ -1,6 +1,9 @@ -

Wersja 4.11.5, 2022-04-18

+

Wersja 4.11.8, 2022-09-17

    -
  • Poprawiono działanie dotyku na systemie Android 12 i nowszych.
  • +
  • Vulcan UONET+: naprawiono działanie systemu wiadomości. @Antoni-Czaplicki
  • +
  • Poprawiono wyświetlanie lekcji odwołanych na stronie głównej.
  • +
  • Dodano dostęp do Laboratorium na ekranie logowania.
  • +
  • Usunięto obsługę dziennika EduDziennik. [*]


diff --git a/app/src/main/cpp/szkolny-signing.cpp b/app/src/main/cpp/szkolny-signing.cpp index b3014e32..35e96eb0 100644 --- a/app/src/main/cpp/szkolny-signing.cpp +++ b/app/src/main/cpp/szkolny-signing.cpp @@ -9,7 +9,7 @@ /*secret password - removed for source code publication*/ static toys AES_IV[16] = { - 0x5d, 0x6b, 0xa0, 0x4e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + 0xb2, 0x96, 0xab, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt index 1cb7587a..3df74621 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Constants.kt @@ -59,40 +59,12 @@ const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action=" const val LIBRUS_SYNERGIA_HOMEWORK_ATTACHMENT_URL = "https://synergia.librus.pl/homework/downloadFile" const val LIBRUS_SYNERGIA_MESSAGES_ATTACHMENT_URL = "https://synergia.librus.pl/wiadomosci/pobierz_zalacznik" -const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT -const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik" -const val IDZIENNIK_WEB_LOGIN = "login.aspx" -const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.aspx" -const val IDZIENNIK_WEB_HOME = "mod_panelRodzica/StronaGlowna.aspx" -const val IDZIENNIK_WEB_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec" -const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia" -const val IDZIENNIK_WEB_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia" -const val IDZIENNIK_WEB_EXAMS = "mod_panelRodzica/sprawdziany/mod_sprawdzianyPanel.asmx/pobierzListe" -const val IDZIENNIK_WEB_HOMEWORK = "mod_panelRodzica/pracaDomowa/WS_pracaDomowa.asmx/pobierzPraceDomowe" -const val IDZIENNIK_WEB_NOTICES = "mod_panelRodzica/uwagi/WS_uwagiUcznia.asmx/pobierzUwagiUcznia" -const val IDZIENNIK_WEB_ATTENDANCE = "mod_panelRodzica/obecnosci/WS_obecnosciUcznia.asmx/pobierzObecnosciUcznia" -const val IDZIENNIK_WEB_ANNOUNCEMENTS = "mod_panelRodzica/tabOgl/WS_tablicaOgloszen.asmx/GetOgloszenia" -const val IDZIENNIK_WEB_MESSAGES_LIST = "mod_komunikator/WS_wiadomosci.asmx/PobierzListeWiadomosci" -const val IDZIENNIK_WEB_GET_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/PobierzWiadomosc" -const val IDZIENNIK_WEB_GET_RECIPIENT_LIST = "mod_komunikator/WS_wiadomosci.asmx/pobierzListeOdbiorcowPanelRodzic" -const val IDZIENNIK_WEB_SEND_MESSAGE = "mod_komunikator/WS_wiadomosci.asmx/WyslijWiadomosc" -const val IDZIENNIK_WEB_GET_ATTACHMENT = "mod_komunikator/Download.ashx" -const val IDZIENNIK_WEB_GET_HOMEWORK = "mod_panelRodzica/pracaDomowa/WS_pracaDomowa.asmx/pobierzJednaPraceDomowa" -const val IDZIENNIK_WEB_GET_HOMEWORK_ATTACHMENT = "mod_panelRodzica/pracaDomowa.aspx" - -val IDZIENNIK_API_USER_AGENT = SYSTEM_USER_AGENT -const val IDZIENNIK_API_URL = "https://iuczniowie.progman.pl/idziennik/api" -const val IDZIENNIK_API_CURRENT_REGISTER = "Uczniowie/\$STUDENT_ID/AktualnyDziennik" -const val IDZIENNIK_API_GRADES = "Uczniowie/\$STUDENT_ID/Oceny/" /* + semester */ -const val IDZIENNIK_API_MESSAGES_INBOX = "Wiadomosci/Odebrane" -const val IDZIENNIK_API_MESSAGES_SENT = "Wiadomosci/Wyslane" - val MOBIDZIENNIK_USER_AGENT = SYSTEM_USER_AGENT const val VULCAN_HEBE_USER_AGENT = "Dart/2.10 (dart:io)" const val VULCAN_HEBE_APP_NAME = "DzienniczekPlus 2.0" -const val VULCAN_HEBE_APP_VERSION = "21.02.09 (G)" +const val VULCAN_HEBE_APP_VERSION = "22.09.02 (G)" private const val VULCAN_API_DEVICE_NAME_PREFIX = "Szkolny.eu " private const val VULCAN_API_DEVICE_NAME_SUFFIX = " - nie usuwać" val VULCAN_API_DEVICE_NAME by lazy { @@ -116,13 +88,13 @@ const val VULCAN_HEBE_ENDPOINT_GRADE_SUMMARY = "api/mobile/grade/summary" const val VULCAN_HEBE_ENDPOINT_HOMEWORK = "api/mobile/homework" const val VULCAN_HEBE_ENDPOINT_NOTICES = "api/mobile/note" const val VULCAN_HEBE_ENDPOINT_ATTENDANCE = "api/mobile/lesson" -const val VULCAN_HEBE_ENDPOINT_MESSAGES = "api/mobile/message" -const val VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS = "api/mobile/message/status" -const val VULCAN_HEBE_ENDPOINT_MESSAGES_SEND = "api/mobile/message" +const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX = "api/mobile/messagebox" +const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK = "api/mobile/messagebox/addressbook" +const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES = "api/mobile/messagebox/message" +const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS = "api/mobile/messagebox/message/status" +const val VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND = "api/mobile/messagebox/message" const val VULCAN_HEBE_ENDPOINT_LUCKY_NUMBER = "api/mobile/school/lucky" -const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}" - const val PODLASIE_API_VERSION = "1.0.62" const val PODLASIE_API_URL = "https://cpdklaser.zeto.bialystok.pl/api" const val PODLASIE_API_USER_ENDPOINT = "/pobierzDaneUcznia" diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/EdziennikNotification.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/EdziennikNotification.kt index 0b413356..6b2b7533 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/EdziennikNotification.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/EdziennikNotification.kt @@ -13,6 +13,7 @@ import androidx.core.app.NotificationCompat.PRIORITY_MIN import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.ext.Bundle +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver import kotlin.math.roundToInt @@ -40,14 +41,14 @@ class EdziennikNotification(val app: App) { "task" to "TaskCancelRequest", "taskId" to taskId )) - return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) as PendingIntent + return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag()) as PendingIntent } private val closePendingIntent: PendingIntent get() { val intent = SzkolnyReceiver.getIntent(app, Bundle( "task" to "ServiceCloseRequest" )) - return PendingIntent.getBroadcast(app, 0, intent, 0) as PendingIntent + return PendingIntent.getBroadcast(app, 0, intent, pendingIntentFlag()) as PendingIntent } private fun errorCountText(): String? { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt index eefc1d31..227561e6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Errors.kt @@ -198,13 +198,6 @@ const val ERROR_VULCAN_HEBE_ENTITY_NOT_FOUND = 365 const val ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY = 366 const val ERROR_VULCAN_API_DEPRECATED = 390 -const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501 -const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510 -const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511 -const val ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS = 521 -const val ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED = 522 -const val ERROR_EDUDZIENNIK_WEB_TEAM_MISSING = 530 - const val ERROR_LOGIN_PODLASIE_API_INVALID_TOKEN = 601 const val ERROR_LOGIN_PODLASIE_API_DEVICE_LIMIT = 602 const val ERROR_PODLASIE_API_NO_TOKEN = 630 @@ -224,8 +217,6 @@ const val EXCEPTION_MOBIDZIENNIK_WEB_FILE_REQUEST = 908 const val EXCEPTION_LIBRUS_MESSAGES_FILE_REQUEST = 909 const val EXCEPTION_NOTIFY = 910 const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911 -const val EXCEPTION_EDUDZIENNIK_WEB_REQUEST = 920 -const val EXCEPTION_EDUDZIENNIK_FILE_REQUEST = 921 const val ERROR_ONEDRIVE_DOWNLOAD = 930 const val EXCEPTION_VULCAN_WEB_LOGIN = 931 const val EXCEPTION_VULCAN_WEB_REQUEST = 932 diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt index b3db9f71..0f0c07ae 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/LoginMethods.kt @@ -4,7 +4,6 @@ package pl.szczodrzynski.edziennik.data.api -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb 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.LibrusLoginPortal @@ -26,8 +25,9 @@ import pl.szczodrzynski.edziennik.data.api.models.LoginMethod const val SYNERGIA_API_ENABLED = false - +// the graveyard const val LOGIN_TYPE_IDZIENNIK = 3 +const val LOGIN_TYPE_EDUDZIENNIK = 5 const val LOGIN_TYPE_TEMPLATE = 21 @@ -118,15 +118,6 @@ val vulcanLoginMethods = listOf( .withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED } ) -const val LOGIN_TYPE_EDUDZIENNIK = 5 -const val LOGIN_MODE_EDUDZIENNIK_WEB = 0 -const val LOGIN_METHOD_EDUDZIENNIK_WEB = 100 -val edudziennikLoginMethods = listOf( - LoginMethod(LOGIN_TYPE_EDUDZIENNIK, LOGIN_METHOD_EDUDZIENNIK_WEB, EdudziennikLoginWeb::class.java) - .withIsPossible { _, _ -> true } - .withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED } -) - const val LOGIN_TYPE_PODLASIE = 6 const val LOGIN_MODE_PODLASIE_API = 0 const val LOGIN_METHOD_PODLASIE_API = 100 diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt index b42de2c4..f3d5a297 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/Regexes.kt @@ -20,6 +20,10 @@ object Regexes { """""".toRegex() } + val MESSAGE_META by lazy { + """^\[META:([A-z0-9-&=]+)]""".toRegex() + } + val MOBIDZIENNIK_GRADES_SUBJECT_NAME by lazy { @@ -142,44 +146,6 @@ object Regexes { } - - val IDZIENNIK_LOGIN_HIDDEN_FIELDS by lazy { - """""".toRegex(DOT_MATCHES_ALL) - } - val IDZIENNIK_LOGIN_ERROR by lazy { - """id="spanErrorMessage">(.*?)(.+?)""".toRegex(DOT_MATCHES_ALL) - } - val IDZIENNIK_LOGIN_FIRST_IS_PARENT by lazy { - """id="ctl00_CzyRodzic" value="([01])" />""".toRegex() - } - val IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR by lazy { - """name="ctl00\${"$"}dxComboRokSzkolny".+?selected="selected".*?value="([0-9]+)">([0-9]+)/([0-9]+)<""".toRegex(DOT_MATCHES_ALL) - } - val IDZIENNIK_LOGIN_FIRST_STUDENT_SELECT by lazy { - """""".toRegex(DOT_MATCHES_ALL) - } - val IDZIENNIK_LOGIN_FIRST_STUDENT by lazy { - """(.+?)\s(.+?)\s*\((.+?),\s*(.+?)\)""".toRegex(DOT_MATCHES_ALL) - } - val IDZIENNIK_MESSAGES_RECIPIENT_PARENT by lazy { - """(.+?)\s\((.+)\)""".toRegex() - } - /*Szczęśliwy los na dzisiaj to 19. Los na jutro to 22*/ - val IDZIENNIK_WEB_LUCKY_NUMBER by lazy { - """dzisiaj to ([0-9]+)""".toRegex() - } - val IDZIENNIK_WEB_SELECTED_REGISTER by lazy { - """selected="selected" value="([0-9]+)" data-id-ucznia""".toRegex() - } - - - - val VULCAN_SHIFT_ANNOTATION by lazy { - """\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex() - } val VULCAN_WEB_PERMISSIONS by lazy { """permissions: '([A-z0-9/=+\-_|]+?)'""".toRegex() } @@ -197,82 +163,6 @@ object Regexes { } - - val EDUDZIENNIK_STUDENTS_START by lazy { - """
  • (.*?)""".toRegex() - } - val EDUDZIENNIK_ACCOUNT_NAME_START by lazy { - """(.*?)""".toRegex() - } - val EDUDZIENNIK_SUBJECTS_START by lazy { - """(.+?)""".toRegex() - } - - val EDUDZIENNIK_ATTENDANCE_ENTRIES by lazy { - """(.+?)""".toRegex() - } - val EDUDZIENNIK_ATTENDANCE_TYPES by lazy { - """
    .*?

    (.*?)

    """.toRegex(DOT_MATCHES_ALL) - } - val EDUDZIENNIK_ATTENDANCE_TYPE by lazy { - """\((.+?)\) (.+)""".toRegex() - } - - val EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION by lazy { - """
    .*?

    (.*?)

    """.toRegex(DOT_MATCHES_ALL) - } - val EDUDZIENNIK_HOMEWORK_DESCRIPTION by lazy { - """
    (.*?)
    """.toRegex(DOT_MATCHES_ALL) - } - - val EDUDZIENNIK_SUBJECT_ID by lazy { - """/Courses/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_GRADE_ID by lazy { - """/Grades/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_EXAM_ID by lazy { - """/Evaluations/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_EVENT_TYPE_ID by lazy { - """/GradeLabels/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_ANNOUNCEMENT_ID by lazy { - """/Announcement/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_HOMEWORK_ID by lazy { - """/Homework/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_TEACHER_ID by lazy { - """/Teachers/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_EVENT_ID by lazy { - """/KlassEvent/([\w-_]+?)/""".toRegex() - } - val EDUDZIENNIK_NOTE_ID by lazy { - """/RegistryNotes/([\w-_]+?)/""".toRegex() - } - - val EDUDZIENNIK_SCHOOL_DETAIL_ID by lazy { - """.*?

    (.*?)

    .*?
  • """.toRegex(DOT_MATCHES_ALL) - } - val EDUDZIENNIK_CLASS_DETAIL_ID by lazy { - """(.*?)""".toRegex(DOT_MATCHES_ALL) - } - - val EDUDZIENNIK_TEACHERS by lazy { - """
    .*?

    (.+?) (.+?)

    """.toRegex(DOT_MATCHES_ALL) - } - - - - val LINKIFY_DATE_YMD by lazy { """(1\d{3}|20\d{2})[\-./](1[0-2]|0?\d)[\-./]([1-2]\d|3[0-1]|0?\d)""".toRegex() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt index ab27dda9..0b49e38b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/EdziennikTask.kt @@ -8,7 +8,6 @@ import com.google.gson.JsonObject import org.greenrobot.eventbus.EventBus import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.* -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik 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.podlasie.Podlasie @@ -112,7 +111,6 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback) LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback) - LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback) LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback) LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback) else -> null diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt deleted file mode 100644 index 76b0e9fd..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/DataEdudziennik.kt +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik - -import pl.szczodrzynski.edziennik.App -import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB -import pl.szczodrzynski.edziennik.data.api.models.Data -import pl.szczodrzynski.edziennik.data.db.entity.EventType -import pl.szczodrzynski.edziennik.data.db.entity.LoginStore -import pl.szczodrzynski.edziennik.data.db.entity.Profile -import pl.szczodrzynski.edziennik.ext.* - -/** - * Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art - * - * Use https://codepen.io/kubasz/pen/RwwwbGN to easily generate the student data getters/setters - */ -class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) { - - fun isWebLoginValid() = webSessionIdExpiryTime-30 > currentTimeUnix() && webSessionId.isNotNullNorEmpty() - - override fun satisfyLoginMethods() { - loginMethods.clear() - if (isWebLoginValid()) { - loginMethods += LOGIN_METHOD_EDUDZIENNIK_WEB - } - } - - override fun generateUserCode() = "$schoolName:$loginEmail:${studentId?.crc32()}" - - private var mLoginEmail: String? = null - var loginEmail: String? - get() { mLoginEmail = mLoginEmail ?: loginStore.getLoginData("email", null); return mLoginEmail } - set(value) { loginStore.putLoginData("email", value); mLoginEmail = value } - - private var mLoginPassword: String? = null - var loginPassword: String? - get() { mLoginPassword = mLoginPassword ?: loginStore.getLoginData("password", null); return mLoginPassword } - set(value) { loginStore.putLoginData("password", value); mLoginPassword = 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 mSchoolId: String? = null - var schoolId: String? - get() { mSchoolId = mSchoolId ?: profile?.getStudentData("schoolId", null); return mSchoolId } - set(value) { profile?.putStudentData("schoolId", value) ?: return; mSchoolId = value } - - private var mClassId: String? = null - var classId: String? - get() { mClassId = mClassId ?: profile?.getStudentData("classId", null); return mClassId } - set(value) { profile?.putStudentData("classId", value) ?: return; mClassId = 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 mWebSessionIdExpiryTime: Long? = null - var webSessionIdExpiryTime: Long - get() { mWebSessionIdExpiryTime = mWebSessionIdExpiryTime ?: loginStore.getLoginData("webSessionIdExpiryTime", 0L); return mWebSessionIdExpiryTime ?: 0L } - set(value) { loginStore.putLoginData("webSessionIdExpiryTime", value); mWebSessionIdExpiryTime = value } - - /* ____ _ _ - / __ \| | | | - | | | | |_| |__ ___ _ __ - | | | | __| '_ \ / _ \ '__| - | |__| | |_| | | | __/ | - \____/ \__|_| |_|\___|*/ - private var mCurrentSemester: Int? = null - var currentSemester: Int - get() { mCurrentSemester = mCurrentSemester ?: profile?.getStudentData("currentSemester", 1); return mCurrentSemester ?: 1 } - set(value) { profile?.putStudentData("currentSemester", value) ?: return; mCurrentSemester = value } - - private var mSchoolName: String? = null - var schoolName: String? - get() { mSchoolName = mSchoolName ?: profile?.getStudentData("schoolName", null); return mSchoolName } - set(value) { profile?.putStudentData("schoolName", value) ?: return; mSchoolName = value } - - val studentEndpoint: String - get() = "Students/$studentId/" - - val schoolEndpoint: String - get() = "Schools/$schoolId/" - - val classStudentEndpoint: String - get() = "Class/$studentId/" - - val schoolClassEndpoint: String - get() = "Schools/$classId/" - - val studentAndClassEndpoint: String - get() = "Students/$studentId/Klass/$classId/" - - val studentAndClassesEndpoint: String - get() = "Students/$studentId/Classes/$classId/" - - val timetableEndpoint: String - get() = "Plan/$studentId/" - - val studentAndTeacherClassEndpoint: String - get() = "Students/$studentId/Teachers/$classId/" - - val courseStudentEndpoint: String - get() = "Course/$studentId/" - - fun getEventType(longId: String, name: String): EventType { - val id = longId.crc16().toLong() - return eventTypes.singleOrNull { it.id == id } ?: run { - val eventType = EventType(profileId, id, name, colorFromName(name)) - eventTypes.put(id, eventType) - eventType - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt deleted file mode 100644 index 23d9d3b1..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/Edudziennik.kt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik - -import com.google.gson.JsonObject -import pl.szczodrzynski.edziennik.App -import pl.szczodrzynski.edziennik.data.api.* -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetHomework -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb -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.LoginStore -import pl.szczodrzynski.edziennik.data.db.entity.Profile -import pl.szczodrzynski.edziennik.data.db.entity.Teacher -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 Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { - companion object { - private const val TAG = "Edudziennik" - } - - val internalErrorList = mutableListOf() - val data: DataEdudziennik - private var afterLogin: (() -> Unit)? = null - - init { - data = DataEdudziennik(app, profile, loginStore).apply { - callback = wrapCallback(this@Edudziennik.callback) - satisfyLoginMethods() - } - } - - private fun completed() { - data.saveData() - callback.onCompleted() - } - - /* _______ _ _ _ _ _ - |__ __| | /\ | | (_) | | | - | | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___ - | | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \ - | | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | | - |_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_| - __/ | - |__*/ - override fun sync(featureIds: List, viewId: Int?, onlyEndpoints: List?, arguments: JsonObject?) { - data.arguments = arguments - data.prepare(edudziennikLoginMethods, EdudziennikFeatures, 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(edudziennikLoginMethods, it) } - afterLogin?.let { this.afterLogin = it } - EdudziennikLogin(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() ?: EdudziennikData(data) { - completed() - } - } - - override fun getMessage(message: MessageFull) {} - override fun sendMessage(recipients: List, subject: String, text: String) {} - override fun markAllAnnouncementsAsRead() {} - - override fun getAnnouncement(announcement: AnnouncementFull) { - EdudziennikLoginWeb(data) { - EdudziennikWebGetAnnouncement(data, announcement) { - completed() - } - } - } - - override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {} - override fun getRecipientList() {} - - override fun getEvent(eventFull: EventFull) { - EdudziennikLoginWeb(data) { - EdudziennikWebGetHomework(data, eventFull) { - completed() - } - } - } - - override fun firstLogin() { EdudziennikFirstLogin(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_EDUDZIENNIK_WEB_SESSION_EXPIRED -> { - login() - } - ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID -> { - login() - } - ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS -> { - data() - } - else -> callback.onError(apiError) - } - } - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt deleted file mode 100644 index c3fd17ed..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/EdudziennikFeatures.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-23 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik - -import pl.szczodrzynski.edziennik.data.api.* -import pl.szczodrzynski.edziennik.data.api.models.Feature - -const val ENDPOINT_EDUDZIENNIK_WEB_START = 1000 -const val ENDPOINT_EDUDZIENNIK_WEB_TEACHERS = 1001 -const val ENDPOINT_EDUDZIENNIK_WEB_GRADES = 1011 -const val ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE = 1012 -const val ENDPOINT_EDUDZIENNIK_WEB_EXAMS = 1013 -const val ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE = 1014 -const val ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS = 1015 -const val ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK = 1016 -const val ENDPOINT_EDUDZIENNIK_WEB_EVENTS = 1017 -const val ENDPOINT_EDUDZIENNIK_WEB_NOTES = 1018 -const val ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER = 1030 - -val EdudziennikFeatures = listOf( - /* School and team info and subjects */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_STUDENT_INFO, listOf( - ENDPOINT_EDUDZIENNIK_WEB_START to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Teachers */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TEACHERS, listOf( - ENDPOINT_EDUDZIENNIK_WEB_TEACHERS to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Timetable */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TIMETABLE, listOf( - ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Grades */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_GRADES, listOf( - ENDPOINT_EDUDZIENNIK_WEB_GRADES to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Agenda */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_AGENDA, listOf( - ENDPOINT_EDUDZIENNIK_WEB_EXAMS to LOGIN_METHOD_EDUDZIENNIK_WEB, - ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB, - ENDPOINT_EDUDZIENNIK_WEB_EVENTS to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Homework */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_HOMEWORK, listOf( - ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Behaviour */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_BEHAVIOUR, listOf( - ENDPOINT_EDUDZIENNIK_WEB_NOTES to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Attendance */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ATTENDANCE, listOf( - ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Announcements */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ANNOUNCEMENTS, listOf( - ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)), - - /* Lucky number */ - Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_LUCKY_NUMBER, listOf( - ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER to LOGIN_METHOD_EDUDZIENNIK_WEB - ), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)) -) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt deleted file mode 100644 index 7eb58d1c..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikData.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data - -import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.* -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.* -import pl.szczodrzynski.edziennik.utils.Utils - -class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) { - companion object { - private const val TAG = "EdudziennikData" - } - - 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_EDUDZIENNIK_WEB_START -> { - data.startProgress(R.string.edziennik_progress_endpoint_data) - EdudziennikWebStart(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> { - data.startProgress(R.string.edziennik_progress_endpoint_teachers) - EdudziennikWebTeachers(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_GRADES -> { - data.startProgress(R.string.edziennik_progress_endpoint_grades) - EdudziennikWebGrades(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> { - data.startProgress(R.string.edziennik_progress_endpoint_timetable) - EdudziennikWebTimetable(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> { - data.startProgress(R.string.edziennik_progress_endpoint_exams) - EdudziennikWebExams(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> { - data.startProgress(R.string.edziennik_progress_endpoint_attendance) - EdudziennikWebAttendance(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> { - data.startProgress(R.string.edziennik_progress_endpoint_announcements) - EdudziennikWebAnnouncements(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> { - data.startProgress(R.string.edziennik_progress_endpoint_homework) - EdudziennikWebHomework(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> { - data.startProgress(R.string.edziennik_progress_endpoint_events) - EdudziennikWebEvents(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_NOTES -> { - data.startProgress(R.string.edziennik_progress_endpoint_notices) - EdudziennikWebNotes(data, lastSync, onSuccess) - } - ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> { - data.startProgress(R.string.edziennik_progress_endpoint_lucky_number) - EdudziennikWebLuckyNumber(data, lastSync, onSuccess) - } - else -> onSuccess(endpointId) - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt deleted file mode 100644 index f5adfc5d..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/EdudziennikWeb.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data - -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.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.models.ApiError -import pl.szczodrzynski.edziennik.utils.Utils.d -import pl.szczodrzynski.edziennik.utils.models.Date - -open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Long?) { - companion object { - private const val TAG = "EdudziennikWeb" - } - - val profileId - get() = data.profile?.id ?: -1 - - val profile - get() = data.profile - - fun webGet(tag: String, endpoint: String, xhr: Boolean = false, semester: Int? = null, onSuccess: (text: String) -> Unit) { - val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) { - true -> endpoint - else -> "$endpoint/" - } + (semester?.let { "?semester=" + if(it == -1) "all" else it } ?: "") - - d(tag, "Request: Edudziennik/Web - $url") - - val callback = object : TextCallbackHandler() { - override fun onSuccess(text: String?, response: Response?) { - if (text == null || response == null) { - data.error(ApiError(tag, ERROR_RESPONSE_EMPTY) - .withResponse(response)) - return - } - - if (semester == null && url.contains("start")) { - profile?.also { profile -> - val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com") - val semesterCookie = cookies["semester"]?.toIntOrNull() - - semesterCookie?.let { data.currentSemester = it } - - if (semesterCookie == 2 && profile.dateSemester2Start > Date.getToday()) - profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1) - } - } - - try { - onSuccess(text) - } catch (e: Exception) { - data.error(ApiError(tag, EXCEPTION_EDUDZIENNIK_WEB_REQUEST) - .withThrowable(e) - .withResponse(response) - .withApiResponse(text)) - } - } - - override fun onFailure(response: Response?, throwable: Throwable?) { - val error = when (response?.code()) { - 402 -> ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS - 403 -> ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED - else -> ERROR_REQUEST_FAILURE - } - data.error(ApiError(tag, error) - .withResponse(response) - .withThrowable(throwable)) - } - } - - data.app.cookieJar.set("dziennikel.appspot.com", "sessionid", data.webSessionId) - - Request.builder() - .url(url) - .userAgent(EDUDZIENNIK_USER_AGENT) - .apply { - if (xhr) header("X-Requested-With", "XMLHttpRequest") - } - .get() - .callback(callback) - .build() - .enqueue() - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt deleted file mode 100644 index a577a123..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAnnouncements.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-26 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ANNOUNCEMENT_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebAnnouncements(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - const val TAG = "EdudziennikWebAnnouncements" - } - - init { data.profile?.also { profile -> - webGet(TAG, data.schoolClassEndpoint + "Announcements") { text -> - val doc = Jsoup.parse(text) - - if (doc.getElementsByClass("message").text().trim() != "Brak ogłoszeń.") { - doc.select("table.list tbody tr").forEach { announcementElement -> - val titleElement = announcementElement.child(0).child(0) - - val longId = EDUDZIENNIK_ANNOUNCEMENT_ID.find(titleElement.attr("href"))?.get(1) - ?: return@forEach - val id = longId.crc32() - val subject = titleElement.text() - - val teacherName = announcementElement.child(1).text() - val teacher = data.getTeacherByFirstLast(teacherName) - - val dateString = announcementElement.getElementsByClass("datetime").first()?.text() - val startDate = Date.fromY_m_d(dateString) - val addedDate = Date.fromIsoHm(dateString) - - val announcementObject = Announcement( - profileId = profileId, - id = id, - subject = subject, - text = null, - startDate = startDate, - endDate = null, - teacherId = teacher.id, - addedDate = addedDate - ).also { - it.idString = longId - } - - data.announcementList.add(announcementObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_ANNOUNCEMENT, - id, - profile.empty, - profile.empty - )) - } - } - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt deleted file mode 100644 index 02ba0c85..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebAttendance.kt +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-24 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_ENTRIES -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPE -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPES -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.data.db.entity.Attendance -import pl.szczodrzynski.edziennik.data.db.entity.Metadata -import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS -import pl.szczodrzynski.edziennik.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.ext.singleOrNull -import pl.szczodrzynski.edziennik.utils.models.Date -import java.util.* - -class EdudziennikWebAttendance(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebAttendance" - } - - private var requestSemester: Int? = null - - init { - if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1 - getAttendances() - } - - private fun getAttendances() { data.profile?.also { profile -> - webGet(TAG, data.studentEndpoint + "Presence", semester = requestSemester) { text -> - - val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map { - val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim()) - val symbol = type?.get(1)?.trim() ?: "?" - val name = type?.get(2)?.trim() ?: "nieznany rodzaj" - return@map Triple( - symbol, - name, - when (name.lowercase()) { - "obecność" -> Attendance.TYPE_PRESENT - "nieobecność" -> Attendance.TYPE_ABSENT - "spóźnienie" -> Attendance.TYPE_BELATED - "nieobecność usprawiedliwiona" -> Attendance.TYPE_ABSENT_EXCUSED - "dzień wolny" -> Attendance.TYPE_DAY_FREE - "brak zajęć" -> Attendance.TYPE_DAY_FREE - "oddelegowany" -> Attendance.TYPE_RELEASED - else -> Attendance.TYPE_UNKNOWN - } - ) - } ?: emptyList() - - EDUDZIENNIK_ATTENDANCE_ENTRIES.findAll(text).forEach { attendanceElement -> - val date = Date.fromY_m_d(attendanceElement[1]) - val lessonNumber = attendanceElement[2].toInt() - val attendanceSymbol = attendanceElement[3] - - val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date) - val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber } - - val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32() - - val (typeSymbol, typeName, baseType) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol } - ?: return@forEach - - val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime - ?: return@forEach - - val attendanceObject = Attendance( - profileId = profileId, - id = id, - baseType = baseType, - typeName = typeName, - typeShort = data.app.attendanceManager.getTypeShort(baseType), - typeSymbol = typeSymbol, - typeColor = null, - date = date, - startTime = lesson?.displayStartTime ?: startTime, - semester = profile.currentSemester, - teacherId = lesson?.displayTeacherId ?: -1, - subjectId = lesson?.displaySubjectId ?: -1 - ).also { - it.lessonNumber = lessonNumber - } - - data.attendanceList.add(attendanceObject) - if (baseType != Attendance.TYPE_PRESENT) { - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_ATTENDANCE, - id, - profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN, - profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN - )) - } - } - - if (profile.empty && requestSemester == 1 && data.currentSemester == 2) { - requestSemester = null - getAttendances() - } else { - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) - } - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt deleted file mode 100644 index a296723c..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebEvents.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2020-1-1 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EVENTS -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebEvents(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - const val TAG = "EdudziennikWebEvents" - } - - init { data.profile?.also { profile -> - webGet(TAG, data.studentAndClassesEndpoint + "KlassEvent", xhr = true) { text -> - val doc = Jsoup.parseBodyFragment("" + text.trim() + "
    ") - - doc.getElementsByTag("tr").forEach { eventElement -> - val date = Date.fromY_m_d(eventElement.child(1).text()) - - val titleElement = eventElement.child(2).child(0) - val title = titleElement.text().trim() - - val id = EDUDZIENNIK_EVENT_ID.find(titleElement.attr("href"))?.get(1)?.crc32() - ?: return@forEach - - val eventObject = Event( - profileId = profileId, - id = id, - date = date, - time = null, - topic = title, - color = null, - type = Event.TYPE_CLASS_EVENT, - teacherId = -1, - subjectId = -1, - teamId = data.teamClass?.id ?: -1 - ) - - data.eventList.add(eventObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_EVENT, - id, - profile.empty, - profile.empty - )) - } - - data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT)) - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt deleted file mode 100644 index a30cb421..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebExams.kt +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-24 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_TYPE_ID -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EXAM_ID -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebExams(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - const val TAG = "EdudziennikWebExams" - } - - init { profile?.also { profile -> - webGet(TAG, data.studentAndClassEndpoint + "Evaluations", xhr = true) { text -> - val doc = Jsoup.parseBodyFragment("" + text.trim() + "
    ") - - doc.select("tr").forEach { examElement -> - val id = EDUDZIENNIK_EXAM_ID.find(examElement.child(0).child(0).attr("href")) - ?.get(1)?.crc32() ?: return@forEach - val topic = examElement.child(0).text().trim() - - val subjectElement = examElement.child(1).child(0) - val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1) - ?: return@forEach - val subjectName = subjectElement.text().trim() - val subject = data.getSubject(subjectId.crc32(), subjectName) - - val dateString = examElement.child(2).text().trim() - if (dateString.isBlank()) return@forEach - val date = Date.fromY_m_d(dateString) - - val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date) - val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime - - val eventTypeElement = examElement.child(3).child(0) - val eventTypeId = EDUDZIENNIK_EVENT_TYPE_ID.find(eventTypeElement.attr("href"))?.get(1) - ?: return@forEach - val eventTypeName = eventTypeElement.text() - val eventType = data.getEventType(eventTypeId, eventTypeName) - - val eventObject = Event( - profileId = profileId, - id = id, - date = date, - time = startTime, - topic = topic, - color = null, - type = eventType.id, - teacherId = -1, - subjectId = subject.id, - teamId = data.teamClass?.id ?: -1 - ) - - data.eventList.add(eventObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_EVENT, - id, - profile.empty, - profile.empty - )) - } - - data.toRemove.add(DataRemoveModel.Events.futureExceptTypes(listOf( - Event.TYPE_HOMEWORK, - Event.TYPE_CLASS_EVENT - ))) - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EXAMS) - } - }} -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt deleted file mode 100644 index 5584b555..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetAnnouncement.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-26 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.greenrobot.eventbus.EventBus -import pl.szczodrzynski.edziennik.data.api.Regexes -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent -import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull -import pl.szczodrzynski.edziennik.ext.get - -class EdudziennikWebGetAnnouncement(override val data: DataEdudziennik, - private val announcement: AnnouncementFull, - val onSuccess: () -> Unit -) : EdudziennikWeb(data, null) { - companion object { - const val TAG = "EdudziennikWebGetAnnouncement" - } - - init { - webGet(TAG, "Announcement/${announcement.idString}") { text -> - val description = Regexes.EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION.find(text)?.get(1)?.trim() ?: "" - - announcement.text = description - - EventBus.getDefault().postSticky(AnnouncementGetEvent(announcement)) - - data.announcementList.add(announcement) - onSuccess() - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt deleted file mode 100644 index d6c568ab..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGetHomework.kt +++ /dev/null @@ -1,47 +0,0 @@ -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.greenrobot.eventbus.EventBus -import pl.szczodrzynski.edziennik.data.api.Regexes -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent -import pl.szczodrzynski.edziennik.data.db.full.EventFull -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty -import pl.szczodrzynski.edziennik.utils.html.BetterHtml - -class EdudziennikWebGetHomework( - override val data: DataEdudziennik, - val event: EventFull, - val onSuccess: () -> Unit -) : EdudziennikWeb(data, null) { - companion object { - const val TAG = "EdudziennikWebGetHomework" - } - - init { - if (event.attachmentNames.isNotNullNorEmpty()) { - val id = event.attachmentNames!![0] - - webGet(TAG, "Homework/$id") { text -> - val description = Regexes.EDUDZIENNIK_HOMEWORK_DESCRIPTION.find(text)?.get(1)?.trim() - - if (description != null) - event.topic = BetterHtml.fromHtml(context = null, description).toString() - - event.homeworkBody = "" - event.isDownloaded = true - event.attachmentNames = null - - data.eventList += event - data.eventListReplace = true - - EventBus.getDefault().postSticky(EventGetEvent(event)) - onSuccess() - } - } else { - EventBus.getDefault().postSticky(EventGetEvent(event)) - onSuccess() - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt deleted file mode 100644 index 3ffba09b..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebGrades.kt +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-25 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import android.graphics.Color -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_GRADES -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.Grade.Companion.TYPE_POINT_SUM -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.SYNC_ALWAYS -import pl.szczodrzynski.edziennik.ext.colorFromCssName -import pl.szczodrzynski.edziennik.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.Utils -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebGrades(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebGrades" - } - - private var requestSemester: Int? = null - - init { - if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1 - getGrades() - } - - private fun getGrades() { data.profile?.also { profile -> - webGet(TAG, data.studentEndpoint + "start", semester = requestSemester) { text -> - val semester = requestSemester ?: data.currentSemester - - val doc = Jsoup.parse(text) - val subjects = doc.select("#student_grades tbody").firstOrNull()?.children() - - subjects?.forEach { subjectElement -> - if (subjectElement.id().isBlank()) return@forEach - - val subjectId = subjectElement.id().trim() - val subjectName = subjectElement.child(0).text().trim() - val subject = data.getSubject(subjectId.crc32(), subjectName) - - val gradeType = when { - subjectElement.select("#sum").text().isNotBlank() -> TYPE_POINT_SUM - else -> TYPE_NORMAL - } - - val gradeCountToAverage = subjectElement.select("#avg").text().isNotBlank() - - val grades = subjectElement.select(".grade[data-edited]") - val gradesInfo = subjectElement.select(".grade-tip") - - val gradeValues = if (grades.isNotEmpty()) { - subjects.select(".avg-$subjectId .grade-tip > p").first() - ?.text()?.split('+')?.map { - val split = it.split('*') - val value = split[1].trim().toFloatOrNull() - val weight = value?.let { split[0].trim().toFloatOrNull() } ?: 0f - - Pair(value ?: 0f, weight) - } ?: emptyList() - } else emptyList() - - grades.forEachIndexed { index, gradeElement -> - val id = Regexes.EDUDZIENNIK_GRADE_ID.find(gradeElement.attr("href"))?.get(1)?.crc32() - ?: return@forEachIndexed - val (value, weight) = gradeValues[index] - val name = gradeElement.text().trim().let { - if (it.contains(',') || it.contains('.')) { - val replaced = it.replace(',', '.') - val float = replaced.toFloatOrNull() - - if (float != null && float % 1 == 0f) float.toInt().toString() - else it - } else it - } - - val info = gradesInfo[index] - val fullName = info.child(0).text().trim() - val columnName = info.child(4).text().trim() - val comment = info.ownText() - - val description = columnName + if (comment.isNotBlank()) " - $comment" else null - - val teacherName = info.child(1).text() - val teacher = data.getTeacherByLastFirst(teacherName) - - val addedDate = info.child(2).text().split(' ').let { - val day = it[0].toInt() - val month = Utils.monthFromName(it[1]) - val year = it[2].toInt() - - Date(year, month, day).inMillis - } - - val color = Regexes.STYLE_CSS_COLOR.find(gradeElement.attr("style"))?.get(1)?.let { - if (it.startsWith('#')) Color.parseColor(it) - else colorFromCssName(it) - } ?: -1 - - val gradeObject = Grade( - profileId = profileId, - id = id, - name = name, - type = gradeType, - value = value, - weight = if (gradeCountToAverage) weight else 0f, - color = color, - category = fullName, - description = description, - comment = null, - semester = semester, - teacherId = teacher.id, - subjectId = subject.id, - addedDate = addedDate - ) - - data.gradeList.add(gradeObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_GRADE, - id, - profile.empty, - profile.empty - )) - } - - val proposed = subjectElement.select(".proposal").firstOrNull()?.text()?.trim() - - if (proposed != null && proposed.isNotBlank()) { - val proposedGradeObject = Grade( - profileId = profileId, - id = (-1 * subject.id) - 1, - name = proposed, - type = when (semester) { - 1 -> TYPE_SEMESTER1_PROPOSED - else -> TYPE_SEMESTER2_PROPOSED - }, - value = proposed.toFloatOrNull() ?: 0f, - weight = 0f, - color = -1, - category = null, - description = null, - comment = null, - semester = semester, - teacherId = -1, - subjectId = subject.id - ) - - data.gradeList.add(proposedGradeObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_GRADE, - proposedGradeObject.id, - profile.empty, - profile.empty - )) - } - - val final = subjectElement.select(".final").firstOrNull()?.text()?.trim() - - if (final != null && final.isNotBlank()) { - val finalGradeObject = Grade( - profileId = profileId, - id = (-1 * subject.id) - 2, - name = final, - type = when (semester) { - 1 -> TYPE_SEMESTER1_FINAL - else -> TYPE_SEMESTER2_FINAL - }, - value = final.toFloatOrNull() ?: 0f, - weight = 0f, - color = -1, - category = null, - description = null, - comment = null, - semester = semester, - teacherId = -1, - subjectId = subject.id - ) - - data.gradeList.add(finalGradeObject) - data.metadataList.add(Metadata( - data.profileId, - Metadata.TYPE_GRADE, - finalGradeObject.id, - profile.empty, - profile.empty - )) - } - } - - if (!subjects.isNullOrEmpty()) { - data.toRemove.addAll(listOf( - TYPE_NORMAL, - TYPE_POINT_SUM, - TYPE_SEMESTER1_PROPOSED, - TYPE_SEMESTER2_PROPOSED, - TYPE_SEMESTER1_FINAL, - TYPE_SEMESTER2_FINAL - ).map { - DataRemoveModel.Grades.semesterWithType(semester, it) - }) - } - - if (profile.empty && requestSemester == 1 && data.currentSemester == 2) { - requestSemester = null - getGrades() - } else { - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) - } - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt deleted file mode 100644 index 176c6d3d..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebHomework.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-29 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_HOMEWORK_ID -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebHomework(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - const val TAG = "EdudziennikWebHomework" - } - - init { data.profile?.also { profile -> - webGet(TAG, data.courseStudentEndpoint + "Homework", xhr = true) { text -> - val doc = Jsoup.parseBodyFragment("" + text.trim() + "
    ") - - if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") { - doc.getElementsByTag("tr").forEach { homeworkElement -> - val dateElement = homeworkElement.getElementsByClass("date").first()?.child(0) ?: return@forEach - val idStr = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1) ?: return@forEach - val id = idStr.crc32() - val date = Date.fromY_m_d(dateElement.text()) - - val subjectElement = homeworkElement.child(1).child(0) - val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1) - ?: return@forEach - val subjectName = subjectElement.text() - val subject = data.getSubject(subjectId.crc32(), subjectName) - - val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date) - val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime - - val teacherName = homeworkElement.child(2).text() - val teacher = data.getTeacherByFirstLast(teacherName) - - val topic = homeworkElement.child(4).text().trim() - - val eventObject = Event( - profileId = profileId, - id = id, - date = date, - time = startTime, - topic = topic ?: "", - color = null, - type = Event.TYPE_HOMEWORK, - teacherId = teacher.id, - subjectId = subject.id, - teamId = data.teamClass?.id ?: -1 - ) - - eventObject.attachmentNames = mutableListOf(idStr) - - data.eventList.add(eventObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_HOMEWORK, - id, - profile.empty, - profile.empty - )) - } - } - - data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK)) - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt deleted file mode 100644 index db8164c8..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebLuckyNumber.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-23 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.utils.models.Date - -class EdudziennikWebLuckyNumber(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebLuckyNumber" - } - - init { data.profile?.also { profile -> - webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text -> - text.toIntOrNull()?.also { luckyNumber -> - val luckyNumberObject = LuckyNumber( - profileId = profileId, - date = Date.getToday(), - number = luckyNumber - ) - - data.luckyNumberList.add(luckyNumberObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_LUCKY_NUMBER, - luckyNumberObject.date.value.toLong(), - true, - profile.empty - )) - } - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt deleted file mode 100644 index 56457a91..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebNotes.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2020-1-1 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_NOTE_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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 -import pl.szczodrzynski.edziennik.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.utils.models.Date - -class EdudziennikWebNotes(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - const val TAG = "EdudziennikWebNotes" - } - - init { data.profile?.also { profile -> - webGet(TAG, data.classStudentEndpoint + "RegistryNotesStudent", xhr = true) { text -> - val doc = Jsoup.parseBodyFragment("" + text.trim() + "
    ") - - doc.getElementsByTag("tr").forEach { noteElement -> - val dateElement = noteElement.getElementsByClass("date").first()?.child(0) ?: return@forEach - val addedDate = Date.fromY_m_d(dateElement.text()).inMillis - - val id = EDUDZIENNIK_NOTE_ID.find(dateElement.attr("href"))?.get(0)?.crc32() - ?: return@forEach - - val teacherName = noteElement.child(1).text() - val teacher = data.getTeacherByFirstLast(teacherName) - - val description = noteElement.child(3).text() - - val noticeObject = Notice( - profileId = profileId, - id = id, - type = Notice.TYPE_NEUTRAL, - semester = profile.currentSemester, - text = description, - category = null, - points = null, - teacherId = teacher.id, - addedDate = addedDate - ) - - data.noticeList.add(noticeObject) - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_NOTICE, - id, - profile.empty, - profile.empty - )) - } - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt deleted file mode 100644 index e415986c..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebStart.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-23 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import pl.szczodrzynski.edziennik.data.api.ERROR_EDUDZIENNIK_WEB_TEAM_MISSING -import pl.szczodrzynski.edziennik.data.api.Regexes -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECTS_START -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_START -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.data.api.models.ApiError -import pl.szczodrzynski.edziennik.data.db.entity.Team -import pl.szczodrzynski.edziennik.ext.MONTH -import pl.szczodrzynski.edziennik.ext.crc32 -import pl.szczodrzynski.edziennik.ext.firstLettersName -import pl.szczodrzynski.edziennik.ext.get - -class EdudziennikWebStart(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebStart" - } - - init { - webGet(TAG, data.studentEndpoint + "start") { text -> - getSchoolAndTeam(text) - getSubjects(text) - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_START) - } - } - - private fun getSchoolAndTeam(text: String) { - val schoolId = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)?.trim() - val schoolLongName = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_NAME.find(text)?.get(1)?.trim() - data.schoolId = schoolId - - val classId = Regexes.EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)?.trim() - val className = Regexes.EDUDZIENNIK_CLASS_DETAIL_NAME.find(text)?.get(1)?.trim() - data.classId = classId - - if (classId == null || className == null || schoolId == null || schoolLongName == null) { - data.error(ApiError(TAG, ERROR_EDUDZIENNIK_WEB_TEAM_MISSING) - .withApiResponse(text)) - return - } - - val schoolName = schoolId.crc32().toString() + schoolLongName.firstLettersName + "_edu" - data.schoolName = schoolName - - val teamId = classId.crc32() - val teamCode = "$schoolName:$className" - - val teamObject = Team( - data.profileId, - teamId, - className, - Team.TYPE_CLASS, - teamCode, - -1 - ) - - data.teamClass = teamObject - data.teamList.put(teamObject.id, teamObject) - } - - private fun getSubjects(text: String) { - EDUDZIENNIK_SUBJECTS_START.findAll(text).forEach { - val id = it[1].trim() - val name = it[2].trim() - data.getSubject(id.crc32(), name) - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt deleted file mode 100644 index 115f9919..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTeachers.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-25 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHERS -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.ext.MONTH -import pl.szczodrzynski.edziennik.ext.get - -class EdudziennikWebTeachers(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebTeachers" - } - - init { - webGet(TAG, data.studentAndTeacherClassEndpoint + "grid") { text -> - EDUDZIENNIK_TEACHERS.findAll(text).forEach { - val lastName = it[1].trim() - val firstName = it[2].trim() - data.getTeacher(firstName, lastName) - } - - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS) - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt deleted file mode 100644 index 6cab6026..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/data/web/EdudziennikWebTimetable.kt +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-23 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web - -import org.jsoup.Jsoup -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHER_ID -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -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.ext.crc32 -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.ext.getString -import pl.szczodrzynski.edziennik.ext.singleOrNull -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 EdudziennikWebTimetable(override val data: DataEdudziennik, - override val lastSync: Long?, - val onSuccess: (endpointId: Int) -> Unit -) : EdudziennikWeb(data, lastSync) { - companion object { - private const val TAG = "EdudziennikWebTimetable" - } - - 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) - - webGet(TAG, data.timetableEndpoint + "print?date=$getDate") { text -> - val doc = Jsoup.parse(text) - - val dataDays = mutableListOf() - val dataStart = weekStart.clone() - while (dataStart <= weekEnd) { - dataDays += dataStart.value - dataStart.stepForward(0, 0, 1) - } - - val table = doc.select("#Schedule tbody").first() - - if (table?.text()?.contains("Brak planu lekcji.") == false) { - table.children().forEach { row -> - val rowElements = row.children() - - val lessonNumber = rowElements[0].text().toInt() - - val times = rowElements[1].text().split('-') - val startTime = Time.fromH_m(times[0].trim()) - val endTime = Time.fromH_m(times[1].trim()) - - data.lessonRanges.singleOrNull { - it.lessonNumber == lessonNumber && it.startTime == startTime && it.endTime == endTime - } ?: run { - data.lessonRanges.put(lessonNumber, LessonRange(profileId, lessonNumber, startTime, endTime)) - } - - rowElements.subList(2, rowElements.size).forEachIndexed { index, lesson -> - val course = lesson.select(".course").firstOrNull() ?: return@forEachIndexed - val info = course.select("span > span") - - if (info.isEmpty()) return@forEachIndexed - - val type = when (course.hasClass("substitute")) { - true -> Lesson.TYPE_CHANGE - else -> Lesson.TYPE_NORMAL - } - - /* Getting subject */ - - val subjectElement = info[0].child(0) - val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1) - ?: return@forEachIndexed - val subjectName = subjectElement.text().trim() - val subject = data.getSubject(subjectId.crc32(), subjectName) - - /* Getting teacher */ - - val teacherId = if (info.size >= 2) { - val teacherElement = info[1].child(0) - val teacherLongId = EDUDZIENNIK_TEACHER_ID.find(teacherElement.attr("href"))?.get(1) - val teacherName = teacherElement.text().trim() - data.getTeacherByLastFirst(teacherName, teacherLongId).id - } else null - - val lessonObject = Lesson(profileId, -1).also { - it.type = type - it.date = weekStart.clone().stepForward(0, 0, index) - it.lessonNumber = lessonNumber - it.startTime = startTime - it.endTime = endTime - it.subjectId = subject.id - it.teacherId = teacherId - it.teamId = data.teamClass?.id - - it.id = it.buildId() - } - - data.lessonList.add(lessonObject) - dataDays.remove(lessonObject.date!!.value) - - if (type != Lesson.TYPE_NORMAL) { - val seen = profile.empty || lessonObject.date!! < Date.getToday() - - data.metadataList.add(Metadata( - profileId, - Metadata.TYPE_LESSON_CHANGE, - lessonObject.id, - seen, - seen - )) - } - } - } - } - - for (day in dataDays) { - val lessonDate = Date.fromValue(day) - data.lessonList += Lesson(profileId, lessonDate.value.toLong()).apply { - type = Lesson.TYPE_NO_LESSONS - date = lessonDate - } - } - - d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate") - - data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd)) - data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS) - onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) - } - } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt deleted file mode 100644 index 808435af..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/firstlogin/EdudziennikFirstLogin.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin - -import org.greenrobot.eventbus.EventBus -import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_EDUDZIENNIK -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ACCOUNT_NAME_START -import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_STUDENTS_START -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb -import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent -import pl.szczodrzynski.edziennik.data.db.entity.Profile -import pl.szczodrzynski.edziennik.ext.fixName -import pl.szczodrzynski.edziennik.ext.get -import pl.szczodrzynski.edziennik.ext.getShortName -import pl.szczodrzynski.edziennik.ext.set - -class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) { - companion object { - private const val TAG = "EdudziennikFirstLogin" - } - - private val web = EdudziennikWeb(data, null) - private val profileList = mutableListOf() - - init { - val loginStoreId = data.loginStore.id - val loginStoreType = LOGIN_TYPE_EDUDZIENNIK - var firstProfileId = loginStoreId - - EdudziennikLoginWeb(data) { - web.webGet(TAG, "") { text -> - val accountNameLong = EDUDZIENNIK_ACCOUNT_NAME_START.find(text)?.get(1)?.fixName() - - EDUDZIENNIK_STUDENTS_START.findAll(text).forEach { - val studentId = it[1] - val studentNameLong = it[2].fixName() - - if (studentId.isBlank() || studentNameLong.isBlank()) return@forEach - - val studentNameShort = studentNameLong.getShortName() - val accountName = if (accountNameLong == studentNameLong) null else accountNameLong - - val profile = Profile( - firstProfileId++, - loginStoreId, - loginStoreType, - studentNameLong, - data.loginEmail, - studentNameLong, - studentNameShort, - accountName - ).apply { - studentData["studentId"] = studentId - } - profileList.add(profile) - } - - EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore)) - onSuccess() - } - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt deleted file mode 100644 index 1cb2fd07..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLogin.kt +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login - -import pl.szczodrzynski.edziennik.R -import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB -import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.utils.Utils - -class EdudziennikLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) { - companion object { - private const val TAG = "EdudziennikLogin" - } - - 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_EDUDZIENNIK_WEB -> { - data.startProgress(R.string.edziennik_progress_login_edudziennik_web) - EdudziennikLoginWeb(data) { onSuccess(loginMethodId) } - } - } - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt deleted file mode 100644 index d730fe91..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/edudziennik/login/EdudziennikLoginWeb.kt +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) Kacper Ziubryniewicz 2019-12-22 - */ - -package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login - -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.edudziennik.DataEdudziennik -import pl.szczodrzynski.edziennik.data.api.models.ApiError -import pl.szczodrzynski.edziennik.ext.getUnixDate -import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty -import pl.szczodrzynski.edziennik.utils.Utils.d - -class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) { - companion object { - private const val TAG = "EdudziennikLoginWeb" - } - - init { run { - if (data.isWebLoginValid()) { - onSuccess() - } - else { - data.app.cookieJar.clear("dziennikel.appspot.com") - if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) { - loginWithCredentials() - } - else { - data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) - } - } - }} - - private fun loginWithCredentials() { - d(TAG, "Request: Edudziennik/Login/Web - https://dziennikel.appspot.com/login/?next=/") - - val callback = object : TextCallbackHandler() { - override fun onSuccess(text: String?, response: Response?) { - if (text == null || response == null) { - data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) - .withResponse(response)) - return - } - - val url = response.raw().request().url().toString() - - if (!url.contains("Student")) { - when { - text.contains("Wprowadzono nieprawidłową nazwę użytkownika lub hasło.") -> ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN - else -> ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER - }.let { errorCode -> - data.error(ApiError(TAG, errorCode) - .withApiResponse(text) - .withResponse(response)) - return - } - } - - val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com") - val sessionId = cookies["sessionid"] - - if (sessionId == null) { - data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID) - .withResponse(response) - .withApiResponse(text)) - return - } - - data.webSessionId = sessionId - data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */ - onSuccess() - } - - override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) - .withResponse(response) - .withThrowable(throwable)) - } - } - - Request.builder() - .url("https://dziennikel.appspot.com/login/?next=/") - .userAgent(EDUDZIENNIK_USER_AGENT) - .contentType("application/x-www-form-urlencoded") - .addParameter("email", data.loginEmail) - .addParameter("password", data.loginPassword) - .addParameter("auth_method", "password") - .addParameter("next", "/") - .post() - .callback(callback) - .build() - .enqueue() - } -} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt index c6d797fa..0c2bc91c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/DataVulcan.kt @@ -222,15 +222,15 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app get() { mHebeContext = mHebeContext ?: profile?.getStudentData("hebeContext", null); return mHebeContext } set(value) { profile?.putStudentData("hebeContext", value) ?: return; mHebeContext = value } - private var mSenderAddressHash: String? = null - var senderAddressHash: String? - get() { mSenderAddressHash = mSenderAddressHash ?: profile?.getStudentData("senderAddressHash", null); return mSenderAddressHash } - set(value) { profile?.putStudentData("senderAddressHash", value) ?: return; mSenderAddressHash = value } + private var mMessageBoxKey: String? = null + var messageBoxKey: String? + get() { mMessageBoxKey = mMessageBoxKey ?: profile?.getStudentData("messageBoxKey", null); return mMessageBoxKey } + set(value) { profile?.putStudentData("messageBoxKey", value) ?: return; mMessageBoxKey = value } - private var mSenderAddressName: String? = null - var senderAddressName: String? - get() { mSenderAddressName = mSenderAddressName ?: profile?.getStudentData("senderAddressName", null); return mSenderAddressName } - set(value) { profile?.putStudentData("senderAddressName", value) ?: return; mSenderAddressName = value } + private var mMessageBoxName: String? = null + var messageBoxName: String? + get() { mMessageBoxName = mMessageBoxName ?: profile?.getStudentData("messageBoxName", null); return mMessageBoxName } + set(value) { profile?.putStudentData("messageBoxName", value) ?: return; mMessageBoxName = value } val apiUrl: String? get() { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt index 924d7ced..857a596e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/VulcanFeatures.kt @@ -12,6 +12,7 @@ const val ENDPOINT_VULCAN_WEB_LUCKY_NUMBERS = 2010 const val ENDPOINT_VULCAN_HEBE_MAIN = 3000 const val ENDPOINT_VULCAN_HEBE_PUSH_CONFIG = 3005 const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK = 3010 +const val ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 = 3011 const val ENDPOINT_VULCAN_HEBE_TIMETABLE = 3020 const val ENDPOINT_VULCAN_HEBE_EXAMS = 3030 const val ENDPOINT_VULCAN_HEBE_GRADES = 3040 @@ -19,10 +20,11 @@ const val ENDPOINT_VULCAN_HEBE_GRADE_SUMMARY = 3050 const val ENDPOINT_VULCAN_HEBE_HOMEWORK = 3060 const val ENDPOINT_VULCAN_HEBE_NOTICES = 3070 const val ENDPOINT_VULCAN_HEBE_ATTENDANCE = 3080 -const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3090 -const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3100 const val ENDPOINT_VULCAN_HEBE_TEACHERS = 3110 const val ENDPOINT_VULCAN_HEBE_LUCKY_NUMBER = 3200 +const val ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES = 3500 +const val ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX = 3510 +const val ENDPOINT_VULCAN_HEBE_MESSAGES_SENT = 3520 val VulcanFeatures = listOf( // timetable @@ -85,6 +87,8 @@ val VulcanFeatures = listOf( Feature(LOGIN_TYPE_VULCAN, FEATURE_ALWAYS_NEEDED, listOf( ENDPOINT_VULCAN_HEBE_MAIN to LOGIN_METHOD_VULCAN_HEBE, ENDPOINT_VULCAN_HEBE_ADDRESSBOOK to LOGIN_METHOD_VULCAN_HEBE, - ENDPOINT_VULCAN_HEBE_TEACHERS to LOGIN_METHOD_VULCAN_HEBE + ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 to LOGIN_METHOD_VULCAN_HEBE, + ENDPOINT_VULCAN_HEBE_TEACHERS to LOGIN_METHOD_VULCAN_HEBE, + ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES to LOGIN_METHOD_VULCAN_HEBE, ), listOf(LOGIN_METHOD_VULCAN_HEBE)) ) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt index 6170d817..4b3f961f 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanData.kt @@ -21,10 +21,12 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) { ENDPOINT_VULCAN_HEBE_MAIN, ENDPOINT_VULCAN_HEBE_PUSH_CONFIG, ENDPOINT_VULCAN_HEBE_ADDRESSBOOK, + ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2, ENDPOINT_VULCAN_HEBE_TIMETABLE, ENDPOINT_VULCAN_HEBE_EXAMS, ENDPOINT_VULCAN_HEBE_HOMEWORK, ENDPOINT_VULCAN_HEBE_NOTICES, + ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES, ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX, ENDPOINT_VULCAN_HEBE_MESSAGES_SENT, ENDPOINT_VULCAN_HEBE_TEACHERS, @@ -107,6 +109,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) { data.startProgress(R.string.edziennik_progress_endpoint_addressbook) VulcanHebeAddressbook(data, lastSync, onSuccess) } + ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 -> { + data.startProgress(R.string.edziennik_progress_endpoint_addressbook) + VulcanHebeAddressbook2(data, lastSync, onSuccess) + } ENDPOINT_VULCAN_HEBE_TEACHERS -> { data.startProgress(R.string.edziennik_progress_endpoint_teachers) VulcanHebeTeachers(data, lastSync, onSuccess) @@ -139,6 +145,10 @@ class VulcanData(val data: DataVulcan, val onSuccess: () -> Unit) { data.startProgress(R.string.edziennik_progress_endpoint_attendance) VulcanHebeAttendance(data, lastSync, onSuccess) } + ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES -> { + data.startProgress(R.string.edziennik_progress_endpoint_messages) + VulcanHebeMessageBoxes(data, lastSync, onSuccess) + } ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX -> { data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox) VulcanHebeMessages(data, lastSync, onSuccess).getMessages(Message.TYPE_RECEIVED) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt index 457306c2..a99ac7a4 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/VulcanHebe.kt @@ -14,7 +14,6 @@ import im.wangchao.mhttp.Response import im.wangchao.mhttp.body.MediaTypeUtils import im.wangchao.mhttp.callback.JsonCallbackHandler import io.github.wulkanowy.signer.hebe.getSignatureHeaders -import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.* import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe.HebeFilterType @@ -55,6 +54,15 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { return date.getLong("Timestamp") ?: return default } + fun buildDateTime(): JsonObject { + return JsonObject( + "Timestamp" to System.currentTimeMillis(), + "Date" to Date.getToday().stringY_m_d, + "DateDisplay" to Date.getToday().stringDmy, + "Time" to Time.getNow().stringHMS, + ) + } + fun getDate(json: JsonObject?, key: String): Date? { val date = json.getJsonObject(key) return date.getString("Date")?.let { Date.fromY_m_d(it) } @@ -74,6 +82,22 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { return teacherId } + fun getTeacherRecipient(json: JsonObject): Teacher? { + val globalKey = json.getString("GlobalKey") ?: return null + if (globalKey == data.messageBoxKey) + return null + var name = json.getString("Name") ?: return null + val group = json.getString("Group", "P") + val loginId = "${globalKey};${group};${name}" + val pattern = " - $group - (${data.schoolShort})" + if (name.endsWith(pattern)) + name = name.substringBefore(pattern) + val teacher = data.getTeacherByFirstLast(name, loginId) + if (teacher.type == 0) + teacher.type = Teacher.TYPE_OTHER + return teacher + } + fun getSubjectId(json: JsonObject?, key: String): Long? { val subject = json.getJsonObject(key) val subjectId = subject.getLong("Id") ?: return null @@ -89,7 +113,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { } fun getTeamId(json: JsonObject?, key: String): Long? { - val team = json.getJsonObject(key) + val team = json.getJsonObject(key) ?: return null val teamId = team.getLong("Id") var teamName = team.getString("Shortcut") ?: team.getString("Name") @@ -104,7 +128,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { } fun getClassId(json: JsonObject?, key: String): Long? { - val team = json.getJsonObject(key) + val team = json.getJsonObject(key) ?: return null val teamId = team.getLong("Id") val teamName = data.profile?.studentClassName ?: team.getString("Name") @@ -148,7 +172,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { fun isCurrentYear(dateTime: Long): Boolean { return profile?.let { profile -> - return@let dateTime >= profile.dateSemester1Start.inMillis + return@let dateTime >= profile.dateSemester1Start.inMillis - WEEK * MS } ?: false } @@ -355,6 +379,7 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { dateTo: Date? = null, lastSync: Long? = null, folder: Int? = null, + messageBox: String? = null, params: Map = mapOf(), includeFilterType: Boolean = true, onSuccess: (data: List, response: Response?) -> Unit @@ -378,6 +403,9 @@ open class VulcanHebe(open val data: DataVulcan, open val lastSync: Long?) { query["periodId"] = data.studentSemesterId.toString() query["pupilId"] = data.studentId.toString() } + HebeFilterType.BY_MESSAGEBOX -> { + query["box"] = messageBox ?: data.messageBoxKey ?: "" + } } if (dateFrom != null) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt index a4ea84b1..bd8b58e5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/HebeFilterType.kt @@ -5,6 +5,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe enum class HebeFilterType(val endpoint: String) { + BY_MESSAGEBOX("byBox"), BY_PUPIL("byPupil"), BY_PERSON("byPerson"), BY_PERIOD("byPeriod") diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt index 13eeb8db..d7bec22b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook.kt @@ -5,6 +5,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe import androidx.core.util.set +import androidx.room.OnConflictStrategy import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_ADDRESSBOOK import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan @@ -44,7 +45,6 @@ class VulcanHebeAddressbook( ) { list, _ -> list.forEach { person -> val id = person.getString("Id") ?: return@forEach - val loginId = person.getString("LoginId") ?: return@forEach val idType = id.split("-") .getOrNull(0) @@ -69,7 +69,7 @@ class VulcanHebeAddressbook( idLong, name, surname, - loginId + null ).also { data.teacherList[idLong] = it } @@ -108,13 +108,14 @@ class VulcanHebeAddressbook( } teacher.setTeacherType(personType) - teacher.typeDescription = roleText + if (roleText != null) + teacher.typeDescription = roleText } if (teacher.type == 0) teacher.setTeacherType(typeBase) } - + data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK, 2 * DAY) onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK) } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt new file mode 100644 index 00000000..1a6606d0 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeAddressbook2.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2021-2-21. + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe + +import androidx.room.OnConflictStrategy +import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2 +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe +import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_OTHER +import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_PARENT +import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_STUDENT +import pl.szczodrzynski.edziennik.data.db.entity.Teacher.Companion.TYPE_TEACHER +import pl.szczodrzynski.edziennik.ext.DAY +import pl.szczodrzynski.edziennik.ext.getString + +class VulcanHebeAddressbook2( + override val data: DataVulcan, + override val lastSync: Long?, + val onSuccess: (endpointId: Int) -> Unit +) : VulcanHebe(data, lastSync) { + companion object { + const val TAG = "VulcanHebeAddressbook2" + } + + init { + apiGetList( + TAG, + VULCAN_HEBE_ENDPOINT_MESSAGEBOX_ADDRESSBOOK, + HebeFilterType.BY_MESSAGEBOX, + messageBox = data.messageBoxKey, + lastSync = lastSync, + includeFilterType = false + ) { list, _ -> + list.forEach { person -> + val teacher = getTeacherRecipient(person) ?: return@forEach + val group = person.getString("Group", "P") + if (teacher.type == TYPE_OTHER) { + teacher.type = when (group) { + "P" -> TYPE_TEACHER // Pracownik + "O" -> TYPE_PARENT // Opiekun + "U" -> TYPE_STUDENT // Uczeń + else -> TYPE_OTHER + } + } + } + data.teacherOnConflictStrategy = OnConflictStrategy.REPLACE + data.setSyncNext(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2, 2 * DAY) + onSuccess(ENDPOINT_VULCAN_HEBE_ADDRESSBOOK_2) + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt new file mode 100644 index 00000000..e1c03aff --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessageBoxes.kt @@ -0,0 +1,43 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2022-9-16. + */ + +package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe + +import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES +import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe +import pl.szczodrzynski.edziennik.ext.DAY +import pl.szczodrzynski.edziennik.ext.getString + +class VulcanHebeMessageBoxes( + override val data: DataVulcan, + override val lastSync: Long?, + val onSuccess: (endpointId: Int) -> Unit +) : VulcanHebe(data, lastSync) { + companion object { + const val TAG = "VulcanHebeMessageBoxes" + } + + init { + apiGetList( + TAG, + VULCAN_HEBE_ENDPOINT_MESSAGEBOX, + lastSync = lastSync + ) { list, _ -> + for (messageBox in list) { + val name = messageBox.getString("Name") ?: continue + val studentName = profile?.studentNameLong ?: continue + if (!name.startsWith(studentName)) + continue + + data.messageBoxKey = messageBox.getString("GlobalKey") + data.messageBoxName = name + break + } + data.setSyncNext(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES, 7 * DAY) + onSuccess(ENDPOINT_VULCAN_HEBE_MESSAGE_BOXES) + } + } +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt index 5d6e5da4..29f37e62 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessages.kt @@ -4,22 +4,21 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe -import androidx.core.util.set -import com.google.gson.JsonObject -import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES -import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES +import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.ENDPOINT_VULCAN_HEBE_MESSAGES_SENT import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe -import pl.szczodrzynski.edziennik.data.db.entity.* +import pl.szczodrzynski.edziennik.data.db.entity.Message import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_DELETED import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_RECEIVED import pl.szczodrzynski.edziennik.data.db.entity.Message.Companion.TYPE_SENT +import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient +import pl.szczodrzynski.edziennik.data.db.entity.Metadata +import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS import pl.szczodrzynski.edziennik.ext.* import pl.szczodrzynski.edziennik.utils.Utils -import pl.szczodrzynski.navlib.crc16 class VulcanHebeMessages( override val data: DataVulcan, @@ -27,29 +26,7 @@ class VulcanHebeMessages( val onSuccess: (endpointId: Int) -> Unit ) : VulcanHebe(data, lastSync) { companion object { - const val TAG = "VulcanHebeMessagesInbox" - } - - private fun getPersonId(json: JsonObject): Long { - val senderLoginId = json.getInt("LoginId") ?: return -1 - /*if (senderLoginId == data.studentLoginId) - return -1*/ - - val senderName = json.getString("Address") ?: return -1 - val senderNameSplit = senderName.splitName() - val senderLoginIdStr = senderLoginId.toString() - val teacher = data.teacherList.singleOrNull { it.loginId == senderLoginIdStr } - ?: Teacher( - profileId, - -1 * crc16(senderName).toLong(), - senderNameSplit?.second ?: "", - senderNameSplit?.first ?: "", - senderLoginIdStr - ).also { - it.setTeacherType(Teacher.TYPE_OTHER) - data.teacherList[it.id] = it - } - return teacher.id + const val TAG = "VulcanHebeMessages" } fun getMessages(messageType: Int) { @@ -64,17 +41,28 @@ class VulcanHebeMessages( TYPE_SENT -> ENDPOINT_VULCAN_HEBE_MESSAGES_SENT else -> ENDPOINT_VULCAN_HEBE_MESSAGES_INBOX } + + val messageBox = data.messageBoxKey + if (messageBox == null) { + onSuccess(endpointId) + return + } + apiGetList( TAG, - VULCAN_HEBE_ENDPOINT_MESSAGES, - HebeFilterType.BY_PERSON, + VULCAN_HEBE_ENDPOINT_MESSAGEBOX_MESSAGES, + HebeFilterType.BY_MESSAGEBOX, + messageBox = data.messageBoxKey, folder = folder, lastSync = lastSync ) { list, _ -> list.forEach { message -> - val id = message.getLong("Id") ?: return@forEach + val uuid = message.getString("Id") ?: return@forEach + val id = Utils.crc32(uuid.toByteArray()) + val globalKey = message.getString("GlobalKey", "") + val threadKey = message.getString("ThreadKey", "") val subject = message.getString("Subject") ?: return@forEach - val body = message.getString("Content") ?: return@forEach + var body = message.getString("Content") ?: return@forEach val sender = message.getJsonObject("Sender") ?: return@forEach @@ -83,13 +71,27 @@ class VulcanHebeMessages( if (!isCurrentYear(sentDate)) return@forEach + val senderId = if (messageType == TYPE_RECEIVED) + getTeacherRecipient(sender)?.id + else + null + + val meta = mutableMapOf( + "uuid" to uuid, + "globalKey" to globalKey, + "threadKey" to threadKey, + ) + val metaString = meta.map { "${it.key}=${it.value}" }.join("&") + body = "[META:${metaString}]" + body + body = body.replace("\n", "
    ") + val messageObject = Message( profileId = profileId, id = id, type = messageType, subject = subject, - body = body.replace("\n", "
    "), - senderId = if (messageType == TYPE_RECEIVED) getPersonId(sender) else null, + body = body, + senderId = senderId, addedDate = sentDate ) @@ -101,9 +103,14 @@ class VulcanHebeMessages( else -1 for (receiver in receivers) { + val recipientId = if (messageType == TYPE_SENT) + getTeacherRecipient(receiver)?.id ?: -1 + else + -1 + val messageRecipientObject = MessageRecipient( profileId, - if (messageType == TYPE_SENT) getPersonId(receiver) else -1, + recipientId, -1, receiverReadDate, id @@ -115,6 +122,9 @@ class VulcanHebeMessages( ?.asJsonObjectList() ?: return@forEach + messageObject.attachmentIds = mutableListOf() + messageObject.attachmentNames = mutableListOf() + messageObject.attachmentSizes = mutableListOf() for (attachment in attachments) { val fileName = attachment.getString("Name") ?: continue val url = attachment.getString("Link") ?: continue diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt index bd86cfce..f0090a9c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeMessagesChangeStatus.kt @@ -5,7 +5,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe import org.greenrobot.eventbus.EventBus -import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS +import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent @@ -23,13 +23,19 @@ class VulcanHebeMessagesChangeStatus( const val TAG = "VulcanHebeMessagesChangeStatus" } - init { + init { let { + val messageKey = messageObject.body?.let { data.parseMessageMeta(it) }?.get("globalKey") ?: run { + EventBus.getDefault().postSticky(MessageGetEvent(messageObject)) + onSuccess() + return@let + } + apiPost( TAG, - VULCAN_HEBE_ENDPOINT_MESSAGES_STATUS, + VULCAN_HEBE_ENDPOINT_MESSAGEBOX_STATUS, payload = JsonObject( - "MessageId" to messageObject.id, - "LoginId" to data.studentLoginId, + "BoxKey" to data.messageBoxKey, + "MessageKey" to messageKey, "Status" to 1 ) ) { _: Boolean, _ -> @@ -61,5 +67,5 @@ class VulcanHebeMessagesChangeStatus( EventBus.getDefault().postSticky(MessageGetEvent(messageObject)) onSuccess() } - } + }} } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt index e71c4089..5e607caa 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeSendMessage.kt @@ -4,17 +4,20 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.hebe +import com.google.gson.JsonArray import com.google.gson.JsonObject import org.greenrobot.eventbus.EventBus import pl.szczodrzynski.edziennik.* +import pl.szczodrzynski.edziennik.data.api.ERROR_MESSAGE_NOT_SENT import pl.szczodrzynski.edziennik.data.api.ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY -import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGES_SEND +import pl.szczodrzynski.edziennik.data.api.VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.DataVulcan import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.data.VulcanHebe import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent import pl.szczodrzynski.edziennik.data.db.entity.Message import pl.szczodrzynski.edziennik.data.db.entity.Teacher import pl.szczodrzynski.edziennik.ext.* +import java.util.UUID class VulcanHebeSendMessage( override val data: DataVulcan, @@ -28,9 +31,9 @@ class VulcanHebeSendMessage( } init { - if (data.senderAddressName == null || data.senderAddressHash == null) { - VulcanHebeMain(data).getStudents(data.profile, null) { - if (data.senderAddressName == null || data.senderAddressHash == null) { + if (data.messageBoxKey == null || data.messageBoxName == null) { + VulcanHebeMessageBoxes(data, 0) { + if (data.messageBoxKey == null || data.messageBoxName == null) { data.error(TAG, ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY) } else { @@ -44,47 +47,64 @@ class VulcanHebeSendMessage( } private fun sendMessage() { + val uuid = UUID.randomUUID().toString() + val globalKey = UUID.randomUUID().toString() + val partition = "${data.symbol}-${data.schoolSymbol}" + val recipientsArray = JsonArray() recipients.forEach { teacher -> + val loginId = teacher.loginId?.split(";", limit = 3) ?: return@forEach + val key = loginId.getOrNull(0) ?: teacher.loginId + val group = loginId.getOrNull(1) + val name = loginId.getOrNull(2) + if (key?.toIntOrNull() != null) { + // raise error for old-format (non-UUID) login IDs + data.error(TAG, ERROR_MESSAGE_NOT_SENT) + return + } recipientsArray += JsonObject( - "Address" to teacher.fullNameLastFirst, - "LoginId" to (teacher.loginId?.toIntOrNull() ?: return@forEach), - "Initials" to teacher.initialsLastFirst, - "AddressHash" to teacher.fullNameLastFirst.sha1Hex() + "Id" to "${data.messageBoxKey}-${key}", + "Partition" to partition, + "Owner" to data.messageBoxKey, + "GlobalKey" to key, + "Name" to name, + "Group" to group, + "Initials" to "", + "HasRead" to 0, ) } - val senderName = (profile?.accountName ?: profile?.studentNameLong) - ?.swapFirstLastName() ?: "" val sender = JsonObject( - "Address" to data.senderAddressName, - "LoginId" to data.studentLoginId.toString(), - "Initials" to senderName.getNameInitials(), - "AddressHash" to data.senderAddressHash + "Id" to "0", + "Partition" to partition, + "Owner" to data.messageBoxKey, + "GlobalKey" to data.messageBoxKey, + "Name" to data.messageBoxName, + "Group" to "", + "Initials" to "", + "HasRead" to 0, ) apiPost( TAG, - VULCAN_HEBE_ENDPOINT_MESSAGES_SEND, + VULCAN_HEBE_ENDPOINT_MESSAGEBOX_SEND, payload = JsonObject( - "Status" to 1, - "Sender" to sender, - "DateSent" to null, - "DateRead" to null, - "Content" to text, - "Receiver" to recipientsArray, - "Id" to 0, + "Id" to uuid, + "GlobalKey" to globalKey, + "Partition" to partition, + "ThreadKey" to globalKey, // TODO correct threadKey for reply messages "Subject" to subject, - "Attachments" to null, - "Self" to null + "Content" to text, + "Status" to 1, + "Owner" to data.messageBoxKey, + "DateSent" to buildDateTime(), + "DateRead" to null, + "Sender" to sender, + "Receiver" to recipientsArray, + "Attachments" to JsonArray(), ) - ) { json: JsonObject, _ -> - val messageId = json.getLong("Id") - - if (messageId == null) { - // TODO error - return@apiPost - } + ) { _: JsonObject, _ -> + // TODO handle errors VulcanHebeMessages(data, null) { val message = data.messageList.firstOrNull { it.isSent && it.subject == subject } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt index f01e0d6b..7be65e34 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/edziennik/vulcan/data/hebe/VulcanHebeTeachers.kt @@ -45,6 +45,7 @@ class VulcanHebeTeachers( when (subjectName) { "Pedagog" -> teacher.setTeacherType(Teacher.TYPE_PEDAGOGUE) + "Dyrektor" -> teacher.setTeacherType(Teacher.TYPE_PRINCIPAL) else -> { val subjectId = data.getSubject(null, subjectName).id if (!teacher.subjects.contains(subjectId)) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt index d88fa652..49b510c2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/events/UserActionRequiredEvent.kt @@ -8,9 +8,7 @@ data class UserActionRequiredEvent(val profileId: Int, val type: Int) { companion object { const val LOGIN_DATA_MOBIDZIENNIK = 101 const val LOGIN_DATA_LIBRUS = 102 - const val LOGIN_DATA_IDZIENNIK = 103 const val LOGIN_DATA_VULCAN = 104 - const val LOGIN_DATA_EDUDZIENNIK = 105 const val CAPTCHA_LIBRUS = 202 } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt index 94e12fe8..ea53112a 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/models/Data.kt @@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.BuildConfig import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.data.api.ERROR_REQUEST_FAILURE +import pl.szczodrzynski.edziennik.data.api.Regexes.MESSAGE_META import pl.szczodrzynski.edziennik.data.api.interfaces.EndpointCallback import pl.szczodrzynski.edziennik.data.db.AppDb import pl.szczodrzynski.edziennik.data.db.entity.* @@ -489,11 +490,19 @@ abstract class Data(val app: App, val profile: Profile?, val loginStore: LoginSt teacherList[id] = this } return obj.also { - if (loginId != null && it.loginId != null) + if (loginId != null) it.loginId = loginId if (firstName.length > 1) it.name = firstName it.surname = lastName } } + + fun parseMessageMeta(body: String): Map? { + val match = MESSAGE_META.find(body) ?: return null + return match[1].split("&").associateBy( + { it.substringBefore("=") }, + { it.substringAfter("=") }, + ) + } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt index 28eb11a9..d4cff130 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/szkolny/interceptor/Signing.kt @@ -46,6 +46,6 @@ object Signing { /*fun provideKey(param1: String, param2: Long): ByteArray {*/ fun pleaseStopRightNow(param1: String, param2: Long): ByteArray { - return "$param1.MTIzNDU2Nzg5MDWpYbYnaF===.$param2".sha256() + return "$param1.MTIzNDU2Nzg5MDYFZwkReL===.$param2".sha256() } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt index 8b4682d6..41614394 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/api/task/PostNotifications.kt @@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_SER import pl.szczodrzynski.edziennik.ext.Intent import pl.szczodrzynski.edziennik.ext.asBoldSpannable import pl.szczodrzynski.edziennik.ext.concat +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.data.db.entity.Notification as AppNotification @@ -92,7 +93,7 @@ class PostNotifications(val app: App, nList: List) { MainActivity::class.java, "fragmentId" to MainActivity.DRAWER_ITEM_NOTIFICATIONS ) - val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT) + val summaryIntent = PendingIntent.getActivity(app, app.notificationChannelsManager.data.id, intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag()) // On Nougat or newer - show maximum 8 notifications // On Marshmallow or older - show maximum 4 notifications diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt index 5c64613e..24e58d02 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/dao/EventDao.kt @@ -109,7 +109,7 @@ abstract class EventDao : BaseDao { abstract fun removeNotManual(profileId: Int)*/ @RawQuery - abstract fun dontKeepFuture(query: SupportSQLiteQuery?): Long + abstract fun dontKeepFuture(query: SupportSQLiteQuery): Long @Transaction open fun dontKeepFuture(profileId: Int, todayDate: Date, filter: String) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt index e57e8efa..35208927 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/data/db/entity/Notification.kt @@ -13,6 +13,7 @@ import com.google.gson.JsonObject import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import pl.szczodrzynski.edziennik.MainActivity +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag @Entity(tableName = "notifications") data class Notification( @@ -98,7 +99,7 @@ data class Notification( fun getPendingIntent(context: Context): PendingIntent { val intent = Intent(context, MainActivity::class.java) fillIntent(intent) - return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT) + return PendingIntent.getActivity(context, id.toInt(), intent, PendingIntent.FLAG_ONE_SHOT or pendingIntentFlag()) } fun getLargeIcon(): IIcon = when (type) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ext/MiscExtensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ext/MiscExtensions.kt index 22ed9e43..df931fbd 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ext/MiscExtensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ext/MiscExtensions.kt @@ -4,7 +4,9 @@ package pl.szczodrzynski.edziennik.ext +import android.app.PendingIntent import android.database.Cursor +import android.os.Build import androidx.core.database.getIntOrNull import androidx.core.database.getLongOrNull import androidx.core.database.getStringOrNull @@ -64,3 +66,9 @@ inline fun ifNotNull(a: A?, b: B?, code: (A, B) -> R): R? { } infix fun Int.hasSet(what: Int) = this and what == what + +fun pendingIntentFlag(): Int { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + return PendingIntent.FLAG_IMMUTABLE + return 0 +} diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/sync/UpdateWorker.kt b/app/src/main/java/pl/szczodrzynski/edziennik/sync/UpdateWorker.kt index 5325d533..0df0bc83 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/sync/UpdateWorker.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/sync/UpdateWorker.kt @@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update import pl.szczodrzynski.edziennik.ext.DAY import pl.szczodrzynski.edziennik.ext.concat import pl.szczodrzynski.edziennik.ext.formatDate +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.html.BetterHtml import java.util.concurrent.TimeUnit @@ -109,7 +110,7 @@ class UpdateWorker(val context: Context, val params: WorkerParameters) : Worker( } val notificationIntent = Intent(app, UpdateDownloaderService::class.java) - val pendingIntent = PendingIntent.getService(app, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT) + val pendingIntent = PendingIntent.getService(app, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag()) val notification = NotificationCompat.Builder(app, app.notificationChannelsManager.updates.key) .setContentTitle(app.getString(R.string.notification_updates_title)) .setContentText(app.getString(R.string.notification_updates_text, update.versionName)) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabFragment.kt index 93acec1e..ec47b5b6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabFragment.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -17,6 +18,8 @@ import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.databinding.TemplateFragmentBinding import pl.szczodrzynski.edziennik.ext.addOnPageSelectedListener import pl.szczodrzynski.edziennik.ui.base.lazypager.FragmentLazyPagerAdapter +import pl.szczodrzynski.edziennik.ui.login.LoginActivity +import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch import kotlin.coroutines.CoroutineContext class LabFragment : Fragment(), CoroutineScope { @@ -26,7 +29,7 @@ class LabFragment : Fragment(), CoroutineScope { } private lateinit var app: App - private lateinit var activity: MainActivity + private lateinit var activity: AppCompatActivity private lateinit var b: TemplateFragmentBinding private val job: Job = Job() @@ -36,11 +39,14 @@ class LabFragment : Fragment(), CoroutineScope { // local/private variables go here override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - activity = (getActivity() as MainActivity?) ?: return null + activity = (getActivity() as AppCompatActivity?) ?: return null context ?: return null app = activity.application as App b = TemplateFragmentBinding.inflate(inflater) - b.refreshLayout.setParent(activity.swipeRefreshLayout) + when (activity) { + is MainActivity -> b.refreshLayout.setParent((activity as MainActivity).swipeRefreshLayout) + is LoginActivity -> b.refreshLayout.setParent((activity as LoginActivity).swipeRefreshLayout) + } b.refreshLayout.isEnabled = false return b.root } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabPageFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabPageFragment.kt index 8c9e46fe..aecbecb1 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabPageFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabPageFragment.kt @@ -9,6 +9,7 @@ import android.os.Process import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.sqlite.db.SimpleSQLiteQuery import com.chuckerteam.chucker.api.Chucker @@ -35,7 +36,7 @@ class LabPageFragment : LazyFragment(), CoroutineScope { } private lateinit var app: App - private lateinit var activity: MainActivity + private lateinit var activity: AppCompatActivity private lateinit var b: LabFragmentBinding private val job: Job = Job() @@ -45,7 +46,7 @@ class LabPageFragment : LazyFragment(), CoroutineScope { // local/private variables go here override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - activity = (getActivity() as MainActivity?) ?: return null + activity = (getActivity() as AppCompatActivity?) ?: return null context ?: return null app = activity.application as App b = LabFragmentBinding.inflate(inflater) @@ -55,6 +56,16 @@ class LabPageFragment : LazyFragment(), CoroutineScope { override fun onPageCreated(): Boolean { b.app = app + if (app.profile.id == 0) { + b.last10unseen.isVisible = false + b.fullSync.isVisible = false + b.clearProfile.isVisible = false + b.rodo.isVisible = false + b.removeHomework.isVisible = false + b.unarchive.isVisible = false + b.profile.isVisible = false + } + b.last10unseen.onClick { launch(Dispatchers.Default) { val events = app.db.eventDao().getAllNow(App.profileId) @@ -139,7 +150,8 @@ class LabPageFragment : LazyFragment(), CoroutineScope { b.profile += profiles.map { TextInputDropDown.Item(it.id.toLong(), "${it.id} ${it.name} archived ${it.archived}", tag = it) } b.profile.select(app.profileId.toLong()) b.profile.setOnChangeListener { - activity.loadProfile(it.id.toInt()) + if (activity is MainActivity) + (activity as MainActivity).loadProfile(it.id.toInt()) return@setOnChangeListener true } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabProfileFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabProfileFragment.kt index 995f3133..5b289ea4 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabProfileFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/debug/LabProfileFragment.kt @@ -8,6 +8,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -22,6 +23,7 @@ import pl.szczodrzynski.edziennik.ext.input import pl.szczodrzynski.edziennik.ext.set import pl.szczodrzynski.edziennik.ext.startCoroutineTimer import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment +import pl.szczodrzynski.edziennik.ui.login.LoginActivity import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration import kotlin.coroutines.CoroutineContext @@ -31,7 +33,7 @@ class LabProfileFragment : LazyFragment(), CoroutineScope { } private lateinit var app: App - private lateinit var activity: MainActivity + private lateinit var activity: AppCompatActivity private lateinit var b: TemplateListPageFragmentBinding private val job: Job = Job() @@ -45,7 +47,7 @@ class LabProfileFragment : LazyFragment(), CoroutineScope { } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - activity = (getActivity() as MainActivity?) ?: return null + activity = (getActivity() as AppCompatActivity?) ?: return null context ?: return null app = activity.application as App b = TemplateListPageFragmentBinding.inflate(inflater) @@ -142,7 +144,10 @@ class LabProfileFragment : LazyFragment(), CoroutineScope { .show() } catch (e: Exception) { - activity.error(ApiError.fromThrowable(TAG, e)) + if (activity is MainActivity) + (activity as MainActivity).error(ApiError.fromThrowable(TAG, e)) + if (activity is LoginActivity) + (activity as LoginActivity).error(ApiError.fromThrowable(TAG, e)) } }) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt index 78ac63e7..54f94433 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/HomeFragment.kt @@ -198,7 +198,7 @@ class HomeFragment : Fragment(), CoroutineScope { } } - override fun performAccessibilityAction(host: View, action: Int, args: Bundle): Boolean { + override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean { val fromPosition: Int = b.list.getChildLayoutPosition(host) if (action == R.id.move_card_down_action) { swapCards(fromPosition, fromPosition + 1, adapter) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/cards/HomeTimetableCard.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/cards/HomeTimetableCard.kt index b1d31f18..ab297ef8 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/cards/HomeTimetableCard.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/home/cards/HomeTimetableCard.kt @@ -75,7 +75,7 @@ class HomeTimetableCard( private var counterEnd: Time? = null private var subjectSpannable: CharSequence? = null - private val ignoreCancelled = true + private val ignoreCancelled = false private val countInSeconds: Boolean get() = app.config.timetable.countInSeconds @@ -160,6 +160,9 @@ class HomeTimetableCard( && it.displayEndTime > now && !(it.isCancelled && ignoreCancelled) } + if (!ignoreCancelled && lessons.all { it.isCancelled }) + // skip current day if all lessons are cancelled + lessons = listOf() while ((lessons.isEmpty() || lessons.none { it.type != Lesson.TYPE_NO_LESSONS && (it.displayDate != today @@ -174,6 +177,7 @@ class HomeTimetableCard( it.profileId == profile.id && it.displayDate == timetableDate } + lessons = lessons.dropWhile { it.isCancelled } if (lessons.isEmpty()) break @@ -238,15 +242,18 @@ class HomeTimetableCard( b.counter.visibility = View.GONE val now = syncedNow - val firstLesson = lessons.firstOrNull() - val lastLesson = lessons.lastOrNull() + val firstLesson = lessons.firstOrNull { !it.isCancelled } + val lastLesson = lessons.lastOrNull { !it.isCancelled } + val skipFirst = if (firstLesson == null) 0 else lessons.indexOf(firstLesson) + val skipLast = if (lastLesson == null) 0 else lessons.size - 1 - lessons.indexOf(lastLesson) + val lessonCount = lessons.size - skipFirst - skipLast if (isToday) { // today b.dayInfo.setText(R.string.home_timetable_today) b.lessonInfo.setText( R.string.home_timetable_lessons_remaining, - lessons.size, + lessonCount, lastLesson?.displayEndTime?.stringHM ?: "?" ) counterStart = firstLesson?.displayStartTime @@ -291,12 +298,14 @@ class HomeTimetableCard( b.dayInfo.setText(dayInfoRes, Week.getFullDayName(timetableDate.weekDay), timetableDate.formattedString) b.lessonInfo.setText( R.string.home_timetable_lessons_info, - lessons.size, + lessonCount, firstLesson?.displayStartTime?.stringHM ?: "?", lastLesson?.displayEndTime?.stringHM ?: "?" ) b.lessonBig.setText(R.string.home_timetable_lesson_first, firstLesson.subjectSpannable) + b.counter.visibility = View.VISIBLE + b.counter.text = firstLesson?.displayStartTime?.stringHM firstLesson?.displayClassroom?.let { b.classroom.visibility = View.VISIBLE b.classroom.text = it @@ -308,9 +317,8 @@ class HomeTimetableCard( val text = mutableListOf( activity.getString(R.string.home_timetable_later) ) - var first = true - for (lesson in lessons) { - if (first) { first = false; continue } + val nextLessons = lessons.drop(skipFirst + 1) + for (lesson in nextLessons) { text += listOf( lesson.displayStartTime?.stringHM, lesson.subjectSpannable @@ -363,7 +371,10 @@ class HomeTimetableCard( b.progress.visibility = View.GONE b.counter.visibility = View.VISIBLE val diff = counterStart - now - b.counter.text = activity.timeTill(diff.toInt(), "\n", countInSeconds) + if (diff >= 60 * MINUTE) + b.counter.text = counterStart.stringHM + else + b.counter.text = activity.timeTill(diff.toInt(), "\n", countInSeconds) } else { // the lesson is right now diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginActivity.kt index 1f8fb442..61aa4520 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginActivity.kt @@ -20,6 +20,7 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError import pl.szczodrzynski.edziennik.data.db.entity.LoginStore import pl.szczodrzynski.edziennik.databinding.LoginActivityBinding import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar +import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch import kotlin.coroutines.CoroutineContext class LoginActivity : AppCompatActivity(), CoroutineScope { @@ -32,6 +33,7 @@ class LoginActivity : AppCompatActivity(), CoroutineScope { lateinit var navOptions: NavOptions val nav by lazy { Navigation.findNavController(this, R.id.nav_host_fragment) } val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) } + val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout } private val job: Job = Job() override val coroutineContext: CoroutineContext diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt index b793b34b..1bfe0abd 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginChooserFragment.kt @@ -66,6 +66,8 @@ class LoginChooserFragment : Fragment(), CoroutineScope { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { if (!isAdded) return + val adapter = LoginChooserAdapter(activity, this::onLoginModeClicked) + b.versionText.setText( R.string.login_chooser_version_format, app.buildManager.versionName, @@ -73,10 +75,33 @@ class LoginChooserFragment : Fragment(), CoroutineScope { ) b.versionText.onClick { app.buildManager.showVersionDialog(activity) + if (!App.devMode) + return@onClick + if (adapter.items.firstOrNull { it is LoginInfo.Register && it.internalName == "lab" } != null) + return@onClick + adapter.items.add( + index = 0, + element = LoginInfo.Register( + loginType = 999999, + internalName = "lab", + registerName = R.string.menu_lab, + registerLogo = R.drawable.face_2, + loginModes = listOf( + LoginInfo.Mode( + loginMode = 0, + name = 0, + icon = 0, + guideText = 0, + credentials = listOf(), + errorCodes = mapOf() + ) + ) + ) + ) + adapter.notifyItemInserted(0) + b.list.smoothScrollToPosition(0) } - val adapter = LoginChooserAdapter(activity, this::onLoginModeClicked) - LoginInfo.chooserList = LoginInfo.chooserList ?: LoginInfo.list.toMutableList() @@ -164,7 +189,7 @@ class LoginChooserFragment : Fragment(), CoroutineScope { anim.fillAfter = true activity.getRootView().startAnimation(anim) - b.list.smoothScrollToPosition(0) + adapter.items.removeAll { it !is LoginInfo.Register } adapter.items.add( LoginInfo.Register( loginType = 74, @@ -183,7 +208,8 @@ class LoginChooserFragment : Fragment(), CoroutineScope { ) ) ) - adapter.notifyItemInserted(adapter.items.size - 1) + adapter.notifyDataSetChanged() + b.list.smoothScrollToPosition(adapter.items.size - 1) } when { @@ -216,6 +242,11 @@ class LoginChooserFragment : Fragment(), CoroutineScope { return } + if (loginType.internalName == "lab") { + nav.navigate(R.id.labFragment, null, activity.navOptions) + return + } + if (!app.config.privacyPolicyAccepted) { MaterialAlertDialogBuilder(activity) .setTitle(R.string.privacy_policy) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt index 0c47d2b7..0448b514 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/login/LoginInfo.kt @@ -278,28 +278,6 @@ object LoginInfo { ) ) ), - Register( - loginType = LOGIN_TYPE_EDUDZIENNIK, - internalName = "edudziennik", - registerName = R.string.login_type_edudziennik, - registerLogo = R.drawable.login_logo_edudziennik, - loginModes = listOf( - Mode( - loginMode = LOGIN_MODE_EDUDZIENNIK_WEB, - name = R.string.login_mode_edudziennik_web, - icon = R.drawable.login_mode_edudziennik_web, - hintText = R.string.login_mode_edudziennik_web_hint, - guideText = R.string.login_mode_edudziennik_web_guide, - credentials = listOf( - getEmailCredential("email"), - getPasswordCredential("password") - ), - errorCodes = mapOf( - ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN to R.string.login_error_incorrect_login_or_password - ) - ) - ) - ), Register( loginType = LOGIN_TYPE_PODLASIE, internalName = "podlasie", diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt index 41314c1a..52e7c23b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/messages/compose/MessagesComposeFragment.kt @@ -77,7 +77,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope { private lateinit var stylingConfig: StylingConfig private lateinit var uiConfig: UIConfig private val enableTextStyling - get() = app.profile.loginStoreType != LoginStore.LOGIN_TYPE_VULCAN + get() = app.profile.loginStoreType != LoginStore.LOGIN_TYPE_LIBRUS private var changedRecipients = false private var changedSubject = false private var changedBody = false diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/luckynumber/WidgetLuckyNumberProvider.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/luckynumber/WidgetLuckyNumberProvider.kt index e6332115..40b40d5c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/luckynumber/WidgetLuckyNumberProvider.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/luckynumber/WidgetLuckyNumberProvider.kt @@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.ext.getJsonObject +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.utils.Utils import pl.szczodrzynski.edziennik.utils.models.Date @@ -81,7 +82,7 @@ class WidgetLuckyNumberProvider : AppWidgetProvider() { val openIntent = Intent(context, MainActivity::class.java) openIntent.action = Intent.ACTION_MAIN openIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOME) - val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, 0) + val openPendingIntent = PendingIntent.getActivity(context, 0, openIntent, pendingIntentFlag()) views.setOnClickPendingIntent(R.id.widgetLuckyNumberRoot, openPendingIntent) appWidgetManager.updateAppWidget(appWidgetId, views) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt index b2ac08d7..dc4eb02e 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/notifications/WidgetNotificationsProvider.kt @@ -22,6 +22,7 @@ import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.ext.Bundle import pl.szczodrzynski.edziennik.ext.getJsonObject +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.receivers.SzkolnyReceiver import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig @@ -47,7 +48,7 @@ class WidgetNotificationsProvider : AppWidgetProvider() { val syncIntent = SzkolnyReceiver.getIntent(context, Bundle( "task" to "SyncRequest" )) - val syncPendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, 0) + val syncPendingIntent = PendingIntent.getBroadcast(context, 0, syncIntent, pendingIntentFlag()) views.setOnClickPendingIntent(R.id.widgetNotificationsSync, syncPendingIntent) views.setImageViewBitmap( @@ -68,13 +69,13 @@ class WidgetNotificationsProvider : AppWidgetProvider() { val itemIntent = Intent(context, MainActivity::class.java) itemIntent.action = Intent.ACTION_MAIN - val itemPendingIntent = PendingIntent.getActivity(context, 0, itemIntent, 0) + val itemPendingIntent = PendingIntent.getActivity(context, 0, itemIntent, pendingIntentFlag()) views.setPendingIntentTemplate(R.id.widgetNotificationsListView, itemPendingIntent) val headerIntent = Intent(context, MainActivity::class.java) headerIntent.action = Intent.ACTION_MAIN headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS) - val headerPendingIntent = PendingIntent.getActivity(context, 0, headerIntent, 0) + val headerPendingIntent = PendingIntent.getActivity(context, 0, headerIntent, pendingIntentFlag()) views.setOnClickPendingIntent(R.id.widgetNotificationsHeader, headerPendingIntent) appWidgetManager.updateAppWidget(appWidgetId, views) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt index 8c87ad30..87da09a8 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/ui/widgets/timetable/WidgetTimetableProvider.kt @@ -31,6 +31,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Lesson import pl.szczodrzynski.edziennik.data.db.entity.Lesson.Companion.TYPE_NO_LESSONS import pl.szczodrzynski.edziennik.ext.filterOutArchived import pl.szczodrzynski.edziennik.ext.getJsonObject +import pl.szczodrzynski.edziennik.ext.pendingIntentFlag import pl.szczodrzynski.edziennik.ui.widgets.LessonDialogActivity import pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig import pl.szczodrzynski.edziennik.utils.models.Date @@ -53,8 +54,8 @@ class WidgetTimetableProvider : AppWidgetProvider() { return getPendingSelfIntent(context, intent) } - fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent { - return PendingIntent.getBroadcast(context, 0, intent, 0) + private fun getPendingSelfIntent(context: Context, intent: Intent): PendingIntent { + return PendingIntent.getBroadcast(context, 0, intent, pendingIntentFlag()) } fun drawableToBitmap(drawable: Drawable): Bitmap { @@ -111,7 +112,7 @@ class WidgetTimetableProvider : AppWidgetProvider() { refreshIntent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds) val refreshPendingIntent = PendingIntent.getBroadcast(context, - 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT) + 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT or pendingIntentFlag()) views.setOnClickPendingIntent(R.id.widgetTimetableRefresh, refreshPendingIntent) views.setOnClickPendingIntent(R.id.widgetTimetableSync, getPendingSelfIntent(context, ACTION_SYNC_DATA)) @@ -394,7 +395,7 @@ class WidgetTimetableProvider : AppWidgetProvider() { } } headerIntent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE) - val headerPendingIntent = PendingIntent.getActivity(app, appWidgetId, headerIntent, 0) + val headerPendingIntent = PendingIntent.getActivity(app, appWidgetId, headerIntent, pendingIntentFlag()) views.setOnClickPendingIntent(R.id.widgetTimetableHeader, headerPendingIntent) timetables!!.put(appWidgetId, models) @@ -408,7 +409,7 @@ class WidgetTimetableProvider : AppWidgetProvider() { // create an intent used to display the lesson details dialog val itemIntent = Intent(app, LessonDialogActivity::class.java) itemIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK/* or Intent.FLAG_ACTIVITY_CLEAR_TASK*/) - val itemPendingIntent = PendingIntent.getActivity(app, appWidgetId, itemIntent, 0) + val itemPendingIntent = PendingIntent.getActivity(app, appWidgetId, itemIntent, pendingIntentFlag()) views.setPendingIntentTemplate(R.id.widgetTimetableListView, itemPendingIntent) if (!unified) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt b/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt index 2e3bc072..97610845 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/utils/html/BetterHtml.kt @@ -15,6 +15,7 @@ import android.text.style.* import androidx.appcompat.widget.AppCompatEditText import androidx.core.graphics.ColorUtils import androidx.core.text.HtmlCompat +import pl.szczodrzynski.edziennik.data.api.Regexes.MESSAGE_META import pl.szczodrzynski.edziennik.ext.dp import pl.szczodrzynski.edziennik.ext.getWordBounds import pl.szczodrzynski.edziennik.ext.resolveAttr @@ -45,7 +46,7 @@ object BetterHtml { .toRegex(RegexOption.IGNORE_CASE) var text = html - .replace("\\[META:[A-z0-9]+;[0-9-]+]".toRegex(), "") + .replace(MESSAGE_META, "") .replace("background-color: ?$hexPattern;".toRegex(), "") // treat paragraphs as if they had no margin .replace(" - + android:layout_height="match_parent"> + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 92471e03..a78eb068 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -306,9 +306,6 @@ Klassengruppen herunterladen… Stundenplan herunterladen… Geräteinformationen herunterladen… - bei Edudziennik einloggen… - bei iDziennik einloggen… - bei iDziennik einloggen… Einloggen in die API… Einloggen bei LIBRUS® nachrichten… Einloggen bei LIBRUS® Rodzina… @@ -324,7 +321,6 @@ Fehler Fehlerdetails Falsches Modul angegeben: %d Melden Sie es dem Anwendungsentwickler - Ihr iDziennik-Passwort ist abgelaufen. Sie müssen es in der Desktop-Version der Website ändern Die Schulfach-ID wurde nicht angegeben Ein Fehler ist aufgetreten! Ein Fehler ist aufgetreten: %s @@ -519,8 +515,6 @@ Registrierung erlauben Einloggen Möchten Sie die Anmeldung bei der App wirklich abbrechen? Angezeigte Profile werden nicht gespeichert. - Verwenden Sie die Kontodaten, mit denen Sie sich bei der Desktop-Version von Edudziennik einlogen - Einloggen - Edudziennik Fehler: %s Konto ist nicht aktiviert Token ist abgelaufen. Erzeugen Sie ein neues Token @@ -566,10 +560,6 @@ Symbol Token Benutzername - Verwenden Sie die Daten, mit denen Sie sich bei der Desktop-Version von iDziennik einloggen - Hilfe - iDziennik Progman - Melden Sie sich mit den Daten an, die Sie von Ihrer Schule erhalten haben. Bei Problemen verwenden Sie die Schaltfläche unter dem Formular. - Einloggen - iDziennik Progman LIBRUS® - Einloggen Um die App verwenden zu können, müssen Sie über ein LIBRUS® Rodzina-Konto verfügen. Sie können sie unter portal.librus.pl erstellen. Verwenden Sie die Daten, die Sie an den im Bild markierten Stellen eingeben. Hilfe für LIBRUS® einloggen diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index 97eaeac1..851129f9 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -306,9 +306,6 @@ Syncing class groups… Syncing timetable… Syncing unit info… - Logging in to Edudziennik… - Logging in to iDziennik… - Logging in to iDziennik… Logging in to the API… Logging in to LIBRUS® messages… Logging in to LIBRUS® Rodzina… @@ -324,7 +321,6 @@ Error Error details Wrong module given: %d Report it to the application developer - Your iDziennik password has expired. You have to change it in the desktop version of the website. The subject ID wasn\'t specified. An error occurred! An error occurred: %s @@ -519,8 +515,6 @@ Allow registration Log in Do you really want to cancel? Displayed profiles won\'t be saved. - Use the account details, which you use to login into the desktop version of Edudziennik. - Log in - Edudziennik Error: %s Account is not activated Token has expired. Generate a new token. @@ -566,10 +560,6 @@ Symbol Token Username - Use the data which you use to login to the desktop version of iDziennik. - Help - iDziennik Progman - Use the data which you got from your school. In case of any problems, use the button below the form. - Log in - iDziennik Progman LIBRUS® - login In order to use the app you need a LIBRUS® Rodzina account. You can create it on portal.librus.pl. Use the data you normally enter in the fields marked on the image. Help for LIBRUS® login @@ -859,7 +849,7 @@ Open-source licenses Privacy policy E-register - © Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - 2022 + © Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 – 2022 Click to check for updates Update Version @@ -1269,7 +1259,6 @@ Update Not now Update - EduDziennik Log in - %s Date Teacher @@ -1323,7 +1312,6 @@ Use e-mail/username and password Logging in to PPE… Podlaska Platforma Edukacyjna - Log in using e-mail and password Logging in to VULCAN® register… Login via VULCAN® platform Log in using e-mail @@ -1343,12 +1331,10 @@ %.2f%% Attendance during this period: %.2f%% Log in child/parent account in app - Enter the e-mail address and password that you use to log in to the browser on the EduDziennik website. Probably the school year for this student has not yet started (will start %s). Please try to sync later. The school year ended on %s. Student data from the previous year will be moved to the archive for later review. Trademarks featured in this application belong to their rightful owners and are used for informational purposes only. You are viewing a student\'s data from the school year %d/%d. - Use data, that you enter on the e-register website To be able to scan the QR code, you need to grant access to the camera.\n\nClick OK to grant permissions. It\'s a pity, the opinions of others help me develop the application. The selected login method is still being tested and may not work properly. If you have problems with the app, please choose the recommended login method. diff --git a/app/src/main/res/values/errors.xml b/app/src/main/res/values/errors.xml index 827227c5..f0916a8b 100644 --- a/app/src/main/res/values/errors.xml +++ b/app/src/main/res/values/errors.xml @@ -168,13 +168,6 @@ ERROR_VULCAN_HEBE_MISSING_SENDER_ENTRY ERROR_VULCAN_API_DEPRECATED - ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN - ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER - ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID - ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS - ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED - ERROR_EDUDZIENNIK_WEB_TEAM_MISSING - ERROR_LOGIN_PODLASIE_API_INVALID_TOKEN ERROR_LOGIN_PODLASIE_API_DEVICE_LIMIT ERROR_PODLASIE_API_NO_TOKEN @@ -194,8 +187,6 @@ EXCEPTION_LIBRUS_MESSAGES_FILE_REQUEST EXCEPTION_NOTIFY EXCEPTION_LIBRUS_MESSAGES_REQUEST - EXCEPTION_EDUDZIENNIK_WEB_REQUEST - EXCEPTION_EDUDZIENNIK_FILE_REQUEST ERROR_ONEDRIVE_DOWNLOAD EXCEPTION_VULCAN_WEB_LOGIN EXCEPTION_VULCAN_WEB_REQUEST @@ -367,13 +358,6 @@ Błąd wysyłania wiadomości - brak informacji o nadawcy. W związku z wygaszeniem aplikacji Dzienniczek+ przez firmę Vulcan, należy zalogować się ponownie.\n\nAby móc dalej korzystać z aplikacji Szkolny.eu, otwórz Ustawienia i wybierz opcję Dodaj nowego ucznia.\nNastępnie zaloguj się do dziennika Vulcan zgodnie z instrukcją.\n\nPrzepraszamy za niedogodności. - Błędny email lub hasło - Inny błąd logowania - Brak ID sesji - Ograniczony dostęp do dziennika - Sesja wygasła - Nie można pobrać informacji o klasie i szkole - Nieprawidłowy token Przekroczono maksymalną liczbę urządzeń (5) ERROR_PODLASIE_API_NO_TOKEN @@ -393,8 +377,6 @@ EXCEPTION_LIBRUS_MESSAGES_FILE_REQUEST EXCEPTION_NOTIFY Zgłoś błąd: pobieranie wiadomości LIBRUS® - Wystąpił błąd - Wystąpił błąd podczas pobierania pliku Nie udało się pobrać pliku z OneDrive EXCEPTION_VULCAN_WEB_LOGIN EXCEPTION_VULCAN_WEB_REQUEST diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa04fd00..a8f81073 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -340,9 +340,6 @@ Pobieranie grup klasowych… Pobieranie planu lekcji… Pobieranie informacji o jednostce… - Logowanie do Edudziennika… - Logowanie do iDziennika… - Logowanie do iDziennika… Logowanie do API Logowanie do wiadomości LIBRUS® Logowanie do Portalu LIBRUS® Rodzina @@ -359,7 +356,6 @@ Błąd Szczegóły błędu Podano nieprawidłowy moduł: %d Zgłoś błąd programiście - Twoje hasło do iDziennika wygasło, co oznacza że musisz je zmienić w wersji komputerowej serwisu. Identyfikator przedmiotu nie został podany. Wystąpił błąd! Wystąpił błąd: %s @@ -569,8 +565,6 @@ Zezwól na rejestrację Zaloguj Czy na pewno chcesz anulować logowanie w aplikacji? Wyświetlane profile nie zostaną zapisane. - Użyj danych, którymi logujesz się do wersji komputerowej Edudziennika. - Zaloguj się - Edudziennik Błąd: %s Konto nie zostało aktywowane Token wygasł. Wygeneruj ponownie @@ -616,10 +610,6 @@ Symbol Token Użytkownik - Użyj danych, którymi logujesz się do wersji komputerowej iDziennika. - Pomoc - iDziennik Progman - Zaloguj się danymi, które otrzymałeś od swojej szkoły. W razie problemów skorzystaj z przycisku pod formularzem. - Zaloguj się - iDziennik Progman LIBRUS® - logowanie Aby korzystać z aplikacji musisz posiadać konto LIBRUS® Rodzina. Możesz je założyć na stronie portal.librus.pl. Użyj danych, które wpisujesz w miejsca zaznaczone na obrazku. Pomoc do logowania LIBRUS® @@ -1354,10 +1344,6 @@ Podaj dane, którymi logujesz się na stronie internetowej dziennika VULCAN® lub na miejskiej platformie. Podaj dane, których używasz do logowania na stronie MobiDziennika. Jako adres serwera możesz wpisać adres strony internetowej, na której masz MobiDziennik. Logowanie do dziennika VULCAN®... - EduDziennik - Zaloguj używając e-maila i hasła - Użyj danych, które podajesz na stronie internetowej e-dziennika - Podaj adres e-mail i hasło, których używasz do logowania w przeglądarce na stronie EduDziennika. Podlaska Platforma Edukacyjna Zaloguj używając tokenu Podaj token aplikacji mobilnej. diff --git a/app/src/play-not/java/pl/szczodrzynski/edziennik/sync/UpdateDownloaderService.kt b/app/src/play-not/java/pl/szczodrzynski/edziennik/sync/UpdateDownloaderService.kt index 31c24d2f..93881939 100644 --- a/app/src/play-not/java/pl/szczodrzynski/edziennik/sync/UpdateDownloaderService.kt +++ b/app/src/play-not/java/pl/szczodrzynski/edziennik/sync/UpdateDownloaderService.kt @@ -115,6 +115,7 @@ class UpdateDownloaderService : IntentService(UpdateDownloaderService::class.jav Toast.makeText(app, "Nie można znaleźć katalogu docelowego. Pobierz aktualizację ręcznie z Google Play.", Toast.LENGTH_LONG).show() return } + Toast.makeText(app, "Pobieranie aktualizacji Szkolny.eu ${update.versionName}", Toast.LENGTH_LONG).show() downloadId = downloadManager.enqueue(request) } } diff --git a/build.gradle b/build.gradle index 3c8bdc7f..3088163b 100644 --- a/build.gradle +++ b/build.gradle @@ -2,17 +2,17 @@ buildscript { ext { - kotlin_version = '1.5.30' + kotlin_version = '1.6.10' release = [ - versionName: "4.11.5", - versionCode: 4110599 + versionName: "4.11.8", + versionCode: 4110899 ] setup = [ - compileSdk: 30, + compileSdk: 33, minSdk : 16, - targetSdk : 30 + targetSdk : 33 ] } @@ -21,10 +21,10 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.3' + classpath 'com.android.tools.build:gradle:7.2.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - classpath 'com.google.gms:google-services:4.3.10' - classpath 'com.google.firebase:firebase-crashlytics-gradle:2.7.1' + classpath 'com.google.gms:google-services:4.3.14' + classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4c24d72f..e004eb08 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Wed Feb 17 14:04:38 CET 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME