mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-17 07:51:55 +02:00
Compare commits
192 Commits
v4.0-beta.
...
v4.0-beta.
Author | SHA1 | Date | |
---|---|---|---|
40cdc7d713 | |||
49825aca48 | |||
1d57c4e705 | |||
87ae5787ee | |||
20f16c25a3 | |||
6f1ec79d9b | |||
18c7eea89c | |||
f73060aeb6 | |||
2f653b83b6 | |||
445dec907d | |||
927316d24b | |||
3957453ed6 | |||
0296c704cb | |||
1e7fe972de | |||
c95bc656ea | |||
a082d95b04 | |||
6866dd4801 | |||
2186da416e | |||
22d859fcde | |||
39514b69b3 | |||
c384736840 | |||
507657f273 | |||
60641742ed | |||
0fc6f07986 | |||
1b2bdc0580 | |||
9bac239f77 | |||
371acb2d2a | |||
454f82e139 | |||
e8da249353 | |||
c7950c53da | |||
b5502478e4 | |||
4480a7e486 | |||
7c7dff743b | |||
c568cd3f2e | |||
6ec2bc6f21 | |||
af3b6f3a97 | |||
d855118610 | |||
c9992d9fe8 | |||
85fe2636cc | |||
35f4a31a76 | |||
1e494ebb70 | |||
ed93627505 | |||
b9b4b0036f | |||
4aa31424d6 | |||
8a825227cb | |||
cc1b581d7e | |||
9936d90ae2 | |||
df1a241b2b | |||
ae89b33fb7 | |||
e05b483f5c | |||
715f536b23 | |||
930813fb8a | |||
acd5e9b998 | |||
06011bf4ae | |||
30e15b813c | |||
fcd7a7f349 | |||
42ef40439e | |||
098beb14fe | |||
0b186a754a | |||
d00963b53d | |||
e282af0e80 | |||
630361849c | |||
88a1de50ca | |||
d8263d0b6a | |||
611ab0f100 | |||
70c307b796 | |||
054a233ad6 | |||
55268f1c43 | |||
1bec6d281c | |||
f17a02be54 | |||
4e8fdd2225 | |||
59819b4a96 | |||
673378d8d9 | |||
30044d6b21 | |||
ee43d40680 | |||
1354faf8c7 | |||
1bfb3781ab | |||
d7d0c6f822 | |||
2bea18dc3c | |||
f998f2d956 | |||
faa77ee5fb | |||
88ec463284 | |||
b7df71d7d9 | |||
6a28dbd2c4 | |||
010f7fa1fe | |||
209f98594f | |||
54121c99a3 | |||
f6f1370edf | |||
d5863485f9 | |||
afc88d316b | |||
b141279811 | |||
1997ea25d5 | |||
f4b49eecd4 | |||
a4493ec964 | |||
af8bda9e92 | |||
06d252e4ca | |||
67be456bb0 | |||
aa5e225148 | |||
367f46fac8 | |||
d2f14093ec | |||
43ed621879 | |||
15c8134d13 | |||
c2b8f71467 | |||
a6b91c3a14 | |||
164cfbfd0d | |||
0bb340e96e | |||
f0447dc455 | |||
626bbfa7a4 | |||
169a900f01 | |||
d0992eaf54 | |||
fc21d757c3 | |||
54363ee919 | |||
fdad3b9997 | |||
4ad826ebe8 | |||
f5e1e9fdd9 | |||
82b232d0e5 | |||
c8c1fe5367 | |||
71128e0244 | |||
453bcaa1f6 | |||
48898ab1d4 | |||
a095520d0d | |||
2e0c6fa6a5 | |||
bfbc0861df | |||
3a500f3f28 | |||
df8094c39c | |||
448fd0e884 | |||
4717b4549e | |||
57a8d72f1c | |||
7e57617e04 | |||
37ddd643ac | |||
bcf3fef303 | |||
7ac4d24106 | |||
93e5bce778 | |||
d48beba307 | |||
760338496c | |||
b52e7a3078 | |||
78c5b6b2a5 | |||
60a3c38951 | |||
4763033f24 | |||
3b0570d21c | |||
16bf478d1a | |||
5bf181b6d1 | |||
21b2e5d194 | |||
759afcf3ca | |||
d48c7844a4 | |||
7d8caa8df7 | |||
62f53930da | |||
9a45cbb679 | |||
8e5a10f6d8 | |||
10c57d2272 | |||
67d4d0f898 | |||
97e0d04842 | |||
3ba30ede92 | |||
1035e411ab | |||
d5ae4b7ec9 | |||
111d040cf9 | |||
8cc594d170 | |||
d8a8bed68d | |||
eedbd954bd | |||
0eb8366027 | |||
894135104b | |||
7b2e408efc | |||
e4115c122e | |||
537b16949e | |||
ca60ceb2a7 | |||
0fad12fea5 | |||
6cd2c23aac | |||
512baaa43f | |||
d097fcc973 | |||
621dbd459c | |||
840ab4b0c4 | |||
904be34a87 | |||
b7fc6fcc38 | |||
55c6e40d6d | |||
4dfb015057 | |||
e40a0ba2bb | |||
fd48f10df9 | |||
6a54e7fef7 | |||
5c4d6ed140 | |||
9ed1be3594 | |||
c5ce582678 | |||
2050083bce | |||
92e6bdb562 | |||
93e70c38b7 | |||
45b96179a5 | |||
a29a534a40 | |||
8e2297359c | |||
92ba7248ef | |||
f657d37cbd | |||
9e312f60bf | |||
85f72b78f7 | |||
40acb67ceb |
@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
|
|||||||
//apply plugin: 'me.tatarka.retrolambda'
|
//apply plugin: 'me.tatarka.retrolambda'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
|
|
||||||
android {
|
android {
|
||||||
lintOptions {
|
lintOptions {
|
||||||
@ -12,7 +12,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion setup.targetSdk
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
@ -43,9 +43,9 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
// Google libraries
|
// Google libraries
|
||||||
implementation "androidx.appcompat:appcompat:${androidXAppCompat}"
|
implementation "androidx.appcompat:appcompat:${versions.appcompat}"
|
||||||
implementation "androidx.recyclerview:recyclerview:${androidXRecyclerView}"
|
implementation "androidx.recyclerview:recyclerview:${versions.recyclerView}"
|
||||||
implementation "com.google.android.material:material:${googleMaterial}"
|
implementation "com.google.android.material:material:${versions.material}"
|
||||||
|
|
||||||
// other libraries
|
// other libraries
|
||||||
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
//implementation 'se.emilsjolander:stickylistheaders:2.7.0'
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
apply plugin: 'kotlin-kapt'
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
apply plugin: 'io.fabric'
|
apply plugin: 'io.fabric'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
}
|
}
|
||||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
compileSdkVersion setup.compileSdk
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId 'pl.szczodrzynski.edziennik'
|
applicationId 'pl.szczodrzynski.edziennik'
|
||||||
minSdkVersion setup.minSdk
|
minSdkVersion setup.minSdk
|
||||||
@ -103,7 +104,7 @@ tasks.whenTaskAdded { task ->
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
|
|
||||||
annotationProcessor "androidx.room:room-compiler:${versions.room}"
|
kapt "androidx.room:room-compiler:${versions.room}"
|
||||||
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
|
||||||
|
|
||||||
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
|
||||||
@ -165,8 +166,8 @@ dependencies {
|
|||||||
//implementation project(":Navigation")
|
//implementation project(":Navigation")
|
||||||
implementation project(":szkolny-font")
|
implementation project(":szkolny-font")
|
||||||
|
|
||||||
debugImplementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
|
implementation "com.github.ChuckerTeam.Chucker:library:3.0.1"
|
||||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
|
//releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:3.0.1"
|
||||||
|
|
||||||
//implementation 'com.github.wulkanowy:uonet-request-signer:master-SNAPSHOT'
|
//implementation 'com.github.wulkanowy:uonet-request-signer:master-SNAPSHOT'
|
||||||
//implementation 'com.github.kuba2k2.uonet-request-signer:android:master-63f094b14a-1'
|
//implementation 'com.github.kuba2k2.uonet-request-signer:android:master-63f094b14a-1'
|
||||||
@ -187,6 +188,10 @@ dependencies {
|
|||||||
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
implementation "com.squareup.retrofit2:converter-gson:${versions.retrofit}"
|
||||||
|
|
||||||
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
implementation 'com.github.jetradarmobile:android-snowfall:1.2.0'
|
||||||
|
|
||||||
|
implementation "io.coil-kt:coil:0.9.2"
|
||||||
|
|
||||||
|
implementation 'com.github.kuba2k2:NumberSlidingPicker:2921225f76'
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -24,11 +24,12 @@
|
|||||||
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
-keep class pl.szczodrzynski.edziennik.utils.models.** { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; }
|
-keep class pl.szczodrzynski.edziennik.data.db.entity.Event { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; }
|
-keep class pl.szczodrzynski.edziennik.data.db.full.EventFull { *; }
|
||||||
|
-keep class pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage { *; }
|
||||||
-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; }
|
-keep class pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel { *; }
|
||||||
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
-keepclassmembers class pl.szczodrzynski.edziennik.ui.widgets.WidgetConfig { public *; }
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.timetable.WidgetTimetableProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.notifications.WidgetNotificationsProvider
|
||||||
-keepnames class pl.szczodrzynski.edziennik.widgets.luckynumber.WidgetLuckyNumber
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||||
|
|
||||||
-keep class .R
|
-keep class .R
|
||||||
-keep class **.R$* {
|
-keep class **.R$* {
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoDisplay">
|
android:theme="@style/AppTheme.Dark.NoDisplay">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
@ -80,10 +80,11 @@
|
|||||||
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
<service android:name=".ui.widgets.timetable.WidgetTimetableService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
<activity android:name=".ui.widgets.LessonDialogActivity"
|
<activity android:name=".ui.widgets.LessonDialogActivity"
|
||||||
|
android:label=""
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:excludeFromRecents="true"
|
android:excludeFromRecents="true"
|
||||||
android:noHistory="true"
|
android:noHistory="true"
|
||||||
android:theme="@style/AppTheme.NoDisplay" />
|
android:theme="@style/AppTheme.Dark.NoDisplay" />
|
||||||
<!-- NOTIFICATIONS -->
|
<!-- NOTIFICATIONS -->
|
||||||
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
<receiver android:name=".ui.widgets.notifications.WidgetNotificationsProvider"
|
||||||
android:label="@string/widget_notifications_title">
|
android:label="@string/widget_notifications_title">
|
||||||
@ -141,12 +142,8 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
<activity android:name=".ui.modules.settings.SettingsLicenseActivity"
|
||||||
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
android:theme="@style/AppTheme" />
|
android:theme="@style/AppTheme" />
|
||||||
<activity android:name=".ui.modules.webpush.WebPushConfigActivity"
|
|
||||||
android:configChanges="orientation|keyboardHidden"
|
|
||||||
android:theme="@style/AppTheme.Dark" />
|
|
||||||
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
<activity android:name=".ui.modules.webpush.QrScannerActivity" />
|
||||||
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
<activity android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
|
||||||
android:configChanges="orientation|keyboardHidden"
|
android:configChanges="orientation|keyboardHidden"
|
||||||
@ -165,18 +162,9 @@
|
|||||||
<action android:name="android.intent.action.USER_PRESENT" />
|
<action android:name="android.intent.action.USER_PRESENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.BootReceiver">
|
<receiver android:name=".sync.UpdateDownloaderService$DownloadProgressReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
|
||||||
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
<action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
|
||||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
|
||||||
</intent-filter>
|
|
||||||
</receiver>
|
|
||||||
<receiver android:name=".sync.FirebaseBroadcastReceiver"
|
|
||||||
android:exported="true"
|
|
||||||
android:permission="com.google.android.c2dm.permission.SEND">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
|
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver android:name=".receivers.SzkolnyReceiver"
|
<receiver android:name=".receivers.SzkolnyReceiver"
|
||||||
@ -193,16 +181,22 @@
|
|||||||
____) | __/ | \ V /| | (_| __/\__ \
|
____) | __/ | \ V /| | (_| __/\__ \
|
||||||
|_____/ \___|_| \_/ |_|\___\___||___/
|
|_____/ \___|_| \_/ |_|\___\___||___/
|
||||||
-->
|
-->
|
||||||
<service android:name=".sync.MyFirebaseMessagingService"
|
<!--<service android:name=".sync.MyFirebaseMessagingService"
|
||||||
android:exported="false">
|
android:exported="false">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>-->
|
||||||
<service android:name=".receivers.BootReceiver$NotificationActionService" />
|
|
||||||
<service android:name=".Notifier$GetDataRetryService" />
|
|
||||||
<service android:name=".data.api.ApiService" />
|
<service android:name=".data.api.ApiService" />
|
||||||
|
<service android:name=".data.firebase.MyFirebaseService"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter android:priority="10000000">
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
|
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
<service android:name=".sync.UpdateDownloaderService" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
_____ _ _
|
_____ _ _
|
||||||
|
@ -1,20 +1,27 @@
|
|||||||
<h3>Wersja 4.0-beta.3, 2020-01-10</h3>
|
<h3>Wersja 4.0-beta.14, 2020-03-24</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkosć oraz poprawność pobieranych danych.</li>
|
<li><b>Przebudowaliśmy cały moduł synchronizacji</b>, co oznacza większą stabilność aplikacji, szybkość oraz poprawność pobieranych danych.</li>
|
||||||
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
<li><b><u>Wysyłanie wiadomości</u></b> - funkcja, na którą czekał każdy. Od teraz w Szkolnym można wysyłać oraz odpowiadać na wiadomości do nauczycieli 👏</li>
|
||||||
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
<li>Udoskonalony wygląd Szkolnego - sprawi, że korzystanie z aplikacji będzie jeszcze przyjemniejsze</li>
|
||||||
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
<li>Nowa <b>Strona główna</b> - ładniejszy wygląd oraz możliwość przestawiania kart na każdym profilu</li>
|
||||||
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
<li>Nowy <b>Plan lekcji</b> - z doskonałą obsługą lekcji przesuniętych oraz dwóch lekcji o tej samej godzinie</li>
|
||||||
|
<li>Nowe <b>Oceny</b> - z możliwością zmiany wartości plusów oraz minusów oraz wyłączenia niektórych ocen ze średniej</li>
|
||||||
|
<li>Opcja wyłączenia wybranych powiadomień z aplikacji</li>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
<li>Nowe okienka informacji o wydarzeniach oraz lekcjach</li>
|
||||||
<li>Łatwiejsze dodawanie własnych wydarzeń</li>
|
<li>Nowe, przyjemniejsze powiadomienia</li>
|
||||||
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
<li>Dużo poprawek w widoku <b>Wiadomości</b> oraz <b>Ogłoszeń</b></li>
|
||||||
<li>Częściowa <b>Obsługa dziennika EduDziennik</b></li>
|
<li>Częściowa <b>Obsługa dziennika EduDziennik</b></li>
|
||||||
<li>Librus: opcja logowania w dziennikach <b>Jednostek Samorządu Terytorialnego</b> oraz <b>Oświata w Radomiu</b></li>
|
<li>Librus: opcja logowania w dziennikach <b>Jednostek Samorządu Terytorialnego</b> oraz <b>Oświata w Radomiu</b></li>
|
||||||
<li>Librus: <b>poprawione obliczanie frekwencji</b></li>
|
<li>Librus: <b>poprawione obliczanie frekwencji</b></li>
|
||||||
<li>Librus: obsługa Zadań domowych bez posiadania Mobilnych dodatków (przez system Synergia)</li>
|
<li>Librus: obsługa Zadań domowych bez posiadania Mobilnych dodatków (przez system Synergia)</li>
|
||||||
<li>Lepsze <b>przekazywanie powiadomień na komputer</b> oraz łatwiejsze parowanie</li>
|
<li>Lepsze <b>przekazywanie powiadomień na komputer</b> oraz łatwiejsze parowanie</li>
|
||||||
|
<li>Łatwiejsze dodawanie własnych wydarzeń</li>
|
||||||
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
<li>Poprawiliśmy synchronizację w tle na niektórych telefonach</li>
|
||||||
|
<li>Usunąłem denerwujący brak zaznaczenia w lewym menu</li>
|
||||||
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
<li>Znaczna ilość błędów z poprzednich wersji już nie występuje</li>
|
||||||
|
<li><strike>Występują natomiast nowe błędy, dlatego proszę o ich zgłaszanie :)</strike></li>
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
@ -22,16 +29,10 @@
|
|||||||
<b>Uwaga.</b> Ponieważ to wersja <i>beta</i>, niektóre funkcje mogą nie działać prawidłowo.<br>
|
<b>Uwaga.</b> Ponieważ to wersja <i>beta</i>, niektóre funkcje mogą nie działać prawidłowo.<br>
|
||||||
Staramy się usuwać takie przypadki, jednak na chwilę obecną mogą występować błędy w:
|
Staramy się usuwać takie przypadki, jednak na chwilę obecną mogą występować błędy w:
|
||||||
<ul>
|
<ul>
|
||||||
<li>Wysyłanie wiadomości może czasami nie działać - proszę o zgłaszanie wszystkich błędów na naszym serwerze Discord</li>
|
<li>Wysyłanie wiadomości może nie działać w pełni prawidłowo - proszę o zgłaszanie wszystkich błędów na naszym serwerze Discord</li>
|
||||||
<li>Terminarz - brak informacji o odwołanych lekcjach w dialogu</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
|
||||||
<i>Okazja ograniczona czasowo:</i> Poczuj prawdziwą zimę, włączając w Ustawieniach widok padającego śniegu!
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
<br>
|
|
||||||
Dzięki za korzystanie ze Szkolnego!<br>
|
Dzięki za korzystanie ze Szkolnego!<br>
|
||||||
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>
|
<i>© Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*secret password - removed for source code publication*/
|
/*secret password - removed for source code publication*/
|
||||||
static toys AES_IV[16] = {
|
static toys AES_IV[16] = {
|
||||||
0x1e, 0xef, 0x4e, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
0xc4, 0x97, 0xfb, 0xbd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||||
|
|
||||||
|
@ -1,714 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ShortcutInfo;
|
|
||||||
import android.content.pm.ShortcutManager;
|
|
||||||
import android.content.pm.Signature;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.Canvas;
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.graphics.drawable.Icon;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.provider.Settings;
|
|
||||||
import android.util.Base64;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import androidx.appcompat.app.AppCompatDelegate;
|
|
||||||
import androidx.work.Configuration;
|
|
||||||
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector;
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor;
|
|
||||||
import com.chuckerteam.chucker.api.RetentionManager;
|
|
||||||
import com.google.android.gms.security.ProviderInstaller;
|
|
||||||
import com.google.firebase.FirebaseApp;
|
|
||||||
import com.google.firebase.FirebaseOptions;
|
|
||||||
import com.google.firebase.iid.FirebaseInstanceId;
|
|
||||||
import com.google.firebase.messaging.FirebaseMessaging;
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.google.gson.JsonSyntaxException;
|
|
||||||
import com.hypertrack.hyperlog.HyperLog;
|
|
||||||
import com.mikepenz.iconics.Iconics;
|
|
||||||
import com.mikepenz.iconics.IconicsColor;
|
|
||||||
import com.mikepenz.iconics.IconicsDrawable;
|
|
||||||
import com.mikepenz.iconics.IconicsSize;
|
|
||||||
import com.mikepenz.iconics.typeface.IIcon;
|
|
||||||
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.ConcurrentModificationException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.net.ssl.TrustManagerFactory;
|
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
|
|
||||||
import cat.ereza.customactivityoncrash.config.CaocConfig;
|
|
||||||
import im.wangchao.mhttp.MHttp;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache;
|
|
||||||
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor;
|
|
||||||
import me.leolin.shortcutbadger.ShortcutBadger;
|
|
||||||
import okhttp3.ConnectionSpec;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.TlsVersion;
|
|
||||||
import pl.szczodrzynski.edziennik.config.Config;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing;
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.DebugLog;
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile;
|
|
||||||
import pl.szczodrzynski.edziennik.network.NetworkUtils;
|
|
||||||
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
|
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker;
|
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.DebugLogFormat;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.AppConfig;
|
|
||||||
|
|
||||||
import static pl.szczodrzynski.edziennik.data.db.entity.LoginStore.LOGIN_TYPE_MOBIDZIENNIK;
|
|
||||||
|
|
||||||
public class App extends androidx.multidex.MultiDexApplication implements Configuration.Provider {
|
|
||||||
private static final String TAG = "App";
|
|
||||||
public static int profileId = -1;
|
|
||||||
private Context mContext;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Configuration getWorkManagerConfiguration() {
|
|
||||||
return new Configuration.Builder()
|
|
||||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final int REQUEST_TIMEOUT = 10 * 1000;
|
|
||||||
|
|
||||||
// notifications
|
|
||||||
//public NotificationManager mNotificationManager;
|
|
||||||
//public final String NOTIFICATION_CHANNEL_ID_UPDATES = "4566";
|
|
||||||
//public String NOTIFICATION_CHANNEL_NAME_UPDATES;
|
|
||||||
public Notifier notifier;
|
|
||||||
|
|
||||||
public static final String APP_URL = "://edziennik.szczodrzynski.pl/app/";
|
|
||||||
|
|
||||||
public ShortcutManager shortcutManager;
|
|
||||||
|
|
||||||
public PermissionChecker permissionChecker;
|
|
||||||
|
|
||||||
public String signature = "";
|
|
||||||
public String deviceId = "";
|
|
||||||
|
|
||||||
public AppDb db;
|
|
||||||
public void debugLog(String text) {
|
|
||||||
if (!devMode)
|
|
||||||
return;
|
|
||||||
db.debugLogDao().add(new DebugLog(Utils.getCurrentTimeUsingCalendar()+": "+text));
|
|
||||||
}
|
|
||||||
public void debugLogAsync(String text) {
|
|
||||||
if (!devMode)
|
|
||||||
return;
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.debugLogDao().add(new DebugLog(Utils.getCurrentTimeUsingCalendar()+": "+text));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// network & APIs
|
|
||||||
public NetworkUtils networkUtils;
|
|
||||||
public PersistentCookieJar cookieJar;
|
|
||||||
public OkHttpClient http;
|
|
||||||
public OkHttpClient httpLazy;
|
|
||||||
|
|
||||||
public SharedPreferences appSharedPrefs; // sharedPreferences for APPCONFIG + JOBS STORE
|
|
||||||
public AppConfig appConfig; // APPCONFIG: common for all profiles
|
|
||||||
//public AppProfile profile; // current profile
|
|
||||||
public SharedPreferences registerStore; // sharedPreferences for REGISTER
|
|
||||||
//public Register register; // REGISTER for current profile, read from registerStore
|
|
||||||
|
|
||||||
public Profile profile;
|
|
||||||
public Config config;
|
|
||||||
private static Config mConfig;
|
|
||||||
public static Config getConfig() {
|
|
||||||
return mConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
// other stuff
|
|
||||||
public Gson gson;
|
|
||||||
public String requestScheme = "https";
|
|
||||||
public boolean unreadBadgesAvailable = true;
|
|
||||||
|
|
||||||
public static boolean devMode = false;
|
|
||||||
|
|
||||||
public static final boolean UPDATES_ON_PLAY_STORE = true;
|
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
|
||||||
public Icon getDesktopIconFromIconics(IIcon icon) {
|
|
||||||
final IconicsDrawable drawable = new IconicsDrawable(mContext, icon)
|
|
||||||
.color(IconicsColor.colorInt(Color.WHITE))
|
|
||||||
.size(IconicsSize.dp(48))
|
|
||||||
.padding(IconicsSize.dp(8))
|
|
||||||
.backgroundColor(IconicsColor.colorRes(R.color.colorPrimaryDark))
|
|
||||||
.roundedCorners(IconicsSize.dp(10));
|
|
||||||
//drawable.setStyle(Paint.Style.FILL);
|
|
||||||
final Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
|
||||||
final Canvas canvas = new Canvas(bitmap);
|
|
||||||
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
|
||||||
drawable.draw(canvas);
|
|
||||||
|
|
||||||
return Icon.createWithBitmap(bitmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
|
|
||||||
CaocConfig.Builder.create()
|
|
||||||
.backgroundMode(CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM) //default: CaocConfig.BACKGROUND_MODE_SHOW_CUSTOM
|
|
||||||
.enabled(true) //default: true
|
|
||||||
.showErrorDetails(true) //default: true
|
|
||||||
.showRestartButton(true) //default: true
|
|
||||||
.logErrorOnRestart(true) //default: true
|
|
||||||
.trackActivities(true) //default: false
|
|
||||||
.minTimeBetweenCrashesMs(2000) //default: 3000
|
|
||||||
.errorDrawable(R.drawable.ic_rip) //default: bug image
|
|
||||||
.restartActivity(MainActivity.class) //default: null (your app's launch activity)
|
|
||||||
.errorActivity(CrashActivity.class) //default: null (default error activity)
|
|
||||||
//.eventListener(new YourCustomEventListener()) //default: null
|
|
||||||
.apply();
|
|
||||||
mContext = this;
|
|
||||||
db = AppDb.getDatabase(this);
|
|
||||||
gson = new Gson();
|
|
||||||
networkUtils = new NetworkUtils(this);
|
|
||||||
|
|
||||||
config = new Config(db);
|
|
||||||
config.migrate(this);
|
|
||||||
mConfig = config;
|
|
||||||
|
|
||||||
Iconics.init(getApplicationContext());
|
|
||||||
Iconics.registerFont(SzkolnyFont.INSTANCE);
|
|
||||||
|
|
||||||
notifier = new Notifier(this);
|
|
||||||
permissionChecker = new PermissionChecker(mContext);
|
|
||||||
|
|
||||||
deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
|
|
||||||
|
|
||||||
cookieJar = new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(this));
|
|
||||||
|
|
||||||
appSharedPrefs = getSharedPreferences(getString(R.string.preference_file_global), Context.MODE_PRIVATE);
|
|
||||||
|
|
||||||
loadConfig();
|
|
||||||
|
|
||||||
Signing.INSTANCE.getCert(this);
|
|
||||||
|
|
||||||
Themes.INSTANCE.setThemeInt(config.getUi().getTheme());
|
|
||||||
|
|
||||||
try {
|
|
||||||
PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES);
|
|
||||||
for (Signature signature: packageInfo.signatures) {
|
|
||||||
byte[] signatureBytes = signature.toByteArray();
|
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
|
||||||
md.update(signatureBytes);
|
|
||||||
this.signature = Base64.encodeToString(md.digest(), Base64.NO_WRAP);
|
|
||||||
//Log.d(TAG, "Signature is "+this.signature);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ("f054761fbdb6a238".equals(deviceId) || BuildConfig.DEBUG) {
|
|
||||||
devMode = true;
|
|
||||||
}
|
|
||||||
else if (config.getDevModePassword() != null) {
|
|
||||||
checkDevModePassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
OkHttpClient.Builder httpBuilder = new OkHttpClient.Builder()
|
|
||||||
.cache(null)
|
|
||||||
.followRedirects(true)
|
|
||||||
.followSslRedirects(true)
|
|
||||||
.retryOnConnectionFailure(true)
|
|
||||||
.cookieJar(cookieJar)
|
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(20, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(40, TimeUnit.SECONDS);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
ProviderInstaller.installIfNeeded(this);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Play Services not found or outdated");
|
|
||||||
X509TrustManager x509TrustManager = null;
|
|
||||||
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
|
|
||||||
trustManagerFactory.init((KeyStore) null);
|
|
||||||
for (TrustManager trustManager: trustManagerFactory.getTrustManagers()) {
|
|
||||||
if (trustManager instanceof X509TrustManager)
|
|
||||||
x509TrustManager = (X509TrustManager) trustManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSLContext sc = SSLContext.getInstance("TLSv1.2");
|
|
||||||
sc.init(null, null, null);
|
|
||||||
httpBuilder.sslSocketFactory(new TLSSocketFactory(sc.getSocketFactory()), x509TrustManager);
|
|
||||||
|
|
||||||
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_0)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_1)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_2)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
List<ConnectionSpec> specs = new ArrayList<>();
|
|
||||||
specs.add(cs);
|
|
||||||
specs.add(ConnectionSpec.COMPATIBLE_TLS);
|
|
||||||
specs.add(ConnectionSpec.CLEARTEXT);
|
|
||||||
|
|
||||||
httpBuilder.connectionSpecs(specs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (Exception exc) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (App.devMode || BuildConfig.DEBUG) {
|
|
||||||
HyperLog.initialize(this);
|
|
||||||
HyperLog.setLogLevel(Log.VERBOSE);
|
|
||||||
HyperLog.setLogFormat(new DebugLogFormat(this));
|
|
||||||
|
|
||||||
ChuckerCollector chuckerCollector = new ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR);
|
|
||||||
ChuckerInterceptor chuckerInterceptor = new ChuckerInterceptor(this, chuckerCollector);
|
|
||||||
httpBuilder.addInterceptor(chuckerInterceptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
http = httpBuilder.build();
|
|
||||||
httpLazy = http.newBuilder().followRedirects(false).followSslRedirects(false).build();
|
|
||||||
|
|
||||||
MHttp.instance()
|
|
||||||
.customOkHttpClient(http);
|
|
||||||
|
|
||||||
//register = new Register(mContext);
|
|
||||||
|
|
||||||
//profileLoadById(appSharedPrefs.getInt("current_profile_id", 1));
|
|
||||||
|
|
||||||
if (config.getSync().getEnabled()) {
|
|
||||||
SyncWorker.Companion.scheduleNext(this, false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SyncWorker.Companion.cancelNext(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.metadataDao().countUnseen().observeForever(count -> {
|
|
||||||
Log.d("MainActivity", "Overall unseen count changed");
|
|
||||||
assert count != null;
|
|
||||||
if (unreadBadgesAvailable) {
|
|
||||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this, count);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//new IonCookieManager(mContext);
|
|
||||||
|
|
||||||
new Handler().post(() -> {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
shortcutManager = getSystemService(ShortcutManager.class);
|
|
||||||
|
|
||||||
ShortcutInfo shortcutTimetable = new ShortcutInfo.Builder(mContext, "item_timetable")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_timetable))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon2.cmd_timetable))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutAgenda = new ShortcutInfo.Builder(mContext, "item_agenda")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_agenda))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon.cmd_calendar))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutGrades = new ShortcutInfo.Builder(mContext, "item_grades")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_grades))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon2.cmd_numeric_5_box))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutHomework = new ShortcutInfo.Builder(mContext, "item_homeworks")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_homework))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(SzkolnyFont.Icon.szf_file_document_edit))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
ShortcutInfo shortcutMessages = new ShortcutInfo.Builder(mContext, "item_messages")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
|
||||||
.setIcon(Icon.createWithResource(this, R.mipmap.ic_shortcut_messages))
|
|
||||||
//.setIcon(getDesktopIconFromIconics(CommunityMaterial.Icon.cmd_email))
|
|
||||||
.setIntent(new Intent(Intent.ACTION_MAIN, null, this, MainActivity.class)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES ))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
shortcutManager.setDynamicShortcuts(Arrays.asList(shortcutTimetable, shortcutAgenda, shortcutGrades, shortcutHomework, shortcutMessages));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.getAppInstalledTime() == 0) {
|
|
||||||
try {
|
|
||||||
config.setAppInstalledTime(getPackageManager().getPackageInfo(getPackageName(), 0).firstInstallTime);
|
|
||||||
config.setAppRateSnackbarTime(config.getAppInstalledTime() + 7 * 24 * 60 * 60 * 1000);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Task<CapabilityInfo> capabilityInfoTask =
|
|
||||||
Wearable.getCapabilityClient(this)
|
|
||||||
.getCapability("edziennik_wear_app", CapabilityClient.FILTER_REACHABLE);
|
|
||||||
capabilityInfoTask.addOnCompleteListener((task) -> {
|
|
||||||
if (task.isSuccessful()) {
|
|
||||||
CapabilityInfo capabilityInfo = task.getResult();
|
|
||||||
assert capabilityInfo != null;
|
|
||||||
Set<Node> nodes;
|
|
||||||
nodes = capabilityInfo.getNodes();
|
|
||||||
Log.d(TAG, "Nodes "+nodes);
|
|
||||||
|
|
||||||
if (nodes.size() > 0) {
|
|
||||||
Wearable.getMessageClient(this).sendMessage(
|
|
||||||
nodes.toArray(new Node[]{})[0].getId(), "/ping", "Hello world".getBytes());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "Capability request failed to return any results.");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Wearable.getDataClient(this).addListener(dataEventBuffer -> {
|
|
||||||
Log.d(TAG, "onDataChanged(): " + dataEventBuffer);
|
|
||||||
|
|
||||||
for (DataEvent event : dataEventBuffer) {
|
|
||||||
if (event.getType() == DataEvent.TYPE_CHANGED) {
|
|
||||||
String path = event.getDataItem().getUri().getPath();
|
|
||||||
Log.d(TAG, "Data "+path+ " :: "+Arrays.toString(event.getDataItem().getData()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
FirebaseApp pushMobidziennikApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
|
||||||
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
|
||||||
.build(),
|
|
||||||
"Mobidziennik2"
|
|
||||||
);
|
|
||||||
|
|
||||||
FirebaseApp pushLibrusApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
|
||||||
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
|
||||||
.build(),
|
|
||||||
"Librus"
|
|
||||||
);
|
|
||||||
|
|
||||||
FirebaseApp pushVulcanApp = FirebaseApp.initializeApp(
|
|
||||||
this,
|
|
||||||
new FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
|
||||||
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
|
||||||
.build(),
|
|
||||||
"Vulcan"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (config.getRunSync()) {
|
|
||||||
config.setRunSync(false);
|
|
||||||
EdziennikTask.Companion.sync().enqueue(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final long startTime = System.currentTimeMillis();
|
|
||||||
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for App is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId()+". Time is "+(System.currentTimeMillis() - startTime));
|
|
||||||
config.getSync().setTokenApp(instanceIdResult.getToken());
|
|
||||||
});
|
|
||||||
/*FirebaseInstanceId.getInstance(pushMobidziennikApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Mobidziennik is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_MOBIDZIENNIK, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
});
|
|
||||||
FirebaseInstanceId.getInstance(pushLibrusApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Librus is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_LIBRUS, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
});
|
|
||||||
FirebaseInstanceId.getInstance(pushVulcanApp).getInstanceId().addOnSuccessListener(instanceIdResult -> {
|
|
||||||
Log.d(TAG, "Token for Vulcan is " + instanceIdResult.getToken() + ", ID is " + instanceIdResult.getId());
|
|
||||||
Pair<String, List<Integer>> pair = appConfig.fcmTokens.get(LOGIN_TYPE_VULCAN);
|
|
||||||
if (pair == null || pair.first == null || !pair.first.equals(instanceIdResult.getToken())) {
|
|
||||||
appConfig.fcmTokens.put(LOGIN_TYPE_VULCAN, new Pair<>(instanceIdResult.getToken(), new ArrayList<>()));
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
|
|
||||||
FirebaseMessaging.getInstance().subscribeToTopic(getPackageName());
|
|
||||||
}
|
|
||||||
catch (IllegalStateException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadConfig()
|
|
||||||
{
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
|
|
||||||
|
|
||||||
if (appSharedPrefs.contains("config")) {
|
|
||||||
// remove old-format config, save the new one and empty the incorrectly-nulled config
|
|
||||||
appConfig = gson.fromJson(appSharedPrefs.getString("config", ""), AppConfig.class);
|
|
||||||
appSharedPrefs.edit().remove("config").apply();
|
|
||||||
saveConfig();
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appSharedPrefs.contains("profiles")) {
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
/*List<Integer> appProfileIds = gson.fromJson(appSharedPrefs.getString("profiles", ""), new TypeToken<List<Integer>>(){}.getType());
|
|
||||||
for (int id: appProfileIds) {
|
|
||||||
AppProfile appProfile = gson.fromJson(appSharedPrefs.getString("profile"+id, ""), AppProfile.class);
|
|
||||||
if (appProfile != null) {
|
|
||||||
appConfig.profiles.add(appProfile);
|
|
||||||
}
|
|
||||||
appSharedPrefsEditor.remove("profile"+id);
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.remove("profiles");
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
//profilesSave();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Map<String,?> keys = appSharedPrefs.getAll();
|
|
||||||
for (Map.Entry<String,?> entry : keys.entrySet()) {
|
|
||||||
if (entry.getKey().startsWith("app.appConfig.")) {
|
|
||||||
String fieldName = entry.getKey().replace("app.appConfig.", "");
|
|
||||||
|
|
||||||
try {
|
|
||||||
Field field = AppConfig.class.getField(fieldName);
|
|
||||||
Object object;
|
|
||||||
try {
|
|
||||||
object = gson.fromJson(entry.getValue().toString(), field.getGenericType());
|
|
||||||
} catch (JsonSyntaxException e) {
|
|
||||||
Log.d(TAG, "For field "+fieldName);
|
|
||||||
e.printStackTrace();
|
|
||||||
object = entry.getValue().toString();
|
|
||||||
}
|
|
||||||
if (object != null)
|
|
||||||
field.set(appConfig, object);
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Log.w(TAG, "Should remove app.appConfig."+fieldName);
|
|
||||||
//appSharedPrefs.edit().remove("app.appConfig."+fieldName).apply(); TODO migration
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (appConfig.lastAppVersion > BuildConfig.VERSION_CODE) {
|
|
||||||
BootReceiver br = new BootReceiver();
|
|
||||||
Intent i = new Intent();
|
|
||||||
//i.putExtra("UserChecked", true);
|
|
||||||
br.onReceive(getContext(), i);
|
|
||||||
Toast.makeText(mContext, R.string.warning_older_version_running, Toast.LENGTH_LONG).show();
|
|
||||||
//Toast.makeText(mContext, "Zaktualizuj aplikację.", Toast.LENGTH_LONG).show();
|
|
||||||
//System.exit(0);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (appConfig == null) {
|
|
||||||
appConfig = new AppConfig(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void saveConfig()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
appConfig.savePending = false;
|
|
||||||
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
|
|
||||||
JsonObject appConfigJson = gson.toJsonTree(appConfig).getAsJsonObject();
|
|
||||||
for (Map.Entry<String, JsonElement> entry : appConfigJson.entrySet()) {
|
|
||||||
String jsonObj;
|
|
||||||
jsonObj = entry.getValue().toString();
|
|
||||||
/*if (entry.getValue().isJsonObject()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonObject().toString();
|
|
||||||
}
|
|
||||||
else if (entry.getValue().isJsonArray()) {
|
|
||||||
jsonObj = entry.getValue().getAsJsonArray().toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
jsonObj = entry.getValue().toString();
|
|
||||||
}*/
|
|
||||||
appSharedPrefsEditor.putString("app.appConfig." + entry.getKey(), jsonObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
}
|
|
||||||
catch (ConcurrentModificationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
//appSharedPrefs.edit().putString("config", gson.toJson(appConfig)).apply();
|
|
||||||
}
|
|
||||||
public void saveConfig(String ... fieldNames)
|
|
||||||
{
|
|
||||||
appConfig.savePending = false;
|
|
||||||
|
|
||||||
SharedPreferences.Editor appSharedPrefsEditor = appSharedPrefs.edit();
|
|
||||||
|
|
||||||
for (String fieldName: fieldNames) {
|
|
||||||
try {
|
|
||||||
Object object = AppConfig.class.getField(fieldName).get(appConfig);
|
|
||||||
appSharedPrefsEditor.putString("app.appConfig."+fieldName, gson.toJson(object));
|
|
||||||
} catch (IllegalAccessException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (ConcurrentModificationException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
appSharedPrefsEditor.apply();
|
|
||||||
//appSharedPrefs.edit().putString("config", gson.toJson(appConfig)).apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileSave() {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileSaveAsync() {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public void profileSaveAsync(Profile profile) {
|
|
||||||
AsyncTask.execute(() -> {
|
|
||||||
db.profileDao().add(profile);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void profileLoadById(int id) {
|
|
||||||
profileLoadById(id, false);
|
|
||||||
}
|
|
||||||
public void profileLoadById(int id, boolean loadedLast) {
|
|
||||||
//Log.d(TAG, "Loading ID "+id);
|
|
||||||
/*if (profile == null) {
|
|
||||||
profile = profileNew();
|
|
||||||
AppDb.profileId = profile.id;
|
|
||||||
appSharedPrefs.edit().putInt("current_profile_id", profile.id).apply();
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile == null || profile.getId() != id) {
|
|
||||||
profile = db.profileDao().getByIdNow(id);
|
|
||||||
/*if (profile == null) {
|
|
||||||
profileLoadById(id);
|
|
||||||
return;
|
|
||||||
}*/
|
|
||||||
if (profile != null) {
|
|
||||||
MainActivity.Companion.setUseOldMessages(profile.getLoginStoreType() == LOGIN_TYPE_MOBIDZIENNIK && appConfig.mobidziennikOldMessages == 1);
|
|
||||||
profileId = profile.getId();
|
|
||||||
appSharedPrefs.edit().putInt("current_profile_id", profile.getId()).apply();
|
|
||||||
config.setProfile(profileId);
|
|
||||||
}
|
|
||||||
else if (!loadedLast) {
|
|
||||||
profileLoadById(profileLastId(), true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
profileId = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*public void profileRemove(int id)
|
|
||||||
{
|
|
||||||
Profile profile = db.profileDao().getFullByIdNow(id);
|
|
||||||
|
|
||||||
if (profile.id == profile.loginStoreId) {
|
|
||||||
// this profile is the owner of the login store
|
|
||||||
// we need to check if any other profile is using it
|
|
||||||
List<Integer> transferProfileIds = db.profileDao().getIdsByLoginStoreIdNow(profile.loginStoreId);
|
|
||||||
if (transferProfileIds.size() == 1) {
|
|
||||||
// this login store is free of users, remove it along with the profile
|
|
||||||
db.loginStoreDao().remove(profile.loginStoreId);
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
else if (transferProfileIds.size() > 1) {
|
|
||||||
transferProfileIds.remove(transferProfileIds.indexOf(profile.id));
|
|
||||||
// someone is using the store
|
|
||||||
// we need to transfer it to the firstProfileId
|
|
||||||
db.loginStoreDao().changeId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
db.profileDao().changeStoreId(profile.loginStoreId, transferProfileIds.get(0));
|
|
||||||
// the current store is removed, we are ready to remove the profile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// else, the profile uses a store that it doesn't own
|
|
||||||
// leave the store and go on with removing
|
|
||||||
|
|
||||||
Log.d(TAG, "Before removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
db.profileDao().remove(profile.id);
|
|
||||||
Log.d(TAG, "After removal: "+db.profileDao().getAllNow().toString());
|
|
||||||
|
|
||||||
*//*int newId = 1;
|
|
||||||
if (appConfig.profiles.size() > 0) {
|
|
||||||
newId = appConfig.profiles.get(appConfig.profiles.size() - 1).id;
|
|
||||||
}
|
|
||||||
Log.d(TAG, "New ID: "+newId);
|
|
||||||
//Toast.makeText(mContext, "selected new id "+newId, Toast.LENGTH_SHORT).show();
|
|
||||||
profileLoadById(newId);*//*
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public int profileFirstId() {
|
|
||||||
Integer id = db.profileDao().getFirstId();
|
|
||||||
return id == null ? 1 : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int profileLastId() {
|
|
||||||
Integer id = db.profileDao().getLastId();
|
|
||||||
return id == null ? 1 : id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Context getContext()
|
|
||||||
{
|
|
||||||
return mContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkDevModePassword() {
|
|
||||||
try {
|
|
||||||
devMode = Utils.AESCrypt.decrypt("nWFVxY65Pa8/aRrT7EylNAencmOD+IxUY2Gg/beiIWY=", config.getDevModePassword()).equals("ok here you go it's enabled now")
|
|
||||||
|| BuildConfig.DEBUG;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
devMode = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -4,20 +4,80 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.ShortcutInfo
|
||||||
|
import android.content.pm.ShortcutManager
|
||||||
|
import android.graphics.drawable.Icon
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.Settings
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.multidex.MultiDexApplication
|
||||||
import androidx.work.Configuration
|
import androidx.work.Configuration
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||||
import kotlinx.coroutines.Job
|
import com.chuckerteam.chucker.api.ChuckerInterceptor
|
||||||
|
import com.chuckerteam.chucker.api.RetentionManager
|
||||||
|
import com.google.firebase.FirebaseApp
|
||||||
|
import com.google.firebase.FirebaseOptions
|
||||||
|
import com.google.firebase.iid.FirebaseInstanceId
|
||||||
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.hypertrack.hyperlog.HyperLog
|
||||||
|
import com.mikepenz.iconics.Iconics
|
||||||
|
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
|
||||||
|
import im.wangchao.mhttp.MHttp
|
||||||
|
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar
|
||||||
|
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache
|
||||||
|
import im.wangchao.mhttp.internal.cookie.persistence.SharedPrefsCookiePersistor
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
import me.leolin.shortcutbadger.ShortcutBadger
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import org.greenrobot.eventbus.EventBus
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.events.ProfileListEmptyEvent
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.network.NetworkUtils
|
||||||
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
|
||||||
|
import pl.szczodrzynski.edziennik.utils.*
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.NotificationChannelsManager
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.TimetableManager
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.UserActionManager
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScope {
|
class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
|
@Volatile
|
||||||
|
lateinit var db: AppDb
|
||||||
|
val config: Config by lazy { Config(db) }
|
||||||
|
var profile: Profile by mutableLazy { Profile(0, 0, 0, "") }
|
||||||
|
val profileId
|
||||||
|
get() = profile.id
|
||||||
|
|
||||||
var devMode = false
|
var devMode = false
|
||||||
|
var debugMode = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//lateinit var db: AppDb
|
val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
|
||||||
//val config by lazy { Config(db); // TODO migrate }
|
val userActionManager by lazy { UserActionManager(this) }
|
||||||
|
val gradesManager by lazy { GradesManager(this) }
|
||||||
|
val timetableManager by lazy { TimetableManager(this) }
|
||||||
|
|
||||||
|
val db
|
||||||
|
get() = App.db
|
||||||
|
val config
|
||||||
|
get() = App.config
|
||||||
|
val profile
|
||||||
|
get() = App.profile
|
||||||
|
val profileId
|
||||||
|
get() = App.profileId
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
override val coroutineContext: CoroutineContext
|
override val coroutineContext: CoroutineContext
|
||||||
@ -26,11 +86,9 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.setMinimumLoggingLevel(Log.VERBOSE)
|
.setMinimumLoggingLevel(Log.VERBOSE)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
/*val preferences by lazy { getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE) }
|
|
||||||
val notifier by lazy { Notifier(this) }
|
|
||||||
val permissionChecker by lazy { PermissionChecker(this) }
|
val permissionChecker by lazy { PermissionChecker(this) }
|
||||||
|
val networkUtils by lazy { NetworkUtils(this) }
|
||||||
lateinit var profile: ProfileFull
|
val gson by lazy { Gson() }
|
||||||
|
|
||||||
/* _ _ _______ _______ _____
|
/* _ _ _______ _______ _____
|
||||||
| | | |__ __|__ __| __ \
|
| | | |__ __|__ __| __ \
|
||||||
@ -48,13 +106,13 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.connectTimeout(20, TimeUnit.SECONDS)
|
.connectTimeout(20, TimeUnit.SECONDS)
|
||||||
.writeTimeout(5, TimeUnit.SECONDS)
|
.writeTimeout(5, TimeUnit.SECONDS)
|
||||||
.readTimeout(10, TimeUnit.SECONDS)
|
.readTimeout(10, TimeUnit.SECONDS)
|
||||||
builder.installHttpsSupport()
|
builder.installHttpsSupport(this)
|
||||||
|
|
||||||
if (devMode || BuildConfig.DEBUG) {
|
if (debugMode || BuildConfig.DEBUG) {
|
||||||
HyperLog.initialize(this)
|
HyperLog.initialize(this)
|
||||||
HyperLog.setLogLevel(Log.VERBOSE)
|
HyperLog.setLogLevel(Log.VERBOSE)
|
||||||
HyperLog.setLogFormat(DebugLogFormat(this))
|
HyperLog.setLogFormat(DebugLogFormat(this))
|
||||||
val chuckerCollector = ChuckerCollector(this, true, Period.ONE_HOUR)
|
val chuckerCollector = ChuckerCollector(this, true, RetentionManager.Period.ONE_HOUR)
|
||||||
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
val chuckerInterceptor = ChuckerInterceptor(this, chuckerCollector)
|
||||||
builder.addInterceptor(chuckerInterceptor)
|
builder.addInterceptor(chuckerInterceptor)
|
||||||
}
|
}
|
||||||
@ -77,22 +135,7 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
|_____/|_|\__, |_| |_|\__,_|\__|\__,_|_| \___|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
private val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
val deviceId: String by lazy { Settings.Secure.getString(contentResolver, Settings.Secure.ANDROID_ID) ?: "" }
|
||||||
private val signature: String by lazy {
|
|
||||||
var str = ""
|
|
||||||
try {
|
|
||||||
val packageInfo: PackageInfo = packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
|
|
||||||
for (signature in packageInfo.signatures) {
|
|
||||||
val signatureBytes = signature.toByteArray()
|
|
||||||
val md = MessageDigest.getInstance("SHA")
|
|
||||||
md.update(signatureBytes)
|
|
||||||
str = Base64.encodeToString(md.digest(), Base64.DEFAULT)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
str
|
|
||||||
}
|
|
||||||
private var unreadBadgesAvailable = true
|
private var unreadBadgesAvailable = true
|
||||||
|
|
||||||
/* _____ _
|
/* _____ _
|
||||||
@ -118,193 +161,194 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
.apply()
|
.apply()
|
||||||
Iconics.init(applicationContext)
|
Iconics.init(applicationContext)
|
||||||
Iconics.registerFont(SzkolnyFont)
|
Iconics.registerFont(SzkolnyFont)
|
||||||
db = AppDb.getDatabase(this)
|
App.db = AppDb(this)
|
||||||
Themes.themeInt = config.ui.theme
|
Themes.themeInt = config.ui.theme
|
||||||
|
debugMode = config.debugMode
|
||||||
MHttp.instance().customOkHttpClient(http)
|
MHttp.instance().customOkHttpClient(http)
|
||||||
|
|
||||||
|
if (!profileLoadById(config.lastProfileId)) {
|
||||||
|
db.profileDao().firstId?.let { profileLoadById(it) }
|
||||||
|
}
|
||||||
|
|
||||||
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
devMode = "f054761fbdb6a238" == deviceId || BuildConfig.DEBUG
|
||||||
if (config.devModePassword != null)
|
|
||||||
checkDevModePassword()
|
|
||||||
|
|
||||||
Signing.getCert(this)
|
Signing.getCert(this)
|
||||||
|
|
||||||
launch { async(Dispatchers.Default) {
|
launch {
|
||||||
if (config.sync.enabled) {
|
withContext(Dispatchers.Default) {
|
||||||
scheduleNext(this@App, false)
|
config.migrate(this@App)
|
||||||
} else {
|
|
||||||
cancelNext(this@App)
|
if (config.devModePassword != null)
|
||||||
|
checkDevModePassword()
|
||||||
|
debugMode = devMode || config.debugMode
|
||||||
|
|
||||||
|
if (config.sync.enabled)
|
||||||
|
SyncWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
SyncWorker.cancelNext(this@App)
|
||||||
|
|
||||||
|
if (config.sync.notifyAboutUpdates)
|
||||||
|
UpdateWorker.scheduleNext(this@App, false)
|
||||||
|
else
|
||||||
|
UpdateWorker.cancelNext(this@App)
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||||
|
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
||||||
|
|
||||||
|
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
|
||||||
|
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
||||||
|
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
|
||||||
|
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
||||||
|
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
shortcutManager.dynamicShortcuts = listOf(
|
||||||
|
shortcutTimetable,
|
||||||
|
shortcutAgenda,
|
||||||
|
shortcutGrades,
|
||||||
|
shortcutHomework,
|
||||||
|
shortcutMessages
|
||||||
|
)
|
||||||
|
} // shortcuts - end
|
||||||
|
|
||||||
|
notificationChannelsManager.registerAllChannels()
|
||||||
|
|
||||||
|
|
||||||
|
if (config.appInstalledTime == 0L)
|
||||||
|
try {
|
||||||
|
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
||||||
|
config.appRateSnackbarTime = config.appInstalledTime + 7 * DAY * MS
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
val pushMobidziennikApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
||||||
|
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
||||||
|
.build(),
|
||||||
|
"Mobidziennik2"
|
||||||
|
)
|
||||||
|
|
||||||
|
val pushLibrusApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
||||||
|
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
||||||
|
.build(),
|
||||||
|
"Librus"
|
||||||
|
)
|
||||||
|
|
||||||
|
val pushVulcanApp = FirebaseApp.initializeApp(
|
||||||
|
this@App,
|
||||||
|
FirebaseOptions.Builder()
|
||||||
|
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
||||||
|
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
||||||
|
.build(),
|
||||||
|
"Vulcan"
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
config.sync.tokenApp = token
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
if (token != config.sync.tokenMobidziennik) {
|
||||||
|
config.sync.tokenMobidziennik = token
|
||||||
|
config.sync.tokenMobidziennikList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
if (token != config.sync.tokenLibrus) {
|
||||||
|
config.sync.tokenLibrus = token
|
||||||
|
config.sync.tokenLibrusList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
||||||
|
val token = instanceIdResult.token
|
||||||
|
if (token != config.sync.tokenVulcan) {
|
||||||
|
config.sync.tokenVulcan = token
|
||||||
|
config.sync.tokenVulcanList = listOf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
|
||||||
|
} catch (e: IllegalStateException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
db.metadataDao().countUnseen().observeForever { count: Int ->
|
db.metadataDao().countUnseen().observeForever { count: Int ->
|
||||||
if (unreadBadgesAvailable)
|
if (unreadBadgesAvailable)
|
||||||
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
unreadBadgesAvailable = ShortcutBadger.applyCount(this@App, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
|
||||||
val shortcutManager = getSystemService(ShortcutManager::class.java)
|
|
||||||
|
|
||||||
val shortcutTimetable = ShortcutInfo.Builder(this@App, "item_timetable")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_timetable)).setLongLabel(getString(R.string.shortcut_timetable))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_timetable))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_TIMETABLE))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutAgenda = ShortcutInfo.Builder(this@App, "item_agenda")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_agenda)).setLongLabel(getString(R.string.shortcut_agenda))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_agenda))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_AGENDA))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutGrades = ShortcutInfo.Builder(this@App, "item_grades")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_grades)).setLongLabel(getString(R.string.shortcut_grades))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_grades))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_GRADES))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutHomework = ShortcutInfo.Builder(this@App, "item_homeworks")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_homework)).setLongLabel(getString(R.string.shortcut_homework))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_homework))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_HOMEWORK))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
val shortcutMessages = ShortcutInfo.Builder(this@App, "item_messages")
|
|
||||||
.setShortLabel(getString(R.string.shortcut_messages)).setLongLabel(getString(R.string.shortcut_messages))
|
|
||||||
.setIcon(Icon.createWithResource(this@App, R.mipmap.ic_shortcut_messages))
|
|
||||||
.setIntent(Intent(Intent.ACTION_MAIN, null, this@App, MainActivity::class.java)
|
|
||||||
.putExtra("fragmentId", MainActivity.DRAWER_ITEM_MESSAGES))
|
|
||||||
.build()
|
|
||||||
|
|
||||||
shortcutManager.dynamicShortcuts = listOf(
|
|
||||||
shortcutTimetable,
|
|
||||||
shortcutAgenda,
|
|
||||||
shortcutGrades,
|
|
||||||
shortcutHomework,
|
|
||||||
shortcutMessages
|
|
||||||
)
|
|
||||||
} // shortcuts - end
|
|
||||||
|
|
||||||
if (config.appInstalledTime == 0L)
|
|
||||||
try {
|
|
||||||
config.appInstalledTime = packageManager.getPackageInfo(packageName, 0).firstInstallTime
|
|
||||||
config.appRateSnackbarTime = config.appInstalledTime + 7*DAY*MS
|
|
||||||
} catch (e: NameNotFoundException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
|
|
||||||
val pushMobidziennikApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyCi5LmsZ5BBCQnGtrdvWnp1bWLCNP8OWQE")
|
|
||||||
.setApplicationId("1:747285019373:android:f6341bf7b158621d")
|
|
||||||
.build(),
|
|
||||||
"Mobidziennik2"
|
|
||||||
)
|
|
||||||
|
|
||||||
val pushLibrusApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDfTuEoYPKdv4aceEws1CO3n0-HvTndz-o")
|
|
||||||
.setApplicationId("1:513056078587:android:1e29083b760af544")
|
|
||||||
.build(),
|
|
||||||
"Librus"
|
|
||||||
)
|
|
||||||
|
|
||||||
val pushVulcanApp = FirebaseApp.initializeApp(
|
|
||||||
this@App,
|
|
||||||
FirebaseOptions.Builder()
|
|
||||||
.setApiKey("AIzaSyDW8MUtanHy64_I0oCpY6cOxB3jrvJd_iA")
|
|
||||||
.setApplicationId("1:987828170337:android:ac97431a0a4578c3")
|
|
||||||
.build(),
|
|
||||||
"Vulcan"
|
|
||||||
)
|
|
||||||
|
|
||||||
try {
|
|
||||||
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
config.sync.tokenApp = token
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushMobidziennikApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenMobidziennik) {
|
|
||||||
config.sync.tokenMobidziennik = token
|
|
||||||
config.sync.tokenMobidziennikList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushLibrusApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenLibrus) {
|
|
||||||
config.sync.tokenLibrus = token
|
|
||||||
config.sync.tokenLibrusList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseInstanceId.getInstance(pushVulcanApp).instanceId.addOnSuccessListener { instanceIdResult ->
|
|
||||||
val token = instanceIdResult.token
|
|
||||||
if (token != config.sync.tokenVulcan) {
|
|
||||||
config.sync.tokenVulcan = token
|
|
||||||
config.sync.tokenVulcanList = listOf()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FirebaseMessaging.getInstance().subscribeToTopic(packageName)
|
|
||||||
} catch (e: IllegalStateException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun profileLoad(profileId: Int) {
|
|
||||||
db.profileDao().getFullByIdNow(profileId)?.also {
|
|
||||||
profile = it
|
|
||||||
} ?: run {
|
|
||||||
if (!::profile.isInitialized) {
|
|
||||||
profile = ProfileFull(-1, "", "", -1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun profileLoad(profileId: Int, onSuccess: (profile: ProfileFull) -> Unit) {
|
|
||||||
|
private fun profileLoadById(profileId: Int): Boolean {
|
||||||
|
db.profileDao().getByIdNow(profileId)?.also {
|
||||||
|
App.profile = it
|
||||||
|
App.config.lastProfileId = it.id
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
fun profileLoad(profileId: Int, onSuccess: (profile: Profile) -> Unit) {
|
||||||
launch {
|
launch {
|
||||||
val deferred = async(Dispatchers.Default) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
profileLoad(profileId)
|
profileLoadById(profileId)
|
||||||
}
|
}
|
||||||
deferred.await()
|
if (success)
|
||||||
onSuccess(profile)
|
onSuccess(profile)
|
||||||
|
else
|
||||||
|
profileLoadLast(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun profileLoadLast(onSuccess: (profile: Profile) -> Unit) {
|
||||||
private fun OkHttpClient.Builder.installHttpsSupport() {
|
launch {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
val success = withContext(Dispatchers.Default) {
|
||||||
try {
|
profileLoadById(db.profileDao().lastId ?: return@withContext false)
|
||||||
try {
|
|
||||||
ProviderInstaller.installIfNeeded(this@App)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
|
||||||
|
|
||||||
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
|
||||||
trustManagerFactory.init(null as KeyStore?)
|
|
||||||
|
|
||||||
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
|
||||||
?: return
|
|
||||||
|
|
||||||
val sc = SSLContext.getInstance("TLSv1.2")
|
|
||||||
sc.init(null, null, null)
|
|
||||||
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
|
||||||
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_0)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_1)
|
|
||||||
.tlsVersions(TlsVersion.TLS_1_2)
|
|
||||||
.build()
|
|
||||||
val specs: MutableList<ConnectionSpec> = ArrayList()
|
|
||||||
specs.add(cs)
|
|
||||||
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
|
||||||
specs.add(ConnectionSpec.CLEARTEXT)
|
|
||||||
connectionSpecs(specs)
|
|
||||||
}
|
|
||||||
} catch (exc: Exception) {
|
|
||||||
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
|
||||||
}
|
}
|
||||||
|
if (!success) {
|
||||||
|
EventBus.getDefault().post(ProfileListEmptyEvent())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun profileSave() = profileSave(profile)
|
||||||
|
fun profileSave(profile: Profile) {
|
||||||
|
launch(Dispatchers.Default) {
|
||||||
|
App.db.profileDao().add(profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,5 +359,5 @@ class Szkolny : /*MultiDexApplication(),*/ Configuration.Provider, CoroutineScop
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kuba Szczodrzyński 2019-11-11.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import androidx.databinding.BindingAdapter;
|
|
||||||
|
|
||||||
public class Binding {
|
|
||||||
@BindingAdapter("strikeThrough")
|
|
||||||
public static void strikeThrough(TextView textView, Boolean strikeThrough) {
|
|
||||||
if (strikeThrough) {
|
|
||||||
textView.setPaintFlags(textView.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
} else {
|
|
||||||
textView.setPaintFlags(textView.getPaintFlags() & ~Paint.STRIKE_THRU_TEXT_FLAG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
20
app/src/main/java/pl/szczodrzynski/edziennik/Binding.kt
Normal file
20
app/src/main/java/pl/szczodrzynski/edziennik/Binding.kt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-11-11.
|
||||||
|
*/
|
||||||
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
|
import android.graphics.Paint
|
||||||
|
import android.widget.TextView
|
||||||
|
import androidx.databinding.BindingAdapter
|
||||||
|
|
||||||
|
object Binding {
|
||||||
|
@JvmStatic
|
||||||
|
@BindingAdapter("strikeThrough")
|
||||||
|
fun strikeThrough(textView: TextView, strikeThrough: Boolean) {
|
||||||
|
if (strikeThrough) {
|
||||||
|
textView.paintFlags = textView.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
|
||||||
|
} else {
|
||||||
|
textView.paintFlags = textView.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,13 +2,17 @@ package pl.szczodrzynski.edziennik
|
|||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.graphics.PorterDuff
|
import android.graphics.PorterDuff
|
||||||
import android.graphics.PorterDuffColorFilter
|
import android.graphics.PorterDuffColorFilter
|
||||||
|
import android.graphics.Rect
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@ -22,8 +26,10 @@ import android.util.Base64
|
|||||||
import android.util.Base64.NO_WRAP
|
import android.util.Base64.NO_WRAP
|
||||||
import android.util.Base64.encodeToString
|
import android.util.Base64.encodeToString
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.WindowManager
|
||||||
import android.widget.CheckBox
|
import android.widget.CheckBox
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.RadioButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.*
|
import androidx.annotation.*
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
@ -34,30 +40,49 @@ import androidx.core.util.forEach
|
|||||||
import androidx.lifecycle.LifecycleOwner
|
import androidx.lifecycle.LifecycleOwner
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
|
import com.google.android.gms.security.ProviderInstaller
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
import com.google.gson.JsonElement
|
import com.google.gson.JsonElement
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
|
import com.google.gson.JsonParser
|
||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.RequestBody
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.TlsVersion
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApiException
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.ApiResponse
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
||||||
|
import pl.szczodrzynski.edziennik.network.TLSSocketFactory
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import java.io.InterruptedIOException
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
|
import java.net.ConnectException
|
||||||
|
import java.net.SocketTimeoutException
|
||||||
|
import java.net.UnknownHostException
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
import java.security.KeyStore
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.zip.CRC32
|
import java.util.zip.CRC32
|
||||||
import javax.crypto.Mac
|
import javax.crypto.Mac
|
||||||
import javax.crypto.spec.SecretKeySpec
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
import javax.net.ssl.SSLContext
|
||||||
|
import javax.net.ssl.SSLException
|
||||||
|
import javax.net.ssl.TrustManagerFactory
|
||||||
|
import javax.net.ssl.X509TrustManager
|
||||||
import kotlin.Pair
|
import kotlin.Pair
|
||||||
|
|
||||||
|
|
||||||
@ -75,8 +100,8 @@ fun JsonObject?.getInt(key: String): Int? = get(key)?.let { if (it.isJsonNull) n
|
|||||||
fun JsonObject?.getLong(key: String): Long? = get(key)?.let { if (it.isJsonNull) null else it.asLong }
|
fun JsonObject?.getLong(key: String): Long? = get(key)?.let { if (it.isJsonNull) null else it.asLong }
|
||||||
fun JsonObject?.getFloat(key: String): Float? = get(key)?.let { if(it.isJsonNull) null else it.asFloat }
|
fun JsonObject?.getFloat(key: String): Float? = get(key)?.let { if(it.isJsonNull) null else it.asFloat }
|
||||||
fun JsonObject?.getChar(key: String): Char? = get(key)?.let { if(it.isJsonNull) null else it.asCharacter }
|
fun JsonObject?.getChar(key: String): Char? = get(key)?.let { if(it.isJsonNull) null else it.asCharacter }
|
||||||
fun JsonObject?.getJsonObject(key: String): JsonObject? = get(key)?.let { if (it.isJsonNull) null else it.asJsonObject }
|
fun JsonObject?.getJsonObject(key: String): JsonObject? = get(key)?.let { if (it.isJsonObject) it.asJsonObject else null }
|
||||||
fun JsonObject?.getJsonArray(key: String): JsonArray? = get(key)?.let { if (it.isJsonNull) null else it.asJsonArray }
|
fun JsonObject?.getJsonArray(key: String): JsonArray? = get(key)?.let { if (it.isJsonArray) it.asJsonArray else null }
|
||||||
|
|
||||||
fun JsonObject?.getBoolean(key: String, defaultValue: Boolean): Boolean = get(key)?.let { if (it.isJsonNull) defaultValue else it.asBoolean } ?: defaultValue
|
fun JsonObject?.getBoolean(key: String, defaultValue: Boolean): Boolean = get(key)?.let { if (it.isJsonNull) defaultValue else it.asBoolean } ?: defaultValue
|
||||||
fun JsonObject?.getString(key: String, defaultValue: String): String = get(key)?.let { if (it.isJsonNull) defaultValue else it.asString } ?: defaultValue
|
fun JsonObject?.getString(key: String, defaultValue: String): String = get(key)?.let { if (it.isJsonNull) defaultValue else it.asString } ?: defaultValue
|
||||||
@ -84,8 +109,19 @@ fun JsonObject?.getInt(key: String, defaultValue: Int): Int = get(key)?.let { if
|
|||||||
fun JsonObject?.getLong(key: String, defaultValue: Long): Long = get(key)?.let { if (it.isJsonNull) defaultValue else it.asLong } ?: defaultValue
|
fun JsonObject?.getLong(key: String, defaultValue: Long): Long = get(key)?.let { if (it.isJsonNull) defaultValue else it.asLong } ?: defaultValue
|
||||||
fun JsonObject?.getFloat(key: String, defaultValue: Float): Float = get(key)?.let { if(it.isJsonNull) defaultValue else it.asFloat } ?: defaultValue
|
fun JsonObject?.getFloat(key: String, defaultValue: Float): Float = get(key)?.let { if(it.isJsonNull) defaultValue else it.asFloat } ?: defaultValue
|
||||||
fun JsonObject?.getChar(key: String, defaultValue: Char): Char = get(key)?.let { if(it.isJsonNull) defaultValue else it.asCharacter } ?: defaultValue
|
fun JsonObject?.getChar(key: String, defaultValue: Char): Char = get(key)?.let { if(it.isJsonNull) defaultValue else it.asCharacter } ?: defaultValue
|
||||||
fun JsonObject?.getJsonObject(key: String, defaultValue: JsonObject): JsonObject = get(key)?.let { if (it.isJsonNull) defaultValue else it.asJsonObject } ?: defaultValue
|
fun JsonObject?.getJsonObject(key: String, defaultValue: JsonObject): JsonObject = get(key)?.let { if (it.isJsonObject) it.asJsonObject else defaultValue } ?: defaultValue
|
||||||
fun JsonObject?.getJsonArray(key: String, defaultValue: JsonArray): JsonArray = get(key)?.let { if (it.isJsonNull) defaultValue else it.asJsonArray } ?: defaultValue
|
fun JsonObject?.getJsonArray(key: String, defaultValue: JsonArray): JsonArray = get(key)?.let { if (it.isJsonArray) it.asJsonArray else defaultValue } ?: defaultValue
|
||||||
|
|
||||||
|
fun JsonArray.getBoolean(key: Int): Boolean? = if (key >= size()) null else get(key)?.let { if (it.isJsonNull) null else it.asBoolean }
|
||||||
|
fun JsonArray.getString(key: Int): String? = if (key >= size()) null else get(key)?.let { if (it.isJsonNull) null else it.asString }
|
||||||
|
fun JsonArray.getInt(key: Int): Int? = if (key >= size()) null else get(key)?.let { if (it.isJsonNull) null else it.asInt }
|
||||||
|
fun JsonArray.getLong(key: Int): Long? = if (key >= size()) null else get(key)?.let { if (it.isJsonNull) null else it.asLong }
|
||||||
|
fun JsonArray.getFloat(key: Int): Float? = if (key >= size()) null else get(key)?.let { if(it.isJsonNull) null else it.asFloat }
|
||||||
|
fun JsonArray.getChar(key: Int): Char? = if (key >= size()) null else get(key)?.let { if(it.isJsonNull) null else it.asCharacter }
|
||||||
|
fun JsonArray.getJsonObject(key: Int): JsonObject? = if (key >= size()) null else get(key)?.let { if (it.isJsonObject) it.asJsonObject else null }
|
||||||
|
fun JsonArray.getJsonArray(key: Int): JsonArray? = if (key >= size()) null else get(key)?.let { if (it.isJsonArray) it.asJsonArray else null }
|
||||||
|
|
||||||
|
fun String.toJsonObject(): JsonObject? = try { JsonParser().parse(this).asJsonObject } catch (ignore: Exception) { null }
|
||||||
|
|
||||||
operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value)
|
operator fun JsonObject.set(key: String, value: JsonElement) = this.add(key, value)
|
||||||
operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value)
|
operator fun JsonObject.set(key: String, value: Boolean) = this.addProperty(key, value)
|
||||||
@ -642,6 +678,34 @@ fun Bundle(vararg properties: Pair<String, Any?>): Bundle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun Intent(action: String? = null, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(action).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
fun Intent(packageContext: Context, cls: Class<*>, vararg properties: Pair<String, Any?>): Intent {
|
||||||
|
return Intent(packageContext, cls).putExtras(Bundle(*properties))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Bundle.toJsonObject(): JsonObject {
|
||||||
|
val json = JsonObject()
|
||||||
|
keySet()?.forEach { key ->
|
||||||
|
get(key)?.let {
|
||||||
|
when (it) {
|
||||||
|
is String -> json.addProperty(key, it)
|
||||||
|
is Char -> json.addProperty(key, it)
|
||||||
|
is Int -> json.addProperty(key, it)
|
||||||
|
is Long -> json.addProperty(key, it)
|
||||||
|
is Float -> json.addProperty(key, it)
|
||||||
|
is Short -> json.addProperty(key, it)
|
||||||
|
is Double -> json.addProperty(key, it)
|
||||||
|
is Boolean -> json.addProperty(key, it)
|
||||||
|
is Bundle -> json.add(key, it.toJsonObject())
|
||||||
|
else -> json.addProperty(key, it.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
fun Intent.toJsonObject() = extras?.toJsonObject()
|
||||||
|
|
||||||
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
fun JsonArray?.isNullOrEmpty(): Boolean = (this?.size() ?: 0) == 0
|
||||||
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
fun JsonArray.isEmpty(): Boolean = this.size() == 0
|
||||||
@ -934,6 +998,8 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
Notification.TYPE_NEW_EVENT -> R.string.notification_type_new_event
|
||||||
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
Notification.TYPE_NEW_HOMEWORK -> R.string.notification_type_new_homework
|
||||||
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
Notification.TYPE_NEW_SHARED_EVENT -> R.string.notification_type_new_shared_event
|
||||||
|
Notification.TYPE_NEW_SHARED_HOMEWORK -> R.string.notification_type_new_shared_homework
|
||||||
|
Notification.TYPE_REMOVED_SHARED_EVENT -> R.string.notification_type_removed_shared_event
|
||||||
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
Notification.TYPE_NEW_MESSAGE -> R.string.notification_type_new_message
|
||||||
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
Notification.TYPE_NEW_NOTICE -> R.string.notification_type_notice
|
||||||
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
Notification.TYPE_NEW_ATTENDANCE -> R.string.notification_type_attendance
|
||||||
@ -950,3 +1016,153 @@ fun Context.getNotificationTitle(type: Int): String {
|
|||||||
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
fun Cursor?.getString(columnName: String) = this?.getStringOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
fun Cursor?.getInt(columnName: String) = this?.getIntOrNull(getColumnIndex(columnName))
|
||||||
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
fun Cursor?.getLong(columnName: String) = this?.getLongOrNull(getColumnIndex(columnName))
|
||||||
|
|
||||||
|
fun OkHttpClient.Builder.installHttpsSupport(context: Context) {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
ProviderInstaller.installIfNeeded(context)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Play Services not found or outdated")
|
||||||
|
|
||||||
|
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||||
|
trustManagerFactory.init(null as KeyStore?)
|
||||||
|
|
||||||
|
val x509TrustManager = trustManagerFactory.trustManagers.singleOrNull { it is X509TrustManager } as X509TrustManager?
|
||||||
|
?: return
|
||||||
|
|
||||||
|
val sc = SSLContext.getInstance("TLSv1.2")
|
||||||
|
sc.init(null, null, null)
|
||||||
|
sslSocketFactory(TLSSocketFactory(sc.socketFactory), x509TrustManager)
|
||||||
|
val cs: ConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_0)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_1)
|
||||||
|
.tlsVersions(TlsVersion.TLS_1_2)
|
||||||
|
.build()
|
||||||
|
val specs: MutableList<ConnectionSpec> = ArrayList()
|
||||||
|
specs.add(cs)
|
||||||
|
specs.add(ConnectionSpec.COMPATIBLE_TLS)
|
||||||
|
specs.add(ConnectionSpec.CLEARTEXT)
|
||||||
|
connectionSpecs(specs)
|
||||||
|
}
|
||||||
|
} catch (exc: Exception) {
|
||||||
|
Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun CharSequence.containsAll(list: List<CharSequence>, ignoreCase: Boolean = false): Boolean {
|
||||||
|
for (i in list) {
|
||||||
|
if (!contains(i, ignoreCase))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun RadioButton.setOnSelectedListener(crossinline listener: (buttonView: CompoundButton) -> Unit)
|
||||||
|
= setOnCheckedChangeListener { buttonView, isChecked -> if (isChecked) listener(buttonView) }
|
||||||
|
|
||||||
|
fun Response.toErrorCode() = when (this.code()) {
|
||||||
|
400 -> ERROR_REQUEST_HTTP_400
|
||||||
|
401 -> ERROR_REQUEST_HTTP_401
|
||||||
|
403 -> ERROR_REQUEST_HTTP_403
|
||||||
|
404 -> ERROR_REQUEST_HTTP_404
|
||||||
|
405 -> ERROR_REQUEST_HTTP_405
|
||||||
|
410 -> ERROR_REQUEST_HTTP_410
|
||||||
|
424 -> ERROR_REQUEST_HTTP_424
|
||||||
|
500 -> ERROR_REQUEST_HTTP_500
|
||||||
|
503 -> ERROR_REQUEST_HTTP_503
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
fun Throwable.toErrorCode() = when (this) {
|
||||||
|
is UnknownHostException -> ERROR_REQUEST_FAILURE_HOSTNAME_NOT_FOUND
|
||||||
|
is SSLException -> ERROR_REQUEST_FAILURE_SSL_ERROR
|
||||||
|
is SocketTimeoutException -> ERROR_REQUEST_FAILURE_TIMEOUT
|
||||||
|
is InterruptedIOException, is ConnectException -> ERROR_REQUEST_FAILURE_NO_INTERNET
|
||||||
|
is SzkolnyApiException -> this.error?.toErrorCode()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
private fun ApiResponse.Error.toErrorCode() = when (this.code) {
|
||||||
|
else -> ERROR_API_EXCEPTION
|
||||||
|
}
|
||||||
|
fun Throwable.toApiError(tag: String) = ApiError.fromThrowable(tag, this)
|
||||||
|
|
||||||
|
inline fun <A, B, R> ifNotNull(a: A?, b: B?, code: (A, B) -> R): R? {
|
||||||
|
if (a != null && b != null) {
|
||||||
|
return code(a, b)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.jvm.JvmName("averageOrNullOfInt")
|
||||||
|
fun Iterable<Int>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||||
|
@kotlin.jvm.JvmName("averageOrNullOfFloat")
|
||||||
|
fun Iterable<Float>.averageOrNull() = this.average().let { if (it.isNaN()) null else it }
|
||||||
|
|
||||||
|
fun String.copyToClipboard(context: Context) {
|
||||||
|
val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
val clipData = ClipData.newPlainText("Tekst", this)
|
||||||
|
clipboard.primaryClip = clipData
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TextView.getTextPosition(range: IntRange): Rect {
|
||||||
|
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
|
|
||||||
|
// Initialize global value
|
||||||
|
var parentTextViewRect = Rect()
|
||||||
|
|
||||||
|
// Initialize values for the computing of clickedText position
|
||||||
|
//val completeText = parentTextView.text as SpannableString
|
||||||
|
val textViewLayout = this.layout
|
||||||
|
|
||||||
|
val startOffsetOfClickedText = range.first//completeText.getSpanStart(clickedText)
|
||||||
|
val endOffsetOfClickedText = range.last//completeText.getSpanEnd(clickedText)
|
||||||
|
var startXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(startOffsetOfClickedText)
|
||||||
|
var endXCoordinatesOfClickedText = textViewLayout.getPrimaryHorizontal(endOffsetOfClickedText)
|
||||||
|
|
||||||
|
// Get the rectangle of the clicked text
|
||||||
|
val currentLineStartOffset = textViewLayout.getLineForOffset(startOffsetOfClickedText)
|
||||||
|
val currentLineEndOffset = textViewLayout.getLineForOffset(endOffsetOfClickedText)
|
||||||
|
val keywordIsInMultiLine = currentLineStartOffset != currentLineEndOffset
|
||||||
|
textViewLayout.getLineBounds(currentLineStartOffset, parentTextViewRect)
|
||||||
|
|
||||||
|
// Update the rectangle position to his real position on screen
|
||||||
|
val parentTextViewLocation = intArrayOf(0, 0)
|
||||||
|
this.getLocationOnScreen(parentTextViewLocation)
|
||||||
|
|
||||||
|
val parentTextViewTopAndBottomOffset = (parentTextViewLocation[1] - this.scrollY + this.compoundPaddingTop)
|
||||||
|
parentTextViewRect.top += parentTextViewTopAndBottomOffset
|
||||||
|
parentTextViewRect.bottom += parentTextViewTopAndBottomOffset
|
||||||
|
|
||||||
|
// In the case of multi line text, we have to choose what rectangle take
|
||||||
|
if (keywordIsInMultiLine) {
|
||||||
|
val screenHeight = windowManager.defaultDisplay.height
|
||||||
|
val dyTop = parentTextViewRect.top
|
||||||
|
val dyBottom = screenHeight - parentTextViewRect.bottom
|
||||||
|
val onTop = dyTop > dyBottom
|
||||||
|
|
||||||
|
if (onTop) {
|
||||||
|
endXCoordinatesOfClickedText = textViewLayout.getLineRight(currentLineStartOffset);
|
||||||
|
} else {
|
||||||
|
parentTextViewRect = Rect()
|
||||||
|
textViewLayout.getLineBounds(currentLineEndOffset, parentTextViewRect);
|
||||||
|
parentTextViewRect.top += parentTextViewTopAndBottomOffset;
|
||||||
|
parentTextViewRect.bottom += parentTextViewTopAndBottomOffset;
|
||||||
|
startXCoordinatesOfClickedText = textViewLayout.getLineLeft(currentLineEndOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parentTextViewRect.left += (
|
||||||
|
parentTextViewLocation[0] +
|
||||||
|
startXCoordinatesOfClickedText +
|
||||||
|
this.compoundPaddingLeft -
|
||||||
|
this.scrollX
|
||||||
|
).toInt()
|
||||||
|
parentTextViewRect.right = (
|
||||||
|
parentTextViewRect.left +
|
||||||
|
endXCoordinatesOfClickedText -
|
||||||
|
startXCoordinatesOfClickedText
|
||||||
|
).toInt()
|
||||||
|
|
||||||
|
return parentTextViewRect
|
||||||
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package pl.szczodrzynski.edziennik
|
package pl.szczodrzynski.edziennik
|
||||||
|
|
||||||
import android.app.Activity
|
|
||||||
import android.app.ActivityManager
|
import android.app.ActivityManager
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
@ -9,12 +8,10 @@ import android.content.IntentFilter
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import android.graphics.drawable.BitmapDrawable
|
import android.graphics.drawable.BitmapDrawable
|
||||||
import android.os.AsyncTask
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
import android.util.Log
|
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -36,19 +33,23 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
|||||||
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.droidsonroids.gif.GifDrawable
|
import pl.droidsonroids.gif.GifDrawable
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.Signing
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata.*
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
||||||
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
import pl.szczodrzynski.edziennik.sync.AppManagerDetectedEvent
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
import pl.szczodrzynski.edziennik.sync.SyncWorker
|
||||||
|
import pl.szczodrzynski.edziennik.sync.UpdateWorker
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.ServerMessageDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.changelog.ChangelogDialog
|
||||||
|
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.settings.ProfileRemoveDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
import pl.szczodrzynski.edziennik.ui.modules.agenda.AgendaFragment
|
||||||
@ -93,9 +94,10 @@ import pl.szczodrzynski.navlib.drawer.items.withAppTitle
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
var useOldMessages = false
|
var useOldMessages = false
|
||||||
@ -108,6 +110,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
const val DRAWER_PROFILE_SYNC_ALL = 201
|
const val DRAWER_PROFILE_SYNC_ALL = 201
|
||||||
const val DRAWER_PROFILE_EXPORT_DATA = 202
|
const val DRAWER_PROFILE_EXPORT_DATA = 202
|
||||||
const val DRAWER_PROFILE_MANAGE = 203
|
const val DRAWER_PROFILE_MANAGE = 203
|
||||||
|
const val DRAWER_PROFILE_MARK_ALL_AS_READ = 204
|
||||||
const val DRAWER_ITEM_HOME = 1
|
const val DRAWER_ITEM_HOME = 1
|
||||||
const val DRAWER_ITEM_TIMETABLE = 11
|
const val DRAWER_ITEM_TIMETABLE = 11
|
||||||
const val DRAWER_ITEM_AGENDA = 12
|
const val DRAWER_ITEM_AGENDA = 12
|
||||||
@ -208,6 +211,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
.withDescription(R.string.drawer_manage_profiles_desc)
|
.withDescription(R.string.drawer_manage_profiles_desc)
|
||||||
.isInProfileList(false)
|
.isInProfileList(false)
|
||||||
|
|
||||||
|
list += NavTarget(DRAWER_PROFILE_MARK_ALL_AS_READ, R.string.menu_mark_everything_as_read, null)
|
||||||
|
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||||
|
.isInProfileList(true)
|
||||||
|
|
||||||
list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null)
|
list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null)
|
||||||
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
.withIcon(CommunityMaterial.Icon.cmd_download_outline)
|
||||||
.isInProfileList(true)
|
.isInProfileList(true)
|
||||||
@ -226,6 +233,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var job = Job()
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = job + Dispatchers.Main
|
||||||
|
|
||||||
val b: ActivitySzkolnyBinding by lazy { ActivitySzkolnyBinding.inflate(layoutInflater) }
|
val b: ActivitySzkolnyBinding by lazy { ActivitySzkolnyBinding.inflate(layoutInflater) }
|
||||||
val navView: NavView by lazy { b.navView }
|
val navView: NavView by lazy { b.navView }
|
||||||
val drawer: NavDrawer by lazy { navView.drawer }
|
val drawer: NavDrawer by lazy { navView.drawer }
|
||||||
@ -257,15 +268,22 @@ class MainActivity : AppCompatActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
d(TAG, "Activity created")
|
||||||
|
|
||||||
setTheme(Themes.appTheme)
|
setTheme(Themes.appTheme)
|
||||||
|
|
||||||
app.config.ui.language?.let {
|
app.config.ui.language?.let {
|
||||||
setLanguage(it)
|
setLanguage(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
setContentView(b.root)
|
if (App.profileId == 0) {
|
||||||
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(TAG, Signing.appPassword)
|
d(TAG, "Profile is valid, inflating views")
|
||||||
|
|
||||||
|
setContentView(b.root)
|
||||||
|
|
||||||
mainSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
mainSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
||||||
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
errorSnackbar.setCoordinator(b.navView.coordinator, b.navView.bottomBar)
|
||||||
@ -332,8 +350,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
setAccountHeaderBackground(app.config.ui.headerBackground)
|
setAccountHeaderBackground(app.config.ui.headerBackground)
|
||||||
|
|
||||||
drawerProfileListEmptyListener = {
|
drawerProfileListEmptyListener = {
|
||||||
app.config.loginFinished = false
|
onProfileListEmptyEvent(ProfileListEmptyEvent())
|
||||||
profileListEmptyListener()
|
|
||||||
}
|
}
|
||||||
drawerItemSelectedListener = { id, position, drawerItem ->
|
drawerItemSelectedListener = { id, position, drawerItem ->
|
||||||
loadTarget(id)
|
loadTarget(id)
|
||||||
@ -362,30 +379,19 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
navTarget = navTargetList[0]
|
navTarget = navTargetList[0]
|
||||||
|
|
||||||
var profileListEmpty = drawer.profileListEmpty
|
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
intent?.putExtras(savedInstanceState)
|
intent?.putExtras(savedInstanceState)
|
||||||
savedInstanceState.clear()
|
savedInstanceState.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profileListEmpty) {
|
|
||||||
handleIntent(intent?.extras)
|
|
||||||
}
|
|
||||||
app.db.profileDao().all.observe(this, Observer { profiles ->
|
app.db.profileDao().all.observe(this, Observer { profiles ->
|
||||||
drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList())
|
drawer.setProfileList(profiles.filter { it.id >= 0 }.toMutableList())
|
||||||
if (profileListEmpty) {
|
drawer.currentProfile = App.profileId
|
||||||
profileListEmpty = false
|
|
||||||
handleIntent(intent?.extras)
|
|
||||||
}
|
|
||||||
else if (app.profile != null) {
|
|
||||||
drawer.currentProfile = app.profile.id
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// if null, getAllFull will load a profile and update drawerItems
|
setDrawerItems()
|
||||||
if (app.profile != null)
|
|
||||||
setDrawerItems()
|
handleIntent(intent?.extras)
|
||||||
|
|
||||||
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
|
||||||
unreadCounters.map {
|
unreadCounters.map {
|
||||||
@ -405,6 +411,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
isStoragePermissionGranted()
|
isStoragePermissionGranted()
|
||||||
|
|
||||||
SyncWorker.scheduleNext(app)
|
SyncWorker.scheduleNext(app)
|
||||||
|
UpdateWorker.scheduleNext(app)
|
||||||
|
|
||||||
// APP BACKGROUND
|
// APP BACKGROUND
|
||||||
if (app.config.ui.appBackground != null) {
|
if (app.config.ui.appBackground != null) {
|
||||||
@ -438,6 +445,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// WHAT'S NEW DIALOG
|
// WHAT'S NEW DIALOG
|
||||||
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
if (app.config.appVersion < BuildConfig.VERSION_CODE) {
|
||||||
|
// force an AppSync after update
|
||||||
|
app.config.sync.lastAppSync = 0L
|
||||||
ChangelogDialog(this)
|
ChangelogDialog(this)
|
||||||
if (app.config.appVersion < 170) {
|
if (app.config.appVersion < 170) {
|
||||||
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
//Intent intent = new Intent(this, ChangelogIntroActivity.class);
|
||||||
@ -509,17 +518,25 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var profileListEmptyListener = {
|
|
||||||
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
|
||||||
}
|
|
||||||
private var profileSettingClickListener = { id: Int, view: View? ->
|
private var profileSettingClickListener = { id: Int, view: View? ->
|
||||||
when (id) {
|
when (id) {
|
||||||
DRAWER_PROFILE_ADD_NEW -> {
|
DRAWER_PROFILE_ADD_NEW -> {
|
||||||
profileListEmptyListener()
|
startActivityForResult(Intent(this, LoginActivity::class.java), REQUEST_LOGIN_ACTIVITY)
|
||||||
}
|
}
|
||||||
DRAWER_PROFILE_SYNC_ALL -> {
|
DRAWER_PROFILE_SYNC_ALL -> {
|
||||||
EdziennikTask.sync().enqueue(this)
|
EdziennikTask.sync().enqueue(this)
|
||||||
}
|
}
|
||||||
|
DRAWER_PROFILE_MARK_ALL_AS_READ -> { launch {
|
||||||
|
withContext(Dispatchers.Default) {
|
||||||
|
app.db.profileDao().allNow.forEach { profile ->
|
||||||
|
if (profile.loginStoreType != LoginStore.LOGIN_TYPE_LIBRUS)
|
||||||
|
app.db.metadataDao().setAllSeenExceptMessagesAndAnnouncements(profile.id, true)
|
||||||
|
else
|
||||||
|
app.db.metadataDao().setAllSeenExceptMessages(profile.id, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Toast.makeText(this@MainActivity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||||
|
}}
|
||||||
else -> {
|
else -> {
|
||||||
loadTarget(id)
|
loadTarget(id)
|
||||||
}
|
}
|
||||||
@ -549,7 +566,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
EdziennikTask.syncProfile(
|
EdziennikTask.syncProfile(
|
||||||
App.profileId,
|
App.profileId,
|
||||||
listOf(navTargetId to fragmentParam),
|
listOf(navTargetId to fragmentParam),
|
||||||
arguments
|
arguments = arguments
|
||||||
).enqueue(this)
|
).enqueue(this)
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
@ -564,6 +581,13 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onProfileListEmptyEvent(event: ProfileListEmptyEvent) {
|
||||||
|
d(TAG, "Profile list is empty. Launch LoginActivity.")
|
||||||
|
app.config.loginFinished = false
|
||||||
|
startActivity(Intent(this, LoginActivity::class.java))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
fun onApiTaskProgressEvent(event: ApiTaskProgressEvent) {
|
||||||
if (event.profileId == App.profileId) {
|
if (event.profileId == App.profileId) {
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
@ -579,6 +603,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) {
|
fun onApiTaskFinishedEvent(event: ApiTaskFinishedEvent) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
if (event.profileId == App.profileId) {
|
if (event.profileId == App.profileId) {
|
||||||
navView.toolbar.apply {
|
navView.toolbar.apply {
|
||||||
subtitleFormat = R.string.toolbar_subtitle
|
subtitleFormat = R.string.toolbar_subtitle
|
||||||
@ -589,6 +614,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onApiTaskAllFinishedEvent(event: ApiTaskAllFinishedEvent) {
|
fun onApiTaskAllFinishedEvent(event: ApiTaskAllFinishedEvent) {
|
||||||
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
@ -604,7 +630,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||||
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
fun onAppManagerDetectedEvent(event: AppManagerDetectedEvent) {
|
||||||
if (app.appConfig.dontShowAppManagerDialog)
|
EventBus.getDefault().removeStickyEvent(event)
|
||||||
|
if (app.config.sync.dontShowAppManagerDialog)
|
||||||
return
|
return
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.app_manager_dialog_title)
|
.setTitle(R.string.app_manager_dialog_title)
|
||||||
@ -626,12 +653,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
.setNeutralButton(R.string.dont_ask_again) { dialog, which ->
|
||||||
app.appConfig.dontShowAppManagerDialog = true
|
app.config.sync.dontShowAppManagerDialog = true
|
||||||
app.saveConfig("dontShowAppManagerDialog")
|
|
||||||
}
|
}
|
||||||
.setCancelable(false)
|
.setCancelable(false)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
fun onUserActionRequiredEvent(event: UserActionRequiredEvent) {
|
||||||
|
app.userActionManager.execute(this, event.profileId, event.type)
|
||||||
|
}
|
||||||
|
|
||||||
private fun fragmentToSyncName(currentFragment: Int): Int {
|
private fun fragmentToSyncName(currentFragment: Int): Int {
|
||||||
return when (currentFragment) {
|
return when (currentFragment) {
|
||||||
@ -669,26 +699,64 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
d(TAG, "}")
|
d(TAG, "}")
|
||||||
|
|
||||||
|
var intentProfileId = -1
|
||||||
|
var intentTargetId = -1
|
||||||
|
|
||||||
|
if (extras?.containsKey("action") == true) {
|
||||||
|
val handled = when (extras.getString("action")) {
|
||||||
|
"serverMessage" -> {
|
||||||
|
ServerMessageDialog(
|
||||||
|
this,
|
||||||
|
extras.getString("serverMessageTitle") ?: getString(R.string.app_name),
|
||||||
|
extras.getString("serverMessageText") ?: ""
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
"feedbackMessage" -> {
|
||||||
|
intentTargetId = TARGET_FEEDBACK
|
||||||
|
false
|
||||||
|
}
|
||||||
|
"userActionRequired" -> {
|
||||||
|
app.userActionManager.execute(
|
||||||
|
this,
|
||||||
|
extras.getInt("profileId"),
|
||||||
|
extras.getInt("type")
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
"createManualEvent" -> {
|
||||||
|
val date = extras.getString("eventDate")?.let { Date.fromY_m_d(it) } ?: Date.getToday()
|
||||||
|
EventManualDialog(
|
||||||
|
this,
|
||||||
|
App.profileId,
|
||||||
|
defaultDate = date
|
||||||
|
)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (handled && !navLoading) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (extras?.containsKey("reloadProfileId") == true) {
|
if (extras?.containsKey("reloadProfileId") == true) {
|
||||||
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
val reloadProfileId = extras.getInt("reloadProfileId", -1)
|
||||||
extras.remove("reloadProfileId")
|
extras.remove("reloadProfileId")
|
||||||
if (reloadProfileId == -1 || (app.profile != null && app.profile.id == reloadProfileId)) {
|
if (reloadProfileId == -1 || app.profile.id == reloadProfileId) {
|
||||||
reloadTarget()
|
reloadTarget()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var intentProfileId = -1
|
if (extras?.getInt("profileId", -1) != -1) {
|
||||||
var intentTargetId = -1
|
|
||||||
|
|
||||||
if (extras?.containsKey("profileId") == true) {
|
|
||||||
intentProfileId = extras.getInt("profileId", -1)
|
intentProfileId = extras.getInt("profileId", -1)
|
||||||
extras.remove("profileId")
|
extras?.remove("profileId")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extras?.containsKey("fragmentId") == true) {
|
if (extras?.getInt("fragmentId", -1) != -1) {
|
||||||
intentTargetId = extras.getInt("fragmentId", -1)
|
intentTargetId = extras.getInt("fragmentId", -1)
|
||||||
extras.remove("fragmentId")
|
extras?.remove("fragmentId")
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (intentTargetId == -1 && navController.currentDestination?.id == R.id.loadingFragment) {
|
/*if (intentTargetId == -1 && navController.currentDestination?.id == R.id.loadingFragment) {
|
||||||
@ -702,9 +770,9 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
app.profile == null || app.profile.id == -1 -> {
|
app.profile.id == 0 -> {
|
||||||
if (intentProfileId == -1)
|
if (intentProfileId == -1)
|
||||||
intentProfileId = app.appSharedPrefs.getInt("current_profile_id", 1)
|
intentProfileId = app.config.lastProfileId
|
||||||
loadProfile(intentProfileId, intentTargetId, extras)
|
loadProfile(intentProfileId, intentTargetId, extras)
|
||||||
}
|
}
|
||||||
intentProfileId != -1 -> {
|
intentProfileId != -1 -> {
|
||||||
@ -743,7 +811,16 @@ class MainActivity : AppCompatActivity() {
|
|||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
d(TAG, "Activity started")
|
||||||
|
super.onStart()
|
||||||
|
}
|
||||||
|
override fun onStop() {
|
||||||
|
d(TAG, "Activity stopped")
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
d(TAG, "Activity resumed")
|
||||||
val filter = IntentFilter()
|
val filter = IntentFilter()
|
||||||
filter.addAction(Intent.ACTION_MAIN)
|
filter.addAction(Intent.ACTION_MAIN)
|
||||||
registerReceiver(intentReceiver, filter)
|
registerReceiver(intentReceiver, filter)
|
||||||
@ -751,10 +828,15 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
}
|
}
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
|
d(TAG, "Activity paused")
|
||||||
unregisterReceiver(intentReceiver)
|
unregisterReceiver(intentReceiver)
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
override fun onDestroy() {
|
||||||
|
d(TAG, "Activity destroyed")
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
@ -768,15 +850,10 @@ class MainActivity : AppCompatActivity() {
|
|||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
if (requestCode == REQUEST_LOGIN_ACTIVITY) {
|
||||||
if (resultCode == Activity.RESULT_CANCELED && false) {
|
if (!app.config.loginFinished)
|
||||||
finish()
|
finish()
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if (!app.config.loginFinished)
|
handleIntent(data?.extras)
|
||||||
finish()
|
|
||||||
else {
|
|
||||||
handleIntent(data?.extras)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -797,34 +874,23 @@ class MainActivity : AppCompatActivity() {
|
|||||||
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
fun loadProfile(id: Int) = loadProfile(id, navTargetId)
|
||||||
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
fun loadProfile(id: Int, arguments: Bundle?) = loadProfile(id, navTargetId, arguments)
|
||||||
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
fun loadProfile(id: Int, drawerSelection: Int, arguments: Bundle? = null) {
|
||||||
//d("NavDebug", "loadProfile(id = $id, drawerSelection = $drawerSelection)")
|
if (App.profileId == id) {
|
||||||
if (app.profile != null && App.profileId == id) {
|
|
||||||
drawer.currentProfile = app.profile.id
|
drawer.currentProfile = app.profile.id
|
||||||
loadTarget(drawerSelection, arguments)
|
loadTarget(drawerSelection, arguments)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
AsyncTask.execute {
|
app.profileLoad(id) {
|
||||||
app.profileLoadById(id)
|
|
||||||
MessagesFragment.pageSelection = -1
|
MessagesFragment.pageSelection = -1
|
||||||
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.tapPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.topPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
MessagesListFragment.bottomPositions = intArrayOf(RecyclerView.NO_POSITION, RecyclerView.NO_POSITION)
|
||||||
|
|
||||||
this.runOnUiThread {
|
setDrawerItems()
|
||||||
if (app.profile == null) {
|
// the drawer profile is updated automatically when the drawer item is clicked
|
||||||
if (app.config.loginFinished) {
|
// update it manually when switching profiles from other source
|
||||||
// this shouldn't run
|
//if (drawer.currentProfile != app.profile.id)
|
||||||
profileListEmptyListener()
|
drawer.currentProfile = app.profileId
|
||||||
}
|
loadTarget(drawerSelection, arguments)
|
||||||
} else {
|
|
||||||
setDrawerItems()
|
|
||||||
// the drawer profile is updated automatically when the drawer item is clicked
|
|
||||||
// update it manually when switching profiles from other source
|
|
||||||
//if (drawer.currentProfile != app.profile.id)
|
|
||||||
drawer.currentProfile = app.profile.id
|
|
||||||
loadTarget(drawerSelection, arguments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
fun loadTarget(id: Int, arguments: Bundle? = null) {
|
||||||
@ -848,7 +914,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
bottomSheet.close()
|
bottomSheet.close()
|
||||||
bottomSheet.removeAllContextual()
|
bottomSheet.removeAllContextual()
|
||||||
bottomSheet.toggleGroupEnabled = false
|
bottomSheet.toggleGroupEnabled = false
|
||||||
bottomSheet.onCloseListener = null
|
|
||||||
drawer.close()
|
drawer.close()
|
||||||
drawer.setSelection(target.id, fireOnClick = false)
|
drawer.setSelection(target.id, fireOnClick = false)
|
||||||
navView.toolbar.setTitle(target.title ?: target.name)
|
navView.toolbar.setTitle(target.title ?: target.name)
|
||||||
@ -969,7 +1034,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
* that something has changed in the bottom sheet.
|
* that something has changed in the bottom sheet.
|
||||||
*/
|
*/
|
||||||
fun gainAttention() {
|
fun gainAttention() {
|
||||||
if (app.config.ui.bottomSheetOpened || true)
|
if (app.config.ui.bottomSheetOpened)
|
||||||
return
|
return
|
||||||
b.navView.postDelayed({
|
b.navView.postDelayed({
|
||||||
navView.gainAttentionOnBottomBar()
|
navView.gainAttentionOnBottomBar()
|
||||||
@ -1018,12 +1083,11 @@ class MainActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDrawerItems() {
|
fun setDrawerItems() {
|
||||||
d("NavDebug", "setDrawerItems() app.profile = ${app.profile ?: "null"}")
|
d("NavDebug", "setDrawerItems() app.profile = ${app.profile}")
|
||||||
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
val drawerItems = arrayListOf<IDrawerItem<*>>()
|
||||||
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
val drawerProfiles = arrayListOf<ProfileSettingDrawerItem>()
|
||||||
|
|
||||||
val supportedFragments = if (app.profile == null) arrayListOf<Int>()
|
val supportedFragments = app.profile.supportedFragments
|
||||||
else app.profile.supportedFragments
|
|
||||||
|
|
||||||
targetPopToHomeList.clear()
|
targetPopToHomeList.clear()
|
||||||
|
|
||||||
@ -1087,7 +1151,8 @@ class MainActivity : AppCompatActivity() {
|
|||||||
private var targetHomeId: Int = -1
|
private var targetHomeId: Int = -1
|
||||||
override fun onBackPressed() {
|
override fun onBackPressed() {
|
||||||
if (!b.navView.onBackPressed()) {
|
if (!b.navView.onBackPressed()) {
|
||||||
if (App.getConfig().ui.openDrawerOnBackPressed) {
|
if (App.config.ui.openDrawerOnBackPressed && ((navTarget.popTo == null && navTarget.popToHome)
|
||||||
|
|| navTarget.id == DRAWER_ITEM_HOME)) {
|
||||||
b.navView.drawer.toggle()
|
b.navView.drawer.toggle()
|
||||||
} else {
|
} else {
|
||||||
navigateUp()
|
navigateUp()
|
||||||
|
@ -1,350 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik;
|
|
||||||
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.NotificationChannel;
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import androidx.core.app.NotificationCompat;
|
|
||||||
import androidx.core.content.ContextCompat;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.receivers.BootReceiver;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time;
|
|
||||||
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_DEFAULT;
|
|
||||||
import static androidx.core.app.NotificationCompat.PRIORITY_MAX;
|
|
||||||
|
|
||||||
public class Notifier {
|
|
||||||
|
|
||||||
private static final String TAG = "Notifier";
|
|
||||||
public static final int ID_GET_DATA = 1337000;
|
|
||||||
public static final int ID_GET_DATA_ERROR = 1337001;
|
|
||||||
private static String CHANNEL_GET_DATA_NAME;
|
|
||||||
private static String CHANNEL_GET_DATA_DESC;
|
|
||||||
private static final String GROUP_KEY_GET_DATA = "pl.szczodrzynski.edziennik.GET_DATA";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS = "pl.szczodrzynski.edziennik.NOTIFICATIONS";
|
|
||||||
|
|
||||||
public static final int ID_NOTIFICATIONS_QUIET = 1337002;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_NAME;
|
|
||||||
public static String CHANNEL_NOTIFICATIONS_QUIET_DESC;
|
|
||||||
public static final String GROUP_KEY_NOTIFICATIONS_QUIET = "pl.szczodrzynski.edziennik.NOTIFICATIONS_QUIET";
|
|
||||||
|
|
||||||
private static final int ID_UPDATES = 1337003;
|
|
||||||
private static String CHANNEL_UPDATES_NAME;
|
|
||||||
private static String CHANNEL_UPDATES_DESC;
|
|
||||||
private static final String GROUP_KEY_UPDATES = "pl.szczodrzynski.edziennik.UPDATES";
|
|
||||||
|
|
||||||
private App app;
|
|
||||||
public NotificationManager notificationManager;
|
|
||||||
private NotificationCompat.Builder getDataNotificationBuilder;
|
|
||||||
public int notificationColor;
|
|
||||||
|
|
||||||
Notifier(App _app) {
|
|
||||||
this.app = _app;
|
|
||||||
|
|
||||||
CHANNEL_GET_DATA_NAME = app.getString(R.string.notification_channel_get_data_name);
|
|
||||||
CHANNEL_GET_DATA_DESC = app.getString(R.string.notification_channel_get_data_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_NAME = app.getString(R.string.notification_channel_notifications_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_DESC = app.getString(R.string.notification_channel_notifications_desc);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_NAME = app.getString(R.string.notification_channel_notifications_quiet_name);
|
|
||||||
CHANNEL_NOTIFICATIONS_QUIET_DESC = app.getString(R.string.notification_channel_notifications_quiet_desc);
|
|
||||||
CHANNEL_UPDATES_NAME = app.getString(R.string.notification_channel_updates_name);
|
|
||||||
CHANNEL_UPDATES_DESC = app.getString(R.string.notification_channel_updates_desc);
|
|
||||||
|
|
||||||
notificationColor = ContextCompat.getColor(app.getContext(), R.color.colorPrimary);
|
|
||||||
notificationManager = (NotificationManager) app.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
NotificationChannel channelGetData = new NotificationChannel(GROUP_KEY_GET_DATA, CHANNEL_GET_DATA_NAME, NotificationManager.IMPORTANCE_MIN);
|
|
||||||
channelGetData.setDescription(CHANNEL_GET_DATA_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelGetData);
|
|
||||||
|
|
||||||
NotificationChannel channelNotifications = new NotificationChannel(GROUP_KEY_NOTIFICATIONS, CHANNEL_NOTIFICATIONS_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelNotifications.setDescription(CHANNEL_NOTIFICATIONS_DESC);
|
|
||||||
channelNotifications.enableLights(true);
|
|
||||||
channelNotifications.setLightColor(notificationColor);
|
|
||||||
notificationManager.createNotificationChannel(channelNotifications);
|
|
||||||
|
|
||||||
NotificationChannel channelNotificationsQuiet = new NotificationChannel(GROUP_KEY_NOTIFICATIONS_QUIET, CHANNEL_NOTIFICATIONS_QUIET_NAME, NotificationManager.IMPORTANCE_DEFAULT);
|
|
||||||
channelNotificationsQuiet.setDescription(CHANNEL_NOTIFICATIONS_QUIET_DESC);
|
|
||||||
channelNotificationsQuiet.setSound(null, null);
|
|
||||||
channelNotificationsQuiet.enableVibration(false);
|
|
||||||
notificationManager.createNotificationChannel(channelNotificationsQuiet);
|
|
||||||
|
|
||||||
NotificationChannel channelUpdates = new NotificationChannel(GROUP_KEY_UPDATES, CHANNEL_UPDATES_NAME, NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
channelUpdates.setDescription(CHANNEL_UPDATES_DESC);
|
|
||||||
notificationManager.createNotificationChannel(channelUpdates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldBeQuiet() {
|
|
||||||
long now = Time.getNow().getInMillis();
|
|
||||||
long start = app.config.getSync().getQuietHoursStart();
|
|
||||||
long end = app.config.getSync().getQuietHoursEnd();
|
|
||||||
if (start > end) {
|
|
||||||
end += 1000 * 60 * 60 * 24;
|
|
||||||
//Log.d(TAG, "Night passing");
|
|
||||||
}
|
|
||||||
if (start > now) {
|
|
||||||
now += 1000 * 60 * 60 * 24;
|
|
||||||
//Log.d(TAG, "Now is smaller");
|
|
||||||
}
|
|
||||||
//Log.d(TAG, "Start is "+start+", now is "+now+", end is "+end);
|
|
||||||
return start > 0 && now >= start && now <= end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getNotificationDefaults() {
|
|
||||||
return (shouldBeQuiet() ? 0 : Notification.DEFAULT_ALL);
|
|
||||||
}
|
|
||||||
public String getNotificationGroup() {
|
|
||||||
return shouldBeQuiet() ? GROUP_KEY_NOTIFICATIONS_QUIET : GROUP_KEY_NOTIFICATIONS;
|
|
||||||
}
|
|
||||||
public int getNotificationPriority() {
|
|
||||||
return shouldBeQuiet() ? PRIORITY_DEFAULT : PRIORITY_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _____ _ _____ _
|
|
||||||
| __ \ | | / ____| | |
|
|
||||||
| | | | __ _| |_ __ _ | | __ ___| |_
|
|
||||||
| | | |/ _` | __/ _` | | | |_ |/ _ \ __|
|
|
||||||
| |__| | (_| | || (_| | | |__| | __/ |_
|
|
||||||
|_____/ \__,_|\__\__,_| \_____|\___|\_*/
|
|
||||||
public Notification notificationGetDataShow(int maxProgress) {
|
|
||||||
/*Intent notificationIntent = new Intent(app.getContext(), SyncService.class);
|
|
||||||
notificationIntent.setAction(ACTION_CANCEL);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_GET_DATA)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_get_data_text))
|
|
||||||
//.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_cancel), pendingIntent)
|
|
||||||
//.setGroup(GROUP_KEY_GET_DATA)
|
|
||||||
.setOngoing(true)
|
|
||||||
.setProgress(maxProgress, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_summary))
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_LOW);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProgress(int progress, int maxProgress) {
|
|
||||||
getDataNotificationBuilder.setProgress(maxProgress, progress, false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataAction(int stringResId) {
|
|
||||||
getDataNotificationBuilder.setContentTitle(app.getString(R.string.sync_action_format, app.getString(stringResId)));
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataProfile(String profileName) {
|
|
||||||
getDataNotificationBuilder.setContentText(profileName);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Notification notificationGetDataError(String profileName, String error, int failedProfileId) {
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), Notifier.GetDataRetryService.class);
|
|
||||||
notificationIntent.putExtra("failedProfileId", failedProfileId);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
getDataNotificationBuilder.mActions.clear();
|
|
||||||
/*try {
|
|
||||||
//Use reflection clean up old actions
|
|
||||||
Field f = getDataNotificationBuilder.getClass().getDeclaredField("mActions");
|
|
||||||
f.setAccessible(true);
|
|
||||||
f.set(getDataNotificationBuilder, new ArrayList<NotificationCompat.Action>());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
getDataNotificationBuilder.setProgress(0, 0, false)
|
|
||||||
.setTicker(app.getString(R.string.notification_get_data_error_summary))
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_warning)
|
|
||||||
.addAction(R.drawable.ic_notification, app.getString(R.string.notification_get_data_once_again), pendingIntent)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_get_data_error_title, profileName))
|
|
||||||
.setContentText(error)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(error))
|
|
||||||
.setOngoing(false);
|
|
||||||
return getDataNotificationBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationPost(int id, Notification notification) {
|
|
||||||
notificationManager.notify(id, notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationCancel(int id) {
|
|
||||||
notificationManager.cancel(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//public void notificationGetDataHide() {
|
|
||||||
// notificationManager.cancel(ID_GET_DATA);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static class GetDataRetryService extends IntentService {
|
|
||||||
private static final String TAG = "Notifier/GetDataRetry";
|
|
||||||
|
|
||||||
public GetDataRetryService() {
|
|
||||||
super(Notifier.GetDataRetryService.class.getSimpleName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(Intent intent) {
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _ __ _ _ _
|
|
||||||
| \ | | | | (_)/ _(_) | | (_)
|
|
||||||
| \| | ___ | |_ _| |_ _ ___ __ _| |_ _ ___ _ __
|
|
||||||
| . ` |/ _ \| __| | _| |/ __/ _` | __| |/ _ \| '_ \
|
|
||||||
| |\ | (_) | |_| | | | | (_| (_| | |_| | (_) | | | |
|
|
||||||
|_| \_|\___/ \__|_|_| |_|\___\__,_|\__|_|\___/|_| |*/
|
|
||||||
public void add(pl.szczodrzynski.edziennik.utils.models.Notification notification) {
|
|
||||||
app.appConfig.notifications.add(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postAll() {
|
|
||||||
Collections.sort(app.appConfig.notifications, (o1, o2) -> (o2.addedDate - o1.addedDate > 0) ? 1 : (o2.addedDate - o1.addedDate < 0) ? -1 : 0);
|
|
||||||
|
|
||||||
if (app.appConfig.notifications.size() > 40) {
|
|
||||||
app.appConfig.notifications.subList(40, app.appConfig.notifications.size() - 1).clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int unreadCount = 0;
|
|
||||||
List<pl.szczodrzynski.edziennik.utils.models.Notification> notificationList = new ArrayList<>();
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
if (!notification.notified) {
|
|
||||||
notification.seen = false;
|
|
||||||
notification.notified = true;
|
|
||||||
unreadCount++;
|
|
||||||
if (notificationList.size() < 10) {
|
|
||||||
notificationList.add(notification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
notification.seen = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: notificationList) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
notification.fillIntent(intent);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, notification.id, intent, 0);
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
// title, text, type, date
|
|
||||||
.setContentTitle(notification.title)
|
|
||||||
.setContentText(notification.text)
|
|
||||||
.setSubText(pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type))
|
|
||||||
.setWhen(notification.addedDate)
|
|
||||||
.setTicker(app.getString(R.string.notification_ticker_format, pl.szczodrzynski.edziennik.utils.models.Notification.stringType(app, notification.type)))
|
|
||||||
// icon, color, lights, priority
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
// channel, group, style
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_SUMMARY)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(notification.text))
|
|
||||||
// intent, auto cancel
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(notification.id, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notificationList.size() > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
|
||||||
Intent intent = new Intent(app, MainActivity.class);
|
|
||||||
intent.setAction("android.intent.action.MAIN");
|
|
||||||
intent.putExtra("fragmentId", MainActivity.DRAWER_ITEM_NOTIFICATIONS);
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(app, ID_NOTIFICATIONS,
|
|
||||||
intent, 0);
|
|
||||||
|
|
||||||
NotificationCompat.Builder groupBuilder =
|
|
||||||
new NotificationCompat.Builder(app, getNotificationGroup())
|
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_new_notification_title_format, unreadCount))
|
|
||||||
.setGroupSummary(true)
|
|
||||||
.setAutoCancel(true)
|
|
||||||
.setChannelId(getNotificationGroup())
|
|
||||||
.setGroup(getNotificationGroup())
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setPriority(getNotificationPriority())
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle());
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
groupBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_NOTIFICATIONS, groupBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* _ _ _ _
|
|
||||||
| | | | | | | |
|
|
||||||
| | | |_ __ __| | __ _| |_ ___ ___
|
|
||||||
| | | | '_ \ / _` |/ _` | __/ _ \/ __|
|
|
||||||
| |__| | |_) | (_| | (_| | || __/\__ \
|
|
||||||
\____/| .__/ \__,_|\__,_|\__\___||___/
|
|
||||||
| |
|
|
||||||
|*/
|
|
||||||
public void notificationUpdatesShow(String updateVersion, String updateUrl, String updateFilename, boolean updateDirect) {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
Intent notificationIntent = new Intent(app.getContext(), BootReceiver.NotificationActionService.class)
|
|
||||||
.putExtra("update_version", updateVersion)
|
|
||||||
.putExtra("update_url", updateUrl)
|
|
||||||
.putExtra("update_filename", updateFilename)
|
|
||||||
.putExtra("update_direct", updateDirect);
|
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getService(app.getContext(), 0,
|
|
||||||
notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
|
|
||||||
|
|
||||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(app, GROUP_KEY_UPDATES)
|
|
||||||
.setSmallIcon(android.R.drawable.stat_sys_download_done)
|
|
||||||
.setColor(notificationColor)
|
|
||||||
.setContentTitle(app.getString(R.string.notification_updates_title))
|
|
||||||
.setContentText(app.getString(R.string.notification_updates_text, updateVersion))
|
|
||||||
.setLights(0xFF00FFFF, 2000, 2000)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setTicker(app.getString(R.string.notification_updates_summary))
|
|
||||||
.setPriority(PRIORITY_MAX)
|
|
||||||
.setAutoCancel(true);
|
|
||||||
if (!shouldBeQuiet()) {
|
|
||||||
notificationBuilder.setDefaults(getNotificationDefaults());
|
|
||||||
}
|
|
||||||
notificationManager.notify(ID_UPDATES, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void notificationUpdatesHide() {
|
|
||||||
if (!app.config.getSync().getNotifyAboutUpdates())
|
|
||||||
return;
|
|
||||||
notificationManager.cancel(ID_UPDATES);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void dump() {
|
|
||||||
for (pl.szczodrzynski.edziennik.utils.models.Notification notification: app.appConfig.notifications) {
|
|
||||||
Log.d(TAG, "Profile"+notification.profileId+" Notification from "+ Date.fromMillis(notification.addedDate).getFormattedString()+" "+ Time.fromMillis(notification.addedDate).getStringHMS()+" - "+notification.text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,12 +16,13 @@ import pl.szczodrzynski.edziennik.config.utils.ConfigMigration
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||||
import pl.szczodrzynski.edziennik.data.db.AppDb
|
import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
||||||
companion object {
|
companion object {
|
||||||
const val DATA_VERSION = 2
|
const val DATA_VERSION = 11
|
||||||
}
|
}
|
||||||
|
|
||||||
private val job = Job()
|
private val job = Job()
|
||||||
@ -45,6 +46,20 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
get() { mHash = mHash ?: values.get("hash", ""); return mHash ?: "" }
|
||||||
set(value) { set("hash", value); mHash = value }
|
set(value) { set("hash", value); mHash = value }
|
||||||
|
|
||||||
|
private var mLastProfileId: Int? = null
|
||||||
|
var lastProfileId: Int
|
||||||
|
get() { mLastProfileId = mLastProfileId ?: values.get("lastProfileId", 0); return mLastProfileId ?: 0 }
|
||||||
|
set(value) { set("lastProfileId", value); mLastProfileId = value }
|
||||||
|
|
||||||
|
private var mUpdatesChannel: String? = null
|
||||||
|
var updatesChannel: String
|
||||||
|
get() { mUpdatesChannel = mUpdatesChannel ?: values.get("updatesChannel", "release"); return mUpdatesChannel ?: "release" }
|
||||||
|
set(value) { set("updatesChannel", value); mUpdatesChannel = value }
|
||||||
|
private var mUpdate: Update? = null
|
||||||
|
var update: Update?
|
||||||
|
get() { mUpdate = mUpdate ?: values.get("update", null as Update?); return mUpdate ?: null as Update? }
|
||||||
|
set(value) { set("update", value); mUpdate = value }
|
||||||
|
|
||||||
private var mAppVersion: Int? = null
|
private var mAppVersion: Int? = null
|
||||||
var appVersion: Int
|
var appVersion: Int
|
||||||
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
get() { mAppVersion = mAppVersion ?: values.get("appVersion", BuildConfig.VERSION_CODE); return mAppVersion ?: BuildConfig.VERSION_CODE }
|
||||||
@ -60,6 +75,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
get() { mPrivacyPolicyAccepted = mPrivacyPolicyAccepted ?: values.get("privacyPolicyAccepted", false); return mPrivacyPolicyAccepted ?: false }
|
get() { mPrivacyPolicyAccepted = mPrivacyPolicyAccepted ?: values.get("privacyPolicyAccepted", false); return mPrivacyPolicyAccepted ?: false }
|
||||||
set(value) { set("privacyPolicyAccepted", value); mPrivacyPolicyAccepted = value }
|
set(value) { set("privacyPolicyAccepted", value); mPrivacyPolicyAccepted = value }
|
||||||
|
|
||||||
|
private var mDebugMode: Boolean? = null
|
||||||
|
var debugMode: Boolean
|
||||||
|
get() { mDebugMode = mDebugMode ?: values.get("debugMode", false); return mDebugMode ?: false }
|
||||||
|
set(value) { set("debugMode", value); mDebugMode = value }
|
||||||
|
|
||||||
private var mDevModePassword: String? = null
|
private var mDevModePassword: String? = null
|
||||||
var devModePassword: String?
|
var devModePassword: String?
|
||||||
get() { mDevModePassword = mDevModePassword ?: values.get("devModePassword", null as String?); return mDevModePassword }
|
get() { mDevModePassword = mDevModePassword ?: values.get("devModePassword", null as String?); return mDevModePassword }
|
||||||
@ -110,4 +130,4 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
|
|||||||
db.configDao().add(ConfigEntry(-1, key, value))
|
db.configDao().add(ConfigEntry(-1, key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,11 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager
|
||||||
|
|
||||||
class ConfigGrades(private val config: Config) {
|
class ConfigGrades(private val config: Config) {
|
||||||
companion object {
|
|
||||||
const val ORDER_BY_DATE_DESC = 0
|
|
||||||
const val ORDER_BY_SUBJECT_ASC = 1
|
|
||||||
const val ORDER_BY_DATE_ASC = 2
|
|
||||||
const val ORDER_BY_SUBJECT_DESC = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
private var mOrderBy: Int? = null
|
private var mOrderBy: Int? = null
|
||||||
var orderBy: Int
|
var orderBy: Int
|
||||||
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: 0 }
|
get() { mOrderBy = mOrderBy ?: config.values.get("gradesOrderBy", 0); return mOrderBy ?: GradesManager.ORDER_BY_DATE_DESC }
|
||||||
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
set(value) { config.set("gradesOrderBy", value); mOrderBy = value }
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,24 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class ConfigSync(private val config: Config) {
|
class ConfigSync(private val config: Config) {
|
||||||
|
private var mDontShowAppManagerDialog: Boolean? = null
|
||||||
|
var dontShowAppManagerDialog: Boolean
|
||||||
|
get() { mDontShowAppManagerDialog = mDontShowAppManagerDialog ?: config.values.get("dontShowAppManagerDialog", false); return mDontShowAppManagerDialog ?: false }
|
||||||
|
set(value) { config.set("dontShowAppManagerDialog", value); mDontShowAppManagerDialog = value }
|
||||||
|
|
||||||
private var mSyncEnabled: Boolean? = null
|
private var mSyncEnabled: Boolean? = null
|
||||||
var enabled: Boolean
|
var enabled: Boolean
|
||||||
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
get() { mSyncEnabled = mSyncEnabled ?: config.values.get("syncEnabled", true); return mSyncEnabled ?: true }
|
||||||
set(value) { config.set("syncEnabled", value); mSyncEnabled = value }
|
set(value) { config.set("syncEnabled", value); mSyncEnabled = value }
|
||||||
|
|
||||||
|
private var mWebPushEnabled: Boolean? = null
|
||||||
|
var webPushEnabled: Boolean
|
||||||
|
get() { mWebPushEnabled = mWebPushEnabled ?: config.values.get("webPushEnabled", true); return mWebPushEnabled ?: true }
|
||||||
|
set(value) { config.set("webPushEnabled", value); mWebPushEnabled = value }
|
||||||
|
|
||||||
private var mSyncOnlyWifi: Boolean? = null
|
private var mSyncOnlyWifi: Boolean? = null
|
||||||
var onlyWifi: Boolean
|
var onlyWifi: Boolean
|
||||||
get() { mSyncOnlyWifi = mSyncOnlyWifi ?: config.values.get("syncOnlyWifi", false); return mSyncOnlyWifi ?: notifyAboutUpdates }
|
get() { mSyncOnlyWifi = mSyncOnlyWifi ?: config.values.get("syncOnlyWifi", false); return mSyncOnlyWifi ?: notifyAboutUpdates }
|
||||||
@ -29,20 +40,30 @@ class ConfigSync(private val config: Config) {
|
|||||||
get() { mNotifyAboutUpdates = mNotifyAboutUpdates ?: config.values.get("notifyAboutUpdates", true); return mNotifyAboutUpdates ?: true }
|
get() { mNotifyAboutUpdates = mNotifyAboutUpdates ?: config.values.get("notifyAboutUpdates", true); return mNotifyAboutUpdates ?: true }
|
||||||
set(value) { config.set("notifyAboutUpdates", value); mNotifyAboutUpdates = value }
|
set(value) { config.set("notifyAboutUpdates", value); mNotifyAboutUpdates = value }
|
||||||
|
|
||||||
|
private var mLastAppSync: Long? = null
|
||||||
|
var lastAppSync: Long
|
||||||
|
get() { mLastAppSync = mLastAppSync ?: config.values.get("lastAppSync", 0L); return mLastAppSync ?: 0L }
|
||||||
|
set(value) { config.set("lastAppSync", value); mLastAppSync = value }
|
||||||
|
|
||||||
/* ____ _ _ _
|
/* ____ _ _ _
|
||||||
/ __ \ (_) | | | |
|
/ __ \ (_) | | | |
|
||||||
| | | |_ _ _ ___| |_ | |__ ___ _ _ _ __ ___
|
| | | |_ _ _ ___| |_ | |__ ___ _ _ _ __ ___
|
||||||
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
|
| | | | | | | |/ _ \ __| | '_ \ / _ \| | | | '__/ __|
|
||||||
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
|
| |__| | |_| | | __/ |_ | | | | (_) | |_| | | \__ \
|
||||||
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
|
\___\_\\__,_|_|\___|\__| |_| |_|\___/ \__,_|_| |__*/
|
||||||
private var mQuietHoursStart: Long? = null
|
private var mQuietHoursEnabled: Boolean? = null
|
||||||
var quietHoursStart: Long
|
var quietHoursEnabled: Boolean
|
||||||
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", 0L); return mQuietHoursStart ?: 0L }
|
get() { mQuietHoursEnabled = mQuietHoursEnabled ?: config.values.get("quietHoursEnabled", false); return mQuietHoursEnabled ?: false }
|
||||||
|
set(value) { config.set("quietHoursEnabled", value); mQuietHoursEnabled = value }
|
||||||
|
|
||||||
|
private var mQuietHoursStart: Time? = null
|
||||||
|
var quietHoursStart: Time?
|
||||||
|
get() { mQuietHoursStart = mQuietHoursStart ?: config.values.get("quietHoursStart", null as Time?); return mQuietHoursStart }
|
||||||
set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value }
|
set(value) { config.set("quietHoursStart", value); mQuietHoursStart = value }
|
||||||
|
|
||||||
private var mQuietHoursEnd: Long? = null
|
private var mQuietHoursEnd: Time? = null
|
||||||
var quietHoursEnd: Long
|
var quietHoursEnd: Time?
|
||||||
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", 0L); return mQuietHoursEnd ?: 0L }
|
get() { mQuietHoursEnd = mQuietHoursEnd ?: config.values.get("quietHoursEnd", null as Time?); return mQuietHoursEnd }
|
||||||
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
|
set(value) { config.set("quietHoursEnd", value); mQuietHoursEnd = value }
|
||||||
|
|
||||||
private var mQuietDuringLessons: Boolean? = null
|
private var mQuietDuringLessons: Boolean? = null
|
||||||
@ -85,4 +106,4 @@ class ConfigSync(private val config: Config) {
|
|||||||
var tokenVulcanList: List<Int>
|
var tokenVulcanList: List<Int>
|
||||||
get() { mTokenVulcanList = mTokenVulcanList ?: config.values.getIntList("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() }
|
get() { mTokenVulcanList = mTokenVulcanList ?: config.values.getIntList("tokenVulcanList", listOf()); return mTokenVulcanList ?: listOf() }
|
||||||
set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value }
|
set(value) { config.set("tokenVulcanList", value); mTokenVulcanList = value }
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel
|
|
||||||
|
|
||||||
class ConfigUI(private val config: Config) {
|
class ConfigUI(private val config: Config) {
|
||||||
private var mTheme: Int? = null
|
private var mTheme: Int? = null
|
||||||
@ -45,16 +44,6 @@ class ConfigUI(private val config: Config) {
|
|||||||
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
get() { mOpenDrawerOnBackPressed = mOpenDrawerOnBackPressed ?: config.values.get("openDrawerOnBackPressed", false); return mOpenDrawerOnBackPressed ?: false }
|
||||||
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
set(value) { config.set("openDrawerOnBackPressed", value); mOpenDrawerOnBackPressed = value }
|
||||||
|
|
||||||
private var mAgendaViewType: Int? = null
|
|
||||||
var agendaViewType: Int
|
|
||||||
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: 0 }
|
|
||||||
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
|
||||||
|
|
||||||
private var mHomeCards: List<HomeCardModel>? = null
|
|
||||||
var homeCards: List<HomeCardModel>
|
|
||||||
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
|
||||||
set(value) { config.set("homeCards", value); mHomeCards = value }
|
|
||||||
|
|
||||||
private var mSnowfall: Boolean? = null
|
private var mSnowfall: Boolean? = null
|
||||||
var snowfall: Boolean
|
var snowfall: Boolean
|
||||||
get() { mSnowfall = mSnowfall ?: config.values.get("snowfall", false); return mSnowfall ?: false }
|
get() { mSnowfall = mSnowfall ?: config.values.get("snowfall", false); return mSnowfall ?: false }
|
||||||
|
@ -9,6 +9,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
import pl.szczodrzynski.edziennik.config.db.ConfigEntry
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.ProfileConfigMigration
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
import pl.szczodrzynski.edziennik.config.utils.toHashMap
|
||||||
@ -27,8 +28,9 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
val values: HashMap<String, String?> = hashMapOf()
|
val values: HashMap<String, String?> = hashMapOf()
|
||||||
|
|
||||||
val grades by lazy { ProfileConfigGrades(this) }
|
val grades by lazy { ProfileConfigGrades(this) }
|
||||||
|
val ui by lazy { ProfileConfigUI(this) }
|
||||||
|
val sync by lazy { ProfileConfigSync(this) }
|
||||||
/*
|
/*
|
||||||
val sync by lazy { ConfigSync(this) }
|
|
||||||
val timetable by lazy { ConfigTimetable(this) }
|
val timetable by lazy { ConfigTimetable(this) }
|
||||||
val grades by lazy { ConfigGrades(this) }*/
|
val grades by lazy { ConfigGrades(this) }*/
|
||||||
|
|
||||||
@ -44,8 +46,8 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
rawEntries.toHashMap(profileId, values)
|
rawEntries.toHashMap(profileId, values)
|
||||||
/*if (dataVersion < DATA_VERSION)
|
if (dataVersion < DATA_VERSION)
|
||||||
ProfileConfigMigration(this)*/
|
ProfileConfigMigration(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(key: String, value: String?) {
|
override fun set(key: String, value: String?) {
|
||||||
@ -54,4 +56,4 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
|
|||||||
db.configDao().add(ConfigEntry(profileId, key, value))
|
db.configDao().add(ConfigEntry(profileId, key, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,10 @@
|
|||||||
package pl.szczodrzynski.edziennik.config
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.getFloat
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.COLOR_MODE_WEIGHTED
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.YEAR_ALL_GRADES
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
|
|
||||||
class ProfileConfigGrades(private val config: ProfileConfig) {
|
class ProfileConfigGrades(private val config: ProfileConfig) {
|
||||||
private var mColorMode: Int? = null
|
private var mColorMode: Int? = null
|
||||||
@ -20,8 +21,32 @@ class ProfileConfigGrades(private val config: ProfileConfig) {
|
|||||||
get() { mYearAverageMode = mYearAverageMode ?: config.values.get("yearAverageMode", YEAR_ALL_GRADES); return mYearAverageMode ?: YEAR_ALL_GRADES }
|
get() { mYearAverageMode = mYearAverageMode ?: config.values.get("yearAverageMode", YEAR_ALL_GRADES); return mYearAverageMode ?: YEAR_ALL_GRADES }
|
||||||
set(value) { config.set("yearAverageMode", value); mYearAverageMode = value }
|
set(value) { config.set("yearAverageMode", value); mYearAverageMode = value }
|
||||||
|
|
||||||
private var mCountZeroToAvg: Boolean? = null
|
private var mHideImproved: Boolean? = null
|
||||||
var countZeroToAvg: Boolean
|
var hideImproved: Boolean
|
||||||
get() { mCountZeroToAvg = mCountZeroToAvg ?: config.values.get("countZeroToAvg", true); return mCountZeroToAvg ?: true }
|
get() { mHideImproved = mHideImproved ?: config.values.get("hideImproved", false); return mHideImproved ?: false }
|
||||||
set(value) { config.set("countZeroToAvg", value); mCountZeroToAvg = value }
|
set(value) { config.set("hideImproved", value); mHideImproved = value }
|
||||||
|
|
||||||
|
private var mAverageWithoutWeight: Boolean? = null
|
||||||
|
var averageWithoutWeight: Boolean
|
||||||
|
get() { mAverageWithoutWeight = mAverageWithoutWeight ?: config.values.get("averageWithoutWeight", true); return mAverageWithoutWeight ?: true }
|
||||||
|
set(value) { config.set("averageWithoutWeight", value); mAverageWithoutWeight = value }
|
||||||
|
|
||||||
|
private var mPlusValue: Float? = null
|
||||||
|
var plusValue: Float?
|
||||||
|
get() { mPlusValue = mPlusValue ?: config.values.getFloat("plusValue"); return mPlusValue }
|
||||||
|
set(value) { config.set("plusValue", value); mPlusValue = value }
|
||||||
|
private var mMinusValue: Float? = null
|
||||||
|
var minusValue: Float?
|
||||||
|
get() { mMinusValue = mMinusValue ?: config.values.getFloat("minusValue"); return mMinusValue }
|
||||||
|
set(value) { config.set("minusValue", value); mMinusValue = value }
|
||||||
|
|
||||||
|
private var mDontCountEnabled: Boolean? = null
|
||||||
|
var dontCountEnabled: Boolean
|
||||||
|
get() { mDontCountEnabled = mDontCountEnabled ?: config.values.get("dontCountEnabled", false); return mDontCountEnabled ?: false }
|
||||||
|
set(value) { config.set("dontCountEnabled", value); mDontCountEnabled = value }
|
||||||
|
|
||||||
|
private var mDontCountGrades: List<String>? = null
|
||||||
|
var dontCountGrades: List<String>
|
||||||
|
get() { mDontCountGrades = mDontCountGrades ?: config.values.get("dontCountGrades", listOf()); return mDontCountGrades ?: listOf() }
|
||||||
|
set(value) { config.set("dontCountGrades", value); mDontCountGrades = value }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-2-21.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
|
||||||
|
class ProfileConfigSync(private val config: ProfileConfig) {
|
||||||
|
private var mNotificationFilter: List<Int>? = null
|
||||||
|
var notificationFilter: List<Int>
|
||||||
|
get() { mNotificationFilter = mNotificationFilter ?: config.values.get("notificationFilter", listOf()); return mNotificationFilter ?: listOf() }
|
||||||
|
set(value) { config.set("notificationFilter", value); mNotificationFilter = value }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
|
import pl.szczodrzynski.edziennik.ui.modules.home.HomeCardModel
|
||||||
|
|
||||||
|
class ProfileConfigUI(private val config: ProfileConfig) {
|
||||||
|
private var mAgendaViewType: Int? = null
|
||||||
|
var agendaViewType: Int
|
||||||
|
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT }
|
||||||
|
set(value) { config.set("agendaViewType", value); mAgendaViewType = value }
|
||||||
|
|
||||||
|
private var mHomeCards: List<HomeCardModel>? = null
|
||||||
|
var homeCards: List<HomeCardModel>
|
||||||
|
get() { mHomeCards = mHomeCards ?: config.values.get("homeCards", listOf(), HomeCardModel::class.java); return mHomeCards ?: listOf() }
|
||||||
|
set(value) { config.set("homeCards", value); mHomeCards = value }
|
||||||
|
}
|
@ -22,4 +22,7 @@ interface ConfigDao {
|
|||||||
|
|
||||||
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
@Query("SELECT * FROM config WHERE profileId = :profileId")
|
||||||
fun getAllNow(profileId: Int): List<ConfigEntry>
|
fun getAllNow(profileId: Int): List<ConfigEntry>
|
||||||
|
|
||||||
|
@Query("DELETE FROM config WHERE profileId = :profileId")
|
||||||
|
fun clear(profileId: Int)
|
||||||
}
|
}
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-19.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
class AppConfigMigrationV3(p: SharedPreferences, config: Config) {
|
||||||
|
init { config.apply {
|
||||||
|
val s = "app.appConfig"
|
||||||
|
if (dataVersion < 1) {
|
||||||
|
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
||||||
|
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
||||||
|
sync.interval = p.getString("$s.registerSyncInterval", null)?.toIntOrNull() ?: 3600
|
||||||
|
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
||||||
|
str.replace("[\\[\\]]*".toRegex(), "")
|
||||||
|
.split(",\\s?".toRegex())
|
||||||
|
.mapNotNull { it.toIntOrNull() }
|
||||||
|
}
|
||||||
|
ui.miniMenuButtons = oldButtons ?: listOf(
|
||||||
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
|
MainActivity.DRAWER_ITEM_GRADES,
|
||||||
|
MainActivity.DRAWER_ITEM_MESSAGES,
|
||||||
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
|
)
|
||||||
|
dataVersion = 1
|
||||||
|
}
|
||||||
|
if (dataVersion < 2) {
|
||||||
|
devModePassword = p.getString("$s.devModePassword", null).fix()
|
||||||
|
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
|
||||||
|
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
|
||||||
|
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
|
||||||
|
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
|
||||||
|
ui.headerBackground = p.getString("$s.headerBackground", null).fix()
|
||||||
|
ui.appBackground = p.getString("$s.appBackground", null).fix()
|
||||||
|
ui.language = p.getString("$s.language", null).fix()
|
||||||
|
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
||||||
|
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
||||||
|
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
||||||
|
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
||||||
|
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
||||||
|
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
||||||
|
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
||||||
|
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
||||||
|
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
||||||
|
|
||||||
|
val startMillis = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
|
||||||
|
val endMillis = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
|
||||||
|
if (startMillis > 0) {
|
||||||
|
try {
|
||||||
|
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
|
||||||
|
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
|
||||||
|
sync.quietHoursEnabled = true
|
||||||
|
}
|
||||||
|
catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sync.quietHoursEnabled = false
|
||||||
|
sync.quietHoursStart = null
|
||||||
|
sync.quietHoursEnd = null
|
||||||
|
}
|
||||||
|
|
||||||
|
sync.tokenMobidziennikList = listOf()
|
||||||
|
sync.tokenVulcanList = listOf()
|
||||||
|
sync.tokenLibrusList = listOf()
|
||||||
|
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
||||||
|
tokens?.forEach {
|
||||||
|
val token = it.value.first
|
||||||
|
when (it.key) {
|
||||||
|
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
||||||
|
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
||||||
|
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dataVersion = 2
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
|
||||||
|
private fun String?.fix(): String? {
|
||||||
|
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
||||||
|
}
|
||||||
|
}
|
@ -37,6 +37,9 @@ fun AbstractConfig.set(key: String, value: JsonElement?) {
|
|||||||
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
fun AbstractConfig.set(key: String, value: List<Any>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
|
fun AbstractConfig.set(key: String, value: Any?) {
|
||||||
|
set(key, value?.let { gson.toJson(it) })
|
||||||
|
}
|
||||||
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
fun AbstractConfig.setStringList(key: String, value: List<String>?) {
|
||||||
set(key, value?.let { gson.toJson(it) })
|
set(key, value?.let { gson.toJson(it) })
|
||||||
}
|
}
|
||||||
@ -74,6 +77,9 @@ fun HashMap<String, String?>.get(key: String, default: JsonObject?): JsonObject?
|
|||||||
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
fun HashMap<String, String?>.get(key: String, default: JsonArray?): JsonArray? {
|
||||||
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
return this[key]?.let { JsonParser().parse(it)?.asJsonArray } ?: default
|
||||||
}
|
}
|
||||||
|
inline fun <reified T> HashMap<String, String?>.get(key: String, default: T?): T? {
|
||||||
|
return this[key]?.let { Gson().fromJson(it, T::class.java) } ?: default
|
||||||
|
}
|
||||||
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
/* !!! cannot use mutable list here - modifying it will not update the DB */
|
||||||
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
fun <T> HashMap<String, String?>.get(key: String, default: List<T>?, classOfT: Class<T>): List<T>? {
|
||||||
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
return this[key]?.let { ConfigGsonUtils().deserializeList<T>(gson, it, classOfT) } ?: default
|
||||||
@ -88,10 +94,14 @@ fun HashMap<String, String?>.getLongList(key: String, default: List<Long>?): Lis
|
|||||||
return this[key]?.let { gson.fromJson<List<Long>>(it, object: TypeToken<List<Long>>(){}.type) } ?: default
|
return this[key]?.let { gson.fromJson<List<Long>>(it, object: TypeToken<List<Long>>(){}.type) } ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun HashMap<String, String?>.getFloat(key: String): Float? {
|
||||||
|
return this[key]?.toFloatOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
fun List<ConfigEntry>.toHashMap(profileId: Int, map: HashMap<String, String?>) {
|
fun List<ConfigEntry>.toHashMap(profileId: Int, map: HashMap<String, String?>) {
|
||||||
map.clear()
|
map.clear()
|
||||||
forEach {
|
forEach {
|
||||||
if (it.profileId == profileId)
|
if (it.profileId == profileId)
|
||||||
map[it.key] = it.value
|
map[it.key] = it.value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,32 +5,34 @@
|
|||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.google.gson.Gson
|
|
||||||
import com.google.gson.reflect.TypeToken
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.BuildConfig
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
|
import pl.szczodrzynski.edziennik.HOUR
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_VULCAN
|
|
||||||
import pl.szczodrzynski.edziennik.config.Config
|
import pl.szczodrzynski.edziennik.config.Config
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
import kotlin.math.abs
|
||||||
|
|
||||||
class ConfigMigration(app: App, config: Config) {
|
class ConfigMigration(app: App, config: Config) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
||||||
ui.theme = p.getString("$s.appTheme", null)?.toIntOrNull() ?: 1
|
if (p.contains("app.appConfig.appTheme")) {
|
||||||
sync.enabled = p.getString("$s.registerSyncEnabled", null)?.toBoolean() ?: true
|
// migrate appConfig from app version 3.x and lower.
|
||||||
sync.interval = p.getString("$s.registerSyncEnabled", null)?.toIntOrNull() ?: 3600
|
// Updates dataVersion to level 2.
|
||||||
val oldButtons = p.getString("$s.miniDrawerButtonIds", null)?.let { str ->
|
AppConfigMigrationV3(p, config)
|
||||||
str.replace("[\\[\\]]*".toRegex(), "")
|
}
|
||||||
.split(",\\s?".toRegex())
|
|
||||||
.mapNotNull { it.toIntOrNull() }
|
if (dataVersion < 2) {
|
||||||
}
|
appVersion = BuildConfig.VERSION_CODE
|
||||||
ui.miniMenuButtons = oldButtons ?: listOf(
|
loginFinished = false
|
||||||
|
ui.language = null
|
||||||
|
ui.theme = 1
|
||||||
|
ui.appBackground = null
|
||||||
|
ui.headerBackground = null
|
||||||
|
ui.miniMenuVisible = false
|
||||||
|
ui.miniMenuButtons = listOf(
|
||||||
MainActivity.DRAWER_ITEM_HOME,
|
MainActivity.DRAWER_ITEM_HOME,
|
||||||
MainActivity.DRAWER_ITEM_TIMETABLE,
|
MainActivity.DRAWER_ITEM_TIMETABLE,
|
||||||
MainActivity.DRAWER_ITEM_AGENDA,
|
MainActivity.DRAWER_ITEM_AGENDA,
|
||||||
@ -39,46 +41,56 @@ class ConfigMigration(app: App, config: Config) {
|
|||||||
MainActivity.DRAWER_ITEM_HOMEWORK,
|
MainActivity.DRAWER_ITEM_HOMEWORK,
|
||||||
MainActivity.DRAWER_ITEM_SETTINGS
|
MainActivity.DRAWER_ITEM_SETTINGS
|
||||||
)
|
)
|
||||||
dataVersion = 1
|
sync.enabled = true
|
||||||
}
|
sync.interval = 1*HOUR.toInt()
|
||||||
if (dataVersion < 2) {
|
sync.notifyAboutUpdates = true
|
||||||
devModePassword = p.getString("$s.devModePassword", null).fix()
|
sync.onlyWifi = false
|
||||||
sync.tokenApp = p.getString("$s.fcmToken", null).fix()
|
sync.quietHoursEnabled = false
|
||||||
timetable.bellSyncMultiplier = p.getString("$s.bellSyncMultiplier", null)?.toIntOrNull() ?: 0
|
sync.quietHoursStart = null
|
||||||
sync.quietHoursStart = p.getString("$s.quietHoursStart", null)?.toLongOrNull() ?: 0
|
sync.quietHoursEnd = null
|
||||||
appRateSnackbarTime = p.getString("$s.appRateSnackbarTime", null)?.toLongOrNull() ?: 0
|
sync.quietDuringLessons = false
|
||||||
sync.quietHoursEnd = p.getString("$s.quietHoursEnd", null)?.toLongOrNull() ?: 0
|
sync.tokenApp = null
|
||||||
timetable.countInSeconds = p.getString("$s.countInSeconds", null)?.toBoolean() ?: false
|
sync.tokenMobidziennik = null
|
||||||
ui.headerBackground = p.getString("$s.headerBackground", null).fix()
|
|
||||||
ui.appBackground = p.getString("$s.appBackground", null).fix()
|
|
||||||
ui.language = p.getString("$s.language", null).fix()
|
|
||||||
appVersion = p.getString("$s.lastAppVersion", null)?.toIntOrNull() ?: BuildConfig.VERSION_CODE
|
|
||||||
appInstalledTime = p.getString("$s.appInstalledTime", null)?.toLongOrNull() ?: 0
|
|
||||||
grades.orderBy = p.getString("$s.gradesOrderBy", null)?.toIntOrNull() ?: 0
|
|
||||||
sync.quietDuringLessons = p.getString("$s.quietDuringLessons", null)?.toBoolean() ?: false
|
|
||||||
ui.miniMenuVisible = p.getString("$s.miniDrawerVisible", null)?.toBoolean() ?: false
|
|
||||||
loginFinished = p.getString("$s.loginFinished", null)?.toBoolean() ?: false
|
|
||||||
sync.onlyWifi = p.getString("$s.registerSyncOnlyWifi", null)?.toBoolean() ?: false
|
|
||||||
sync.notifyAboutUpdates = p.getString("$s.notifyAboutUpdates", null)?.toBoolean() ?: true
|
|
||||||
timetable.bellSyncDiff = p.getString("$s.bellSyncDiff", null)?.let { Gson().fromJson(it, Time::class.java) }
|
|
||||||
|
|
||||||
sync.tokenMobidziennikList = listOf()
|
sync.tokenMobidziennikList = listOf()
|
||||||
sync.tokenVulcanList = listOf()
|
sync.tokenLibrus = null
|
||||||
sync.tokenLibrusList = listOf()
|
sync.tokenLibrusList = listOf()
|
||||||
val tokens = p.getString("$s.fcmTokens", null)?.let { Gson().fromJson<Map<Int, Pair<String, List<Int>>>>(it, object: TypeToken<Map<Int, Pair<String, List<Int>>>>(){}.type) }
|
sync.tokenVulcan = null
|
||||||
tokens?.forEach {
|
sync.tokenVulcanList = listOf()
|
||||||
val token = it.value.first
|
timetable.bellSyncMultiplier = 0
|
||||||
when (it.key) {
|
timetable.bellSyncDiff = null
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> sync.tokenMobidziennik = token
|
timetable.countInSeconds = false
|
||||||
LOGIN_TYPE_VULCAN -> sync.tokenVulcan = token
|
grades.orderBy = ORDER_BY_DATE_DESC
|
||||||
LOGIN_TYPE_LIBRUS -> sync.tokenLibrus = token
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dataVersion = 2
|
dataVersion = 2
|
||||||
}
|
}
|
||||||
}}
|
|
||||||
|
|
||||||
private fun String?.fix(): String? {
|
if (dataVersion < 10) {
|
||||||
return this?.replace("\"", "")?.let { if (it == "null") null else it }
|
ui.openDrawerOnBackPressed = false
|
||||||
}
|
ui.snowfall = false
|
||||||
|
ui.bottomSheetOpened = false
|
||||||
|
sync.dontShowAppManagerDialog = false
|
||||||
|
|
||||||
|
dataVersion = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dataVersion < 11) {
|
||||||
|
val startMillis = config.values.get("quietHoursStart", 0L)
|
||||||
|
val endMillis = config.values.get("quietHoursEnd", 0L)
|
||||||
|
if (startMillis > 0) {
|
||||||
|
try {
|
||||||
|
sync.quietHoursStart = Time.fromMillis(abs(startMillis))
|
||||||
|
sync.quietHoursEnd = Time.fromMillis(abs(endMillis))
|
||||||
|
sync.quietHoursEnabled = true
|
||||||
|
}
|
||||||
|
catch (_: Exception) {}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sync.quietHoursEnabled = false
|
||||||
|
sync.quietHoursStart = null
|
||||||
|
sync.quietHoursEnd = null
|
||||||
|
}
|
||||||
|
|
||||||
|
dataVersion = 11
|
||||||
|
}
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,21 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.config.utils
|
package pl.szczodrzynski.edziennik.config.utils
|
||||||
|
|
||||||
import android.content.Context
|
import pl.szczodrzynski.edziennik.config.ProfileConfig
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
|
||||||
import pl.szczodrzynski.edziennik.config.Config
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||||
|
import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.YEAR_ALL_GRADES
|
||||||
|
|
||||||
class ProfileConfigMigration(app: App, config: Config) {
|
class ProfileConfigMigration(config: ProfileConfig) {
|
||||||
init { config.apply {
|
init { config.apply {
|
||||||
val p = app.getSharedPreferences("pl.szczodrzynski.edziennik_profiles", Context.MODE_PRIVATE)
|
|
||||||
val s = "app.appConfig"
|
|
||||||
|
|
||||||
if (dataVersion < 1) {
|
if (dataVersion < 1) {
|
||||||
|
grades.colorMode = COLOR_MODE_WEIGHTED
|
||||||
|
grades.dontCountEnabled = false
|
||||||
|
grades.yearAverageMode = YEAR_ALL_GRADES
|
||||||
|
ui.agendaViewType = AGENDA_DEFAULT
|
||||||
|
|
||||||
//dataVersion = 1
|
dataVersion = 1
|
||||||
}
|
|
||||||
if (dataVersion < 2) {
|
|
||||||
//gradesColorMode do profilu !
|
|
||||||
//agendaViewType do profilu !
|
|
||||||
// app.appConfig.dontCountZeroToAverage do profilu !
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,17 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.*
|
import pl.szczodrzynski.edziennik.data.api.events.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.ServiceCloseRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
import pl.szczodrzynski.edziennik.data.api.events.requests.TaskCancelRequest
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.*
|
import pl.szczodrzynski.edziennik.data.api.task.ErrorReportTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.SzkolnyTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
|
import pl.szczodrzynski.edziennik.toApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@ -26,7 +30,7 @@ import kotlin.math.roundToInt
|
|||||||
class ApiService : Service() {
|
class ApiService : Service() {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "ApiService"
|
const val TAG = "ApiService"
|
||||||
const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.GET_DATA"
|
const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.SYNC"
|
||||||
fun start(context: Context) {
|
fun start(context: Context) {
|
||||||
context.startService(Intent(context, ApiService::class.java))
|
context.startService(Intent(context, ApiService::class.java))
|
||||||
}
|
}
|
||||||
@ -40,26 +44,25 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
private val syncingProfiles = mutableListOf<Profile>()
|
private val syncingProfiles = mutableListOf<Profile>()
|
||||||
|
|
||||||
private val finishingTaskQueue = mutableListOf(
|
private var szkolnyTaskFinished = false
|
||||||
SzkolnyTask.sync(syncingProfiles),
|
private val allTaskRequestList = mutableListOf<Any>()
|
||||||
NotifyTask()
|
|
||||||
)
|
|
||||||
private val allTaskList = mutableListOf<IApiTask>()
|
|
||||||
private val taskQueue = mutableListOf<IApiTask>()
|
private val taskQueue = mutableListOf<IApiTask>()
|
||||||
private val errorList = mutableListOf<ApiError>()
|
private val errorList = mutableListOf<ApiError>()
|
||||||
|
|
||||||
private var serviceClosed = false
|
private var serviceClosed = false
|
||||||
|
set(value) { field = value; notification.serviceClosed = value }
|
||||||
private var taskCancelled = false
|
private var taskCancelled = false
|
||||||
private var taskIsRunning = false
|
private var taskIsRunning = false
|
||||||
private var taskRunning: IApiTask? = null // for debug purposes
|
private var taskRunning: IApiTask? = null // for debug purposes
|
||||||
private var taskRunningId = -1
|
private var taskRunningId = -1
|
||||||
|
private var taskStartTime = 0L
|
||||||
private var taskMaximumId = 0
|
private var taskMaximumId = 0
|
||||||
|
|
||||||
private var taskProfileId = -1
|
private var taskProfileId = -1
|
||||||
private var taskProgress = -1f
|
private var taskProgress = -1f
|
||||||
private var taskProgressText: String? = null
|
private var taskProgressText: String? = null
|
||||||
|
|
||||||
private val notification by lazy { EdziennikNotification(this) }
|
private val notification by lazy { EdziennikNotification(app) }
|
||||||
|
|
||||||
private var lastEventTime = System.currentTimeMillis()
|
private var lastEventTime = System.currentTimeMillis()
|
||||||
private var taskCancelTries = 0
|
private var taskCancelTries = 0
|
||||||
@ -73,7 +76,7 @@ class ApiService : Service() {
|
|||||||
private val taskCallback = object : EdziennikCallback {
|
private val taskCallback = object : EdziennikCallback {
|
||||||
override fun onCompleted() {
|
override fun onCompleted() {
|
||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished")
|
d(TAG, "Task $taskRunningId (profile $taskProfileId) finished in ${System.currentTimeMillis()-taskStartTime}")
|
||||||
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
|
EventBus.getDefault().postSticky(ApiTaskFinishedEvent(taskProfileId))
|
||||||
clearTask()
|
clearTask()
|
||||||
|
|
||||||
@ -85,9 +88,16 @@ class ApiService : Service() {
|
|||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
d(TAG, "Task $taskRunningId threw an error - $apiError")
|
d(TAG, "Task $taskRunningId threw an error - $apiError")
|
||||||
apiError.profileId = taskProfileId
|
apiError.profileId = taskProfileId
|
||||||
EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError))
|
|
||||||
errorList.add(apiError)
|
if (app.userActionManager.requiresUserAction(apiError)) {
|
||||||
apiError.throwable?.printStackTrace()
|
app.userActionManager.sendToUser(apiError)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
EventBus.getDefault().postSticky(ApiTaskErrorEvent(apiError))
|
||||||
|
errorList.add(apiError)
|
||||||
|
apiError.throwable?.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
if (apiError.isCritical) {
|
if (apiError.isCritical) {
|
||||||
taskRunning?.cancel()
|
taskRunning?.cancel()
|
||||||
notification.setCriticalError().post()
|
notification.setCriticalError().post()
|
||||||
@ -131,15 +141,20 @@ class ApiService : Service() {
|
|||||||
checkIfTaskFrozen()
|
checkIfTaskFrozen()
|
||||||
if (taskIsRunning)
|
if (taskIsRunning)
|
||||||
return
|
return
|
||||||
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) {
|
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && szkolnyTaskFinished)) {
|
||||||
serviceClosed = false
|
|
||||||
allCompleted()
|
allCompleted()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lastEventTime = System.currentTimeMillis()
|
lastEventTime = System.currentTimeMillis()
|
||||||
|
|
||||||
val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0)
|
val task = if (taskQueue.isNotEmpty()) {
|
||||||
|
taskQueue.removeAt(0)
|
||||||
|
} else {
|
||||||
|
szkolnyTaskFinished = true
|
||||||
|
SzkolnyTask(app, syncingProfiles)
|
||||||
|
}
|
||||||
|
|
||||||
task.taskId = ++taskMaximumId
|
task.taskId = ++taskMaximumId
|
||||||
task.prepare(app)
|
task.prepare(app)
|
||||||
taskIsRunning = true
|
taskIsRunning = true
|
||||||
@ -149,7 +164,7 @@ class ApiService : Service() {
|
|||||||
taskProgress = -1f
|
taskProgress = -1f
|
||||||
taskProgressText = task.taskName
|
taskProgressText = task.taskName
|
||||||
|
|
||||||
d(TAG, "Executing task $taskRunningId ($taskProgressText) - $task")
|
d(TAG, "Executing task $taskRunningId - ${task::class.java.name}")
|
||||||
|
|
||||||
// update the notification
|
// update the notification
|
||||||
notification.setCurrentTask(taskRunningId, taskProgressText).post()
|
notification.setCurrentTask(taskRunningId, taskProgressText).post()
|
||||||
@ -159,15 +174,15 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
task.profile?.let { syncingProfiles.add(it) }
|
task.profile?.let { syncingProfiles.add(it) }
|
||||||
|
|
||||||
|
taskStartTime = System.currentTimeMillis()
|
||||||
try {
|
try {
|
||||||
when (task) {
|
when (task) {
|
||||||
is EdziennikTask -> task.run(app, taskCallback)
|
is EdziennikTask -> task.run(app, taskCallback)
|
||||||
is NotifyTask -> task.run(app, taskCallback)
|
|
||||||
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
is ErrorReportTask -> task.run(app, taskCallback, notification, errorList)
|
||||||
is SzkolnyTask -> task.run(app, taskCallback)
|
is SzkolnyTask -> task.run(taskCallback)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
taskCallback.onError(ApiError(TAG, EXCEPTION_API_TASK).withThrowable(e))
|
taskCallback.onError(e.toApiError(TAG))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +229,7 @@ class ApiService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun allCompleted() {
|
private fun allCompleted() {
|
||||||
|
serviceClosed = true
|
||||||
EventBus.getDefault().postSticky(ApiTaskAllFinishedEvent())
|
EventBus.getDefault().postSticky(ApiTaskAllFinishedEvent())
|
||||||
stopSelf()
|
stopSelf()
|
||||||
}
|
}
|
||||||
@ -229,10 +245,12 @@ class ApiService : Service() {
|
|||||||
EventBus.getDefault().removeStickyEvent(task)
|
EventBus.getDefault().removeStickyEvent(task)
|
||||||
d(TAG, task.toString())
|
d(TAG, task.toString())
|
||||||
|
|
||||||
// fix for duplicated tasks, thank you EventBus
|
if (task is EdziennikTask) {
|
||||||
if (task in allTaskList)
|
// fix for duplicated tasks, thank you EventBus
|
||||||
return
|
if (task.request in allTaskRequestList)
|
||||||
allTaskList += task
|
return
|
||||||
|
allTaskRequestList += task.request
|
||||||
|
}
|
||||||
|
|
||||||
if (task is EdziennikTask) {
|
if (task is EdziennikTask) {
|
||||||
when (task.request) {
|
when (task.request) {
|
||||||
@ -293,11 +311,13 @@ class ApiService : Service() {
|
|||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
d(TAG, "Foreground service onStartCommand")
|
d(TAG, "Foreground service onStartCommand")
|
||||||
startForeground(EdziennikNotification.NOTIFICATION_ID, notification.notification)
|
startForeground(app.notificationChannelsManager.sync.id, notification.notification)
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
d(TAG, "Service destroyed")
|
||||||
|
serviceClosed = true
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,9 +22,9 @@ const val FAKE_LIBRUS_TOKEN = "https://librus.szkolny.eu/access_token.php"
|
|||||||
const val FAKE_LIBRUS_ACCOUNT = "/synergia_accounts_fresh.php?login="
|
const val FAKE_LIBRUS_ACCOUNT = "/synergia_accounts_fresh.php?login="
|
||||||
const val FAKE_LIBRUS_ACCOUNTS = "/synergia_accounts.php"
|
const val FAKE_LIBRUS_ACCOUNTS = "/synergia_accounts.php"
|
||||||
|
|
||||||
val LIBRUS_USER_AGENT = "$SYSTEM_USER_AGENT LibrusMobileApp"
|
val LIBRUS_USER_AGENT = "${SYSTEM_USER_AGENT}LibrusMobileApp"
|
||||||
const val SYNERGIA_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/62.0"
|
const val SYNERGIA_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Gecko/20100101 Firefox/62.0"
|
||||||
const val LIBRUS_CLIENT_ID = "wmSyUMo8llDAs4y9tJVYY92oyZ6h4lAt7KCuy0Gv"
|
const val LIBRUS_CLIENT_ID = "6XPsKf10LPz1nxgHQLcvZ1KM48DYzlBAhxipaXY8"
|
||||||
const val LIBRUS_REDIRECT_URL = "http://localhost/bar"
|
const val LIBRUS_REDIRECT_URL = "http://localhost/bar"
|
||||||
const val LIBRUS_AUTHORIZE_URL = "https://portal.librus.pl/oauth2/authorize?client_id=$LIBRUS_CLIENT_ID&redirect_uri=$LIBRUS_REDIRECT_URL&response_type=code"
|
const val LIBRUS_AUTHORIZE_URL = "https://portal.librus.pl/oauth2/authorize?client_id=$LIBRUS_CLIENT_ID&redirect_uri=$LIBRUS_REDIRECT_URL&response_type=code"
|
||||||
const val LIBRUS_LOGIN_URL = "https://portal.librus.pl/rodzina/login/action"
|
const val LIBRUS_LOGIN_URL = "https://portal.librus.pl/rodzina/login/action"
|
||||||
@ -60,6 +60,7 @@ const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
|||||||
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
||||||
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
||||||
const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.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_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec"
|
||||||
const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia"
|
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_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia"
|
||||||
|
@ -1,209 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_BEHAVIOUR
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES
|
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_LUCKY_NUMBER
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ANNOUNCEMENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_EVENT
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_GRADE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_MESSAGE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_NEW_NOTICE
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notification.Companion.TYPE_TIMETABLE_LESSON_CHANGE
|
|
||||||
import pl.szczodrzynski.edziennik.getNotificationTitle
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class DataNotifications(val data: Data) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "DataNotifications"
|
|
||||||
}
|
|
||||||
|
|
||||||
val app = data.app
|
|
||||||
val profileId = data.profile?.id ?: -1
|
|
||||||
val profileName = data.profile?.name ?: ""
|
|
||||||
val profile = data.profile
|
|
||||||
val loginStore = data.loginStore
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (profile == null) {
|
|
||||||
return@run
|
|
||||||
}
|
|
||||||
|
|
||||||
val today = Date.getToday()
|
|
||||||
val todayValue = today.value
|
|
||||||
|
|
||||||
for (lesson in app.db.timetableDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.getString(R.string.notification_lesson_change_format, lesson.getDisplayChangeType(app), if (lesson.displayDate == null) "" else lesson.displayDate!!.formattedString, lesson.changeSubjectName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_TIMETABLE_LESSON_CHANGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_TIMETABLE_LESSON_CHANGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_TIMETABLE,
|
|
||||||
addedDate = lesson.addedDate
|
|
||||||
).addExtra("timetableDate", lesson.displayDate?.stringY_m_d ?: "")
|
|
||||||
}
|
|
||||||
|
|
||||||
for (event in app.db.eventDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = if (event.type == Event.TYPE_HOMEWORK)
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_homework_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_homework_format,
|
|
||||||
event.subjectLongName,
|
|
||||||
event.eventDate.formattedString
|
|
||||||
)
|
|
||||||
else
|
|
||||||
app.getString(
|
|
||||||
if (event.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_event_no_subject_format
|
|
||||||
else
|
|
||||||
R.string.notification_event_format,
|
|
||||||
event.typeName,
|
|
||||||
event.eventDate.formattedString,
|
|
||||||
event.subjectLongName
|
|
||||||
)
|
|
||||||
val type = if (event.type == Event.TYPE_HOMEWORK) TYPE_NEW_HOMEWORK else TYPE_NEW_EVENT
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(type),
|
|
||||||
text = text,
|
|
||||||
type = type,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = if (event.type == Event.TYPE_HOMEWORK) DRAWER_ITEM_HOMEWORK else DRAWER_ITEM_AGENDA,
|
|
||||||
addedDate = event.addedDate
|
|
||||||
).addExtra("eventId", event.id).addExtra("eventDate", event.eventDate.value.toLong())
|
|
||||||
}
|
|
||||||
|
|
||||||
for (grade in app.db.gradeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val gradeName = when (grade.type) {
|
|
||||||
TYPE_SEMESTER1_PROPOSED, TYPE_SEMESTER2_PROPOSED -> app.getString(R.string.grade_semester_proposed_format_2, grade.name)
|
|
||||||
TYPE_SEMESTER1_FINAL, TYPE_SEMESTER2_FINAL -> app.getString(R.string.grade_semester_final_format_2, grade.name)
|
|
||||||
TYPE_YEAR_PROPOSED -> app.getString(R.string.grade_year_proposed_format_2, grade.name)
|
|
||||||
TYPE_YEAR_FINAL -> app.getString(R.string.grade_year_final_format_2, grade.name)
|
|
||||||
else -> grade.name
|
|
||||||
}
|
|
||||||
val text = app.getString(R.string.notification_grade_format, gradeName, grade.subjectLongName)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_GRADE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_GRADE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_GRADES,
|
|
||||||
addedDate = grade.addedDate
|
|
||||||
).addExtra("gradeId", grade.id).addExtra("gradesSubjectId", grade.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (notice in app.db.noticeDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val noticeTypeStr = if (notice.type == Notice.TYPE_POSITIVE) app.getString(R.string.notification_notice_praise) else if (notice.type == Notice.TYPE_NEGATIVE) app.getString(R.string.notification_notice_warning) else app.getString(R.string.notification_notice_new)
|
|
||||||
val text = app.getString(R.string.notification_notice_format, noticeTypeStr, notice.teacherFullName, Date.fromMillis(notice.addedDate).formattedString)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_NOTICE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_NOTICE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_BEHAVIOUR,
|
|
||||||
addedDate = notice.addedDate
|
|
||||||
).addExtra("noticeId", notice.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (attendance in app.db.attendanceDao().getNotNotifiedNow(profileId)) {
|
|
||||||
var attendanceTypeStr = app.getString(R.string.notification_type_attendance)
|
|
||||||
when (attendance.type) {
|
|
||||||
Attendance.TYPE_ABSENT -> attendanceTypeStr = app.getString(R.string.notification_absence)
|
|
||||||
Attendance.TYPE_ABSENT_EXCUSED -> attendanceTypeStr = app.getString(R.string.notification_absence_excused)
|
|
||||||
Attendance.TYPE_BELATED -> attendanceTypeStr = app.getString(R.string.notification_belated)
|
|
||||||
Attendance.TYPE_BELATED_EXCUSED -> attendanceTypeStr = app.getString(R.string.notification_belated_excused)
|
|
||||||
Attendance.TYPE_RELEASED -> attendanceTypeStr = app.getString(R.string.notification_release)
|
|
||||||
}
|
|
||||||
val text = app.getString(
|
|
||||||
if (attendance.subjectLongName.isNullOrEmpty())
|
|
||||||
R.string.notification_attendance_no_lesson_format
|
|
||||||
else
|
|
||||||
R.string.notification_attendance_format,
|
|
||||||
attendanceTypeStr,
|
|
||||||
attendance.subjectLongName,
|
|
||||||
attendance.lessonDate.formattedString
|
|
||||||
)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ATTENDANCE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ATTENDANCE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ATTENDANCE,
|
|
||||||
addedDate = attendance.addedDate
|
|
||||||
).addExtra("attendanceId", attendance.id).addExtra("attendanceSubjectId", attendance.subjectId)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (announcement in app.db.announcementDao().getNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_announcement_format, announcement.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_ANNOUNCEMENT),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_ANNOUNCEMENT,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_ANNOUNCEMENTS,
|
|
||||||
addedDate = announcement.addedDate
|
|
||||||
).addExtra("announcementId", announcement.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (message in app.db.messageDao().getReceivedNotNotifiedNow(profileId)) {
|
|
||||||
val text = app.context.getString(R.string.notification_message_format, message.senderFullName, message.subject)
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_NEW_MESSAGE),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_NEW_MESSAGE,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_MESSAGES,
|
|
||||||
addedDate = message.addedDate
|
|
||||||
).addExtra("messageType", Message.TYPE_RECEIVED.toLong()).addExtra("messageId", message.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
val luckyNumbers = app.db.luckyNumberDao().getNotNotifiedNow(profileId)
|
|
||||||
luckyNumbers?.removeAll { it.date < today }
|
|
||||||
luckyNumbers?.forEach { luckyNumber ->
|
|
||||||
val text = when (luckyNumber.date.value) {
|
|
||||||
todayValue -> // LN for today
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_format else R.string.notification_lucky_number_format, luckyNumber.number)
|
|
||||||
todayValue + 1 -> // LN for tomorrow
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_tomorrow_format else R.string.notification_lucky_number_tomorrow_format, luckyNumber.number)
|
|
||||||
else -> // LN for later
|
|
||||||
app.getString(if (profile.studentNumber != -1 && profile.studentNumber == luckyNumber.number) R.string.notification_lucky_number_yours_later_format else R.string.notification_lucky_number_later_format, luckyNumber.date.formattedString, luckyNumber.number)
|
|
||||||
}
|
|
||||||
data.notifications += Notification(
|
|
||||||
title = app.getNotificationTitle(TYPE_LUCKY_NUMBER),
|
|
||||||
text = text,
|
|
||||||
type = TYPE_LUCKY_NUMBER,
|
|
||||||
profileId = profileId,
|
|
||||||
profileName = profileName,
|
|
||||||
viewId = DRAWER_ITEM_HOME,
|
|
||||||
addedDate = luckyNumber.addedDate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.db.metadataDao().setAllNotified(profileId, true)
|
|
||||||
}}
|
|
||||||
}
|
|
@ -11,19 +11,16 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
import androidx.core.app.NotificationCompat.PRIORITY_MIN
|
||||||
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
|
|
||||||
class EdziennikNotification(val context: Context) {
|
class EdziennikNotification(val app: App) {
|
||||||
companion object {
|
private val notificationManager by lazy { app.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
||||||
const val NOTIFICATION_ID = 20191001
|
|
||||||
}
|
|
||||||
|
|
||||||
private val notificationManager by lazy { context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager }
|
|
||||||
|
|
||||||
private val notificationBuilder: NotificationCompat.Builder by lazy {
|
private val notificationBuilder: NotificationCompat.Builder by lazy {
|
||||||
NotificationCompat.Builder(context, ApiService.NOTIFICATION_API_CHANNEL_ID)
|
NotificationCompat.Builder(app, ApiService.NOTIFICATION_API_CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_notification)
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
.setPriority(PRIORITY_MIN)
|
.setPriority(PRIORITY_MIN)
|
||||||
.setOngoing(true)
|
.setOngoing(true)
|
||||||
@ -35,39 +32,40 @@ class EdziennikNotification(val context: Context) {
|
|||||||
|
|
||||||
private var errorCount = 0
|
private var errorCount = 0
|
||||||
private var criticalErrorCount = 0
|
private var criticalErrorCount = 0
|
||||||
|
var serviceClosed = false
|
||||||
|
|
||||||
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
private fun cancelPendingIntent(taskId: Int): PendingIntent {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
||||||
intent.putExtra("task", "TaskCancelRequest")
|
intent.putExtra("task", "TaskCancelRequest")
|
||||||
intent.putExtra("taskId", taskId)
|
intent.putExtra("taskId", taskId)
|
||||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
||||||
}
|
}
|
||||||
private val closePendingIntent: PendingIntent
|
private val closePendingIntent: PendingIntent
|
||||||
get() {
|
get() {
|
||||||
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
val intent = Intent("pl.szczodrzynski.edziennik.SZKOLNY_MAIN")
|
||||||
intent.putExtra("task", "ServiceCloseRequest")
|
intent.putExtra("task", "ServiceCloseRequest")
|
||||||
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
return PendingIntent.getBroadcast(app, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT) as PendingIntent
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun errorCountText(): String? {
|
private fun errorCountText(): String? {
|
||||||
var result = ""
|
var result = ""
|
||||||
if (criticalErrorCount > 0) {
|
if (criticalErrorCount > 0) {
|
||||||
result += context.resources.getQuantityString(R.plurals.critical_errors_format, criticalErrorCount, criticalErrorCount)
|
result += app.resources.getQuantityString(R.plurals.critical_errors_format, criticalErrorCount, criticalErrorCount)
|
||||||
}
|
}
|
||||||
if (criticalErrorCount > 0 && errorCount > 0) {
|
if (criticalErrorCount > 0 && errorCount > 0) {
|
||||||
result += ", "
|
result += ", "
|
||||||
}
|
}
|
||||||
if (errorCount > 0) {
|
if (errorCount > 0) {
|
||||||
result += context.resources.getQuantityString(R.plurals.normal_errors_format, errorCount, errorCount)
|
result += app.resources.getQuantityString(R.plurals.normal_errors_format, errorCount, errorCount)
|
||||||
}
|
}
|
||||||
return if (result.isEmpty()) null else result
|
return if (result.isEmpty()) null else result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setIdle(): EdziennikNotification {
|
fun setIdle(): EdziennikNotification {
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_title))
|
notificationBuilder.setContentTitle(app.getString(R.string.edziennik_notification_api_title))
|
||||||
notificationBuilder.setProgress(0, 0, false)
|
notificationBuilder.setProgress(0, 0, false)
|
||||||
notificationBuilder.apply {
|
notificationBuilder.apply {
|
||||||
val str = context.getString(R.string.edziennik_notification_api_text)
|
val str = app.getString(R.string.edziennik_notification_api_text)
|
||||||
setStyle(NotificationCompat.BigTextStyle().bigText(str))
|
setStyle(NotificationCompat.BigTextStyle().bigText(str))
|
||||||
setContentText(str)
|
setContentText(str)
|
||||||
}
|
}
|
||||||
@ -81,7 +79,7 @@ class EdziennikNotification(val context: Context) {
|
|||||||
}
|
}
|
||||||
fun setCriticalError(): EdziennikNotification {
|
fun setCriticalError(): EdziennikNotification {
|
||||||
criticalErrorCount++
|
criticalErrorCount++
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.edziennik_notification_api_error_title))
|
notificationBuilder.setContentTitle(app.getString(R.string.edziennik_notification_api_error_title))
|
||||||
notificationBuilder.setProgress(0, 0, false)
|
notificationBuilder.setProgress(0, 0, false)
|
||||||
notificationBuilder.apply {
|
notificationBuilder.apply {
|
||||||
val str = errorCountText()
|
val str = errorCountText()
|
||||||
@ -118,7 +116,7 @@ class EdziennikNotification(val context: Context) {
|
|||||||
notificationBuilder.addAction(
|
notificationBuilder.addAction(
|
||||||
NotificationCompat.Action(
|
NotificationCompat.Action(
|
||||||
R.drawable.ic_notification,
|
R.drawable.ic_notification,
|
||||||
context.getString(R.string.edziennik_notification_api_close),
|
app.getString(R.string.edziennik_notification_api_close),
|
||||||
closePendingIntent
|
closePendingIntent
|
||||||
))
|
))
|
||||||
return this
|
return this
|
||||||
@ -128,13 +126,15 @@ class EdziennikNotification(val context: Context) {
|
|||||||
notificationBuilder.addAction(
|
notificationBuilder.addAction(
|
||||||
NotificationCompat.Action(
|
NotificationCompat.Action(
|
||||||
R.drawable.ic_notification,
|
R.drawable.ic_notification,
|
||||||
context.getString(R.string.edziennik_notification_api_cancel),
|
app.getString(R.string.edziennik_notification_api_cancel),
|
||||||
cancelPendingIntent(taskId)
|
cancelPendingIntent(taskId)
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun post() {
|
fun post() {
|
||||||
notificationManager.notify(NOTIFICATION_ID, notification)
|
if (serviceClosed)
|
||||||
|
return
|
||||||
|
notificationManager.notify(app.notificationChannelsManager.sync.id, notification)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.EndpointTimer
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_NEVER
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_NEVER
|
||||||
|
|
||||||
fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featureIds: List<Int>, viewId: Int?) {
|
fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?) {
|
||||||
val data = this
|
val data = this
|
||||||
|
|
||||||
val possibleLoginMethods = data.loginMethods.toMutableList()
|
val possibleLoginMethods = data.loginMethods.toMutableList()
|
||||||
@ -46,14 +46,19 @@ fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featu
|
|||||||
// add all endpoint IDs and required login methods, filtering using timers
|
// add all endpoint IDs and required login methods, filtering using timers
|
||||||
.onEach { feature ->
|
.onEach { feature ->
|
||||||
feature.endpointIds.forEach { endpoint ->
|
feature.endpointIds.forEach { endpoint ->
|
||||||
|
if (onlyEndpoints?.contains(endpoint.first) == false)
|
||||||
|
return@forEach
|
||||||
(data.endpointTimers
|
(data.endpointTimers
|
||||||
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id
|
.singleOrNull { it.endpointId == endpoint.first } ?: EndpointTimer(data.profile?.id
|
||||||
?: -1, endpoint.first))
|
?: -1, endpoint.first))
|
||||||
.let { timer ->
|
.let { timer ->
|
||||||
if (timer.nextSync == SYNC_ALWAYS ||
|
if (
|
||||||
(viewId != null && timer.viewId == viewId) ||
|
onlyEndpoints?.contains(endpoint.first) == true ||
|
||||||
(timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp)) {
|
timer.nextSync == SYNC_ALWAYS ||
|
||||||
data.targetEndpointIds.add(endpoint.first)
|
viewId != null && timer.viewId == viewId ||
|
||||||
|
timer.nextSync != SYNC_NEVER && timer.nextSync < timestamp
|
||||||
|
) {
|
||||||
|
data.targetEndpointIds[endpoint.first] = timer.lastSync
|
||||||
requiredLoginMethods.add(endpoint.second)
|
requiredLoginMethods.add(endpoint.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,8 +81,8 @@ fun Data.prepare(loginMethods: List<LoginMethod>, features: List<Feature>, featu
|
|||||||
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
data.targetLoginMethodIds = data.targetLoginMethodIds.toHashSet().toMutableList()
|
||||||
data.targetLoginMethodIds.sort()
|
data.targetLoginMethodIds.sort()
|
||||||
|
|
||||||
data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
//data.targetEndpointIds = data.targetEndpointIds.toHashSet().toMutableList()
|
||||||
data.targetEndpointIds.sort()
|
//data.targetEndpointIds.sort()
|
||||||
|
|
||||||
progressCount = targetLoginMethodIds.size + targetEndpointIds.size
|
progressCount = targetLoginMethodIds.size + targetEndpointIds.size
|
||||||
progressStep = if (progressCount <= 0) 0f else 100f / progressCount.toFloat()
|
progressStep = if (progressCount <= 0) 0f else 100f / progressCount.toFloat()
|
||||||
@ -91,7 +96,6 @@ fun Data.prepareFor(loginMethods: List<LoginMethod>, loginMethodId: Int) {
|
|||||||
possibleLoginMethods += it.loginMethodId
|
possibleLoginMethods += it.loginMethodId
|
||||||
}
|
}
|
||||||
|
|
||||||
targetEndpointIds.clear()
|
|
||||||
targetLoginMethodIds.clear()
|
targetLoginMethodIds.clear()
|
||||||
|
|
||||||
// check the login method for any dependencies
|
// check the login method for any dependencies
|
||||||
|
@ -32,6 +32,8 @@ const val CODE_LIBRUS_DISCONNECTED = 31
|
|||||||
const val CODE_PROFILE_ARCHIVED = 30*/
|
const val CODE_PROFILE_ARCHIVED = 30*/
|
||||||
|
|
||||||
const val ERROR_APP_CRASH = 1
|
const val ERROR_APP_CRASH = 1
|
||||||
|
const val ERROR_EXCEPTION = 2
|
||||||
|
const val ERROR_API_EXCEPTION = 3
|
||||||
const val ERROR_MESSAGE_NOT_SENT = 10
|
const val ERROR_MESSAGE_NOT_SENT = 10
|
||||||
|
|
||||||
const val ERROR_REQUEST_FAILURE = 50
|
const val ERROR_REQUEST_FAILURE = 50
|
||||||
@ -51,6 +53,7 @@ const val ERROR_REQUEST_FAILURE_SSL_ERROR = 63
|
|||||||
const val ERROR_RESPONSE_EMPTY = 100
|
const val ERROR_RESPONSE_EMPTY = 100
|
||||||
const val ERROR_LOGIN_DATA_MISSING = 101
|
const val ERROR_LOGIN_DATA_MISSING = 101
|
||||||
const val ERROR_PROFILE_MISSING = 105
|
const val ERROR_PROFILE_MISSING = 105
|
||||||
|
const val ERROR_PROFILE_ARCHIVED = 106
|
||||||
const val ERROR_INVALID_LOGIN_MODE = 110
|
const val ERROR_INVALID_LOGIN_MODE = 110
|
||||||
const val ERROR_LOGIN_METHOD_NOT_SATISFIED = 111
|
const val ERROR_LOGIN_METHOD_NOT_SATISFIED = 111
|
||||||
const val ERROR_NOT_IMPLEMENTED = 112
|
const val ERROR_NOT_IMPLEMENTED = 112
|
||||||
@ -58,6 +61,9 @@ const val ERROR_FILE_DOWNLOAD = 113
|
|||||||
|
|
||||||
const val ERROR_NO_STUDENTS_IN_ACCOUNT = 115
|
const val ERROR_NO_STUDENTS_IN_ACCOUNT = 115
|
||||||
|
|
||||||
|
const val ERROR_CAPTCHA_NEEDED = 3000
|
||||||
|
const val ERROR_CAPTCHA_LIBRUS_PORTAL = 3001
|
||||||
|
|
||||||
const val CODE_INTERNAL_LIBRUS_ACCOUNT_410 = 120
|
const val CODE_INTERNAL_LIBRUS_ACCOUNT_410 = 120
|
||||||
const val CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED = 121
|
const val CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED = 121
|
||||||
const val ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED = 124
|
const val ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED = 124
|
||||||
@ -115,6 +121,11 @@ const val ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN = 179
|
|||||||
const val ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN = 180
|
const val ERROR_LOGIN_LIBRUS_PORTAL_INVALID_LOGIN = 180
|
||||||
const val ERROR_LIBRUS_API_MAINTENANCE = 181
|
const val ERROR_LIBRUS_API_MAINTENANCE = 181
|
||||||
const val ERROR_LIBRUS_PORTAL_MAINTENANCE = 182
|
const val ERROR_LIBRUS_PORTAL_MAINTENANCE = 182
|
||||||
|
const val ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM = 183
|
||||||
|
const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED = 184
|
||||||
|
const val ERROR_LIBRUS_API_DEVICE_REGISTERED = 185
|
||||||
|
const val ERROR_LIBRUS_MESSAGES_NOT_FOUND = 186
|
||||||
|
const val ERROR_LOGIN_LIBRUS_API_INVALID_REQUEST = 187
|
||||||
|
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_INVALID_LOGIN = 201
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_OLD_PASSWORD = 202
|
||||||
@ -129,6 +140,9 @@ const val ERROR_MOBIDZIENNIK_WEB_NO_SESSION_VALUE = 216
|
|||||||
const val ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID = 213
|
const val ERROR_MOBIDZIENNIK_WEB_NO_SERVER_ID = 213
|
||||||
const val ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE = 214
|
const val ERROR_MOBIDZIENNIK_WEB_INVALID_RESPONSE = 214
|
||||||
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID = 215
|
const val ERROR_LOGIN_MOBIDZIENNIK_WEB_NO_SESSION_ID = 215
|
||||||
|
const val ERROR_LOGIN_MOBIDZIENNIK_API2_INVALID_LOGIN = 216
|
||||||
|
const val ERROR_LOGIN_MOBIDZIENNIK_API2_OTHER = 217
|
||||||
|
const val ERROR_MOBIDZIENNIK_WEB_SERVER_PROBLEM = 218
|
||||||
|
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
const val ERROR_LOGIN_VULCAN_INVALID_SYMBOL = 301
|
||||||
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
const val ERROR_LOGIN_VULCAN_INVALID_TOKEN = 302
|
||||||
|
@ -41,6 +41,7 @@ internal const val FEATURE_PUSH_CONFIG = 120
|
|||||||
object Features {
|
object Features {
|
||||||
private fun getAllNecessary(): List<Int> = listOf(
|
private fun getAllNecessary(): List<Int> = listOf(
|
||||||
FEATURE_ALWAYS_NEEDED,
|
FEATURE_ALWAYS_NEEDED,
|
||||||
|
FEATURE_PUSH_CONFIG,
|
||||||
FEATURE_STUDENT_INFO,
|
FEATURE_STUDENT_INFO,
|
||||||
FEATURE_STUDENT_NUMBER,
|
FEATURE_STUDENT_NUMBER,
|
||||||
FEATURE_SCHOOL_INFO,
|
FEATURE_SCHOOL_INFO,
|
||||||
|
@ -11,6 +11,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginSynergia
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginSynergia
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginApi2
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.login.MobidziennikLoginWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.template.login.TemplateLoginWeb
|
||||||
@ -86,11 +87,11 @@ const val LOGIN_METHOD_MOBIDZIENNIK_API2 = 300
|
|||||||
val mobidziennikLoginMethods = listOf(
|
val mobidziennikLoginMethods = listOf(
|
||||||
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_WEB, MobidziennikLoginWeb::class.java)
|
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_WEB, MobidziennikLoginWeb::class.java)
|
||||||
.withIsPossible { _, _ -> true }
|
.withIsPossible { _, _ -> true }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }/*,
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
||||||
|
|
||||||
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_API2, MobidziennikLoginApi2::class.java)
|
LoginMethod(LOGIN_TYPE_MOBIDZIENNIK, LOGIN_METHOD_MOBIDZIENNIK_API2, MobidziennikLoginApi2::class.java)
|
||||||
.withIsPossible { _, loginStore -> loginStore.hasLoginData("email") }
|
.withIsPossible { profile, _ -> profile?.getStudentData("email", null) != null }
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }*/
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
)
|
)
|
||||||
|
|
||||||
const val LOGIN_TYPE_VULCAN = 4
|
const val LOGIN_TYPE_VULCAN = 4
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api
|
||||||
|
|
||||||
import kotlin.text.RegexOption.DOT_MATCHES_ALL
|
import kotlin.text.RegexOption.DOT_MATCHES_ALL
|
||||||
|
import kotlin.text.RegexOption.IGNORE_CASE
|
||||||
|
|
||||||
object Regexes {
|
object Regexes {
|
||||||
val STYLE_CSS_COLOR by lazy {
|
val STYLE_CSS_COLOR by lazy {
|
||||||
@ -54,9 +55,33 @@ object Regexes {
|
|||||||
val MOBIDZIENNIK_MESSAGE_ATTACHMENT by lazy {
|
val MOBIDZIENNIK_MESSAGE_ATTACHMENT by lazy {
|
||||||
"""href="https://.+?\.mobidziennik.pl/.+?&(?:amp;)?zalacznik=([0-9]+)"(?:.+?<small.+?\(([0-9.]+)\s(M|K|G|)B\))*""".toRegex(DOT_MATCHES_ALL)
|
"""href="https://.+?\.mobidziennik.pl/.+?&(?:amp;)?zalacznik=([0-9]+)"(?:.+?<small.+?\(([0-9.]+)\s(M|K|G|)B\))*""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
val MOBIDZIENNIK_MESSAGE_SENT_READ_BY by lazy {
|
||||||
|
"""([0-9]+)/([0-9]+)""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
val MOBIDZIENNIK_MESSAGE_RECIPIENTS_JSON by lazy {
|
val MOBIDZIENNIK_MESSAGE_RECIPIENTS_JSON by lazy {
|
||||||
"""odbiorcy: (\[.+?\]),${'$'}""".toRegex(RegexOption.MULTILINE)
|
"""odbiorcy: (\[.+?]),${'$'}""".toRegex(RegexOption.MULTILINE)
|
||||||
|
}
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_ACCOUNT_EMAIL by lazy {
|
||||||
|
"""name="email" value="(.+?@.+?\..+?)"""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_TABLE by lazy {
|
||||||
|
"""<table .+?id="obecnosci_tabela">(.+?)</table>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_LESSON_COUNT by lazy {
|
||||||
|
"""rel="([0-9-]{10})" colspan="([0-9]+)"""".toRegex()
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_ENTRIES by lazy {
|
||||||
|
"""font-size:.+?class=".*?">(.*?)</td>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_RANGE by lazy {
|
||||||
|
"""<span>([0-9:]+) - .+? (.+?)</span></a>""".toRegex(DOT_MATCHES_ALL)
|
||||||
|
}
|
||||||
|
val MOBIDZIENNIK_ATTENDANCE_LESSON by lazy {
|
||||||
|
"""<strong>(.+?) - (.*?)</strong>.+?<small>.+?\((.+?), .+?(.+?)\)""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -74,7 +99,7 @@ object Regexes {
|
|||||||
"""id="ctl00_CzyRodzic" value="([01])" />""".toRegex()
|
"""id="ctl00_CzyRodzic" value="([01])" />""".toRegex()
|
||||||
}
|
}
|
||||||
val IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR by lazy {
|
val IDZIENNIK_LOGIN_FIRST_SCHOOL_YEAR by lazy {
|
||||||
"""name="ctl00\\${'$'}dxComboRokSzkolny".+?selected="selected".*?value="([0-9]+)">([0-9]+)/([0-9]+)<""".toRegex(DOT_MATCHES_ALL)
|
"""name="ctl00\${"$"}dxComboRokSzkolny".+?selected="selected".*?value="([0-9]+)">([0-9]+)/([0-9]+)<""".toRegex(DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
val IDZIENNIK_LOGIN_FIRST_STUDENT_SELECT by lazy {
|
val IDZIENNIK_LOGIN_FIRST_STUDENT_SELECT by lazy {
|
||||||
"""<select.*?name="ctl00\${"$"}dxComboUczniowie".*?</select>""".toRegex(DOT_MATCHES_ALL)
|
"""<select.*?name="ctl00\${"$"}dxComboUczniowie".*?</select>""".toRegex(DOT_MATCHES_ALL)
|
||||||
@ -85,6 +110,13 @@ object Regexes {
|
|||||||
val IDZIENNIK_MESSAGES_RECIPIENT_PARENT by lazy {
|
val IDZIENNIK_MESSAGES_RECIPIENT_PARENT by lazy {
|
||||||
"""(.+?)\s\((.+)\)""".toRegex()
|
"""(.+?)\s\((.+)\)""".toRegex()
|
||||||
}
|
}
|
||||||
|
/*<span id="ctl00_spanSzczesliwyLos">Szczęśliwy los na dzisiaj to <b>19</b>. Los na jutro to <b>22</b></span>*/
|
||||||
|
val IDZIENNIK_WEB_LUCKY_NUMBER by lazy {
|
||||||
|
"""dzisiaj to <b>([0-9]+)</b>""".toRegex()
|
||||||
|
}
|
||||||
|
val IDZIENNIK_WEB_SELECTED_REGISTER by lazy {
|
||||||
|
"""selected="selected" value="([0-9]+)" data-id-ucznia""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -95,7 +127,7 @@ object Regexes {
|
|||||||
|
|
||||||
|
|
||||||
val LIBRUS_ATTACHMENT_KEY by lazy {
|
val LIBRUS_ATTACHMENT_KEY by lazy {
|
||||||
"""singleUseKey=([0-9A-f_]+)""".toRegex()
|
"""singleUseKey=([0-9A-z_]+)""".toRegex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -168,4 +200,20 @@ object Regexes {
|
|||||||
val EDUDZIENNIK_TEACHERS by lazy {
|
val EDUDZIENNIK_TEACHERS by lazy {
|
||||||
"""<div class="teacher">.*?<p>(.+?) (.+?)</p>""".toRegex(DOT_MATCHES_ALL)
|
"""<div class="teacher">.*?<p>(.+?) (.+?)</p>""".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()
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_DMY by lazy {
|
||||||
|
"""(?<![\d\-./])([1-2]\d|3[0-1]|0?\d)[\-./](1[0-2]|0?\d)(?:[\-./](1\d{3}|2?0?\d{2}))?(?![\d\-/])""".toRegex()
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_ABSOLUTE by lazy {
|
||||||
|
"""([1-3][0-9]|[1-9])\s(sty|lut|mar|kwi|maj|cze|lip|sie|wrz|paź|lis|gru).*?\s(1[0-9]{3}|20[0-9]{2})?""".toRegex(IGNORE_CASE)
|
||||||
|
}
|
||||||
|
val LINKIFY_DATE_RELATIVE by lazy {
|
||||||
|
"""za\s([0-9]+)?\s?(dni|dzień|tydzień|tygodnie)""".toRegex(IGNORE_CASE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.task
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2020-1-16.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
@ -12,11 +16,13 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.template.Template
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
import pl.szczodrzynski.edziennik.data.api.edziennik.vulcan.Vulcan
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.task.IApiTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
|
|
||||||
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTask(profileId) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -24,7 +30,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
|
|
||||||
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
fun firstLogin(loginStore: LoginStore) = EdziennikTask(-1, FirstLoginRequest(loginStore))
|
||||||
fun sync() = EdziennikTask(-1, SyncRequest())
|
fun sync() = EdziennikTask(-1, SyncRequest())
|
||||||
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, arguments))
|
fun syncProfile(profileId: Int, viewIds: List<Pair<Int, Int>>? = null, onlyEndpoints: List<Int>? = null, arguments: JsonObject? = null) = EdziennikTask(profileId, SyncProfileRequest(viewIds, onlyEndpoints, arguments))
|
||||||
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
fun syncProfileList(profileList: List<Int>) = EdziennikTask(-1, SyncProfileListRequest(profileList))
|
||||||
fun messageGet(profileId: Int, message: MessageFull) = EdziennikTask(profileId, MessageGetRequest(message))
|
fun messageGet(profileId: Int, message: MessageFull) = EdziennikTask(profileId, MessageGetRequest(message))
|
||||||
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
fun messageSend(profileId: Int, recipients: List<Teacher>, subject: String, text: String) = EdziennikTask(profileId, MessageSendRequest(recipients, subject, text))
|
||||||
@ -57,6 +63,10 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
private var edziennikInterface: EdziennikInterface? = null
|
private var edziennikInterface: EdziennikInterface? = null
|
||||||
|
|
||||||
internal fun run(app: App, taskCallback: EdziennikCallback) {
|
internal fun run(app: App, taskCallback: EdziennikCallback) {
|
||||||
|
if (profile?.archived == true) {
|
||||||
|
taskCallback.onError(ApiError(TAG, ERROR_PROFILE_ARCHIVED))
|
||||||
|
return
|
||||||
|
}
|
||||||
edziennikInterface = when (loginStore.type) {
|
edziennikInterface = when (loginStore.type) {
|
||||||
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
||||||
@ -75,6 +85,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) }
|
featureIds = request.viewIds?.flatMap { Features.getIdsByView(it.first, it.second) }
|
||||||
?: Features.getAllIds(),
|
?: Features.getAllIds(),
|
||||||
viewId = request.viewIds?.get(0)?.first,
|
viewId = request.viewIds?.get(0)?.first,
|
||||||
|
onlyEndpoints = request.onlyEndpoints,
|
||||||
arguments = request.arguments)
|
arguments = request.arguments)
|
||||||
is MessageGetRequest -> edziennikInterface?.getMessage(request.message)
|
is MessageGetRequest -> edziennikInterface?.getMessage(request.message)
|
||||||
is MessageSendRequest -> edziennikInterface?.sendMessage(request.recipients, request.subject, request.text)
|
is MessageSendRequest -> edziennikInterface?.sendMessage(request.recipients, request.subject, request.text)
|
||||||
@ -96,7 +107,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
|
|
||||||
data class FirstLoginRequest(val loginStore: LoginStore)
|
data class FirstLoginRequest(val loginStore: LoginStore)
|
||||||
class SyncRequest
|
class SyncRequest
|
||||||
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val arguments: JsonObject? = null)
|
data class SyncProfileRequest(val viewIds: List<Pair<Int, Int>>? = null, val onlyEndpoints: List<Int>? = null, val arguments: JsonObject? = null)
|
||||||
data class SyncProfileListRequest(val profileList: List<Int>)
|
data class SyncProfileListRequest(val profileList: List<Int>)
|
||||||
data class MessageGetRequest(val message: MessageFull)
|
data class MessageGetRequest(val message: MessageFull)
|
||||||
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
data class MessageSendRequest(val recipients: List<Teacher>, val subject: String, val text: String)
|
@ -7,11 +7,7 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Subject
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
||||||
|
@ -15,12 +15,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.Edudzienn
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -41,9 +41,7 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -54,9 +52,9 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId)
|
data.prepare(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,60 +27,62 @@ class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useEndpoint(data.targetEndpointIds.removeAt(0)) {
|
val id = data.targetEndpointIds.firstKey()
|
||||||
|
val lastSync = data.targetEndpointIds.remove(id)
|
||||||
|
useEndpoint(id, lastSync) { endpointId ->
|
||||||
data.progress(data.progressStep)
|
data.progress(data.progressStep)
|
||||||
nextEndpoint(onSuccess)
|
nextEndpoint(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_START -> {
|
ENDPOINT_EDUDZIENNIK_WEB_START -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_data)
|
data.startProgress(R.string.edziennik_progress_endpoint_data)
|
||||||
EdudziennikWebStart(data, onSuccess)
|
EdudziennikWebStart(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
||||||
EdudziennikWebTeachers(data, onSuccess)
|
EdudziennikWebTeachers(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
|
ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
EdudziennikWebGrades(data, onSuccess)
|
EdudziennikWebGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
|
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
||||||
EdudziennikWebTimetable(data, onSuccess)
|
EdudziennikWebTimetable(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
||||||
EdudziennikWebExams(data, onSuccess)
|
EdudziennikWebExams(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
|
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
EdudziennikWebAttendance(data, onSuccess)
|
EdudziennikWebAttendance(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
||||||
EdudziennikWebAnnouncements(data, onSuccess)
|
EdudziennikWebAnnouncements(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
|
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
EdudziennikWebHomework(data, onSuccess)
|
EdudziennikWebHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
|
ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
||||||
EdudziennikWebEvents(data, onSuccess)
|
EdudziennikWebEvents(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
|
ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
EdudziennikWebNotes(data, onSuccess)
|
EdudziennikWebNotes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
|
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
EdudziennikWebLuckyNumber(data, onSuccess)
|
EdudziennikWebLuckyNumber(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
else -> onSuccess()
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.*
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
open class EdudziennikWeb(open val data: DataEdudziennik) {
|
open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWeb"
|
private const val TAG = "EdudziennikWeb"
|
||||||
}
|
}
|
||||||
@ -24,11 +25,11 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
val profile
|
val profile
|
||||||
get() = data.profile
|
get() = data.profile
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, xhr: Boolean = false, onSuccess: (text: String) -> Unit) {
|
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()) {
|
val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) {
|
||||||
true -> endpoint
|
true -> endpoint
|
||||||
else -> "$endpoint/"
|
else -> "$endpoint/"
|
||||||
}
|
} + (semester?.let { "?semester=" + if(it == -1) "all" else it } ?: "")
|
||||||
|
|
||||||
d(tag, "Request: Edudziennik/Web - $url")
|
d(tag, "Request: Edudziennik/Web - $url")
|
||||||
|
|
||||||
@ -40,6 +41,18 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (semester == null && url.contains("start")) {
|
||||||
|
profile?.also { profile ->
|
||||||
|
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
||||||
|
val semesterCookie = cookies.firstOrNull { it.name() == "semester" }?.value()?.toIntOrNull()
|
||||||
|
|
||||||
|
semesterCookie?.let { data.currentSemester = it }
|
||||||
|
|
||||||
|
if (semesterCookie == 2 && profile.dateSemester2Start > Date.getToday())
|
||||||
|
profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
onSuccess(text)
|
onSuccess(text)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -67,11 +80,6 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
.name("sessionid")
|
.name("sessionid")
|
||||||
.value(data.webSessionId!!)
|
.value(data.webSessionId!!)
|
||||||
.domain("dziennikel.appspot.com")
|
.domain("dziennikel.appspot.com")
|
||||||
.secure().httpOnly().build(),
|
|
||||||
Cookie.Builder()
|
|
||||||
.name("semester")
|
|
||||||
.value((data.currentSemester).toString())
|
|
||||||
.domain("dziennikel.appspot.com")
|
|
||||||
.secure().httpOnly().build()
|
.secure().httpOnly().build()
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -11,13 +11,15 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
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.Announcement
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebAnnouncements"
|
const val TAG = "EdudziennikWebAnnouncements"
|
||||||
}
|
}
|
||||||
@ -66,7 +68,7 @@ class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) }
|
||||||
}
|
}
|
||||||
|
@ -11,22 +11,31 @@ 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.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE
|
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.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.singleOrNull
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebAttendance"
|
private const val TAG = "EdudziennikWebAttendance"
|
||||||
}
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
private var requestSemester: Int? = null
|
||||||
webGet(TAG, data.studentEndpoint + "Presence") { text ->
|
|
||||||
|
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 attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
|
||||||
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
|
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
|
||||||
@ -69,7 +78,7 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
|||||||
id,
|
id,
|
||||||
lesson?.displayTeacherId ?: -1,
|
lesson?.displayTeacherId ?: -1,
|
||||||
lesson?.displaySubjectId ?: -1,
|
lesson?.displaySubjectId ?: -1,
|
||||||
data.currentSemester,
|
profile.currentSemester,
|
||||||
name,
|
name,
|
||||||
date,
|
date,
|
||||||
lesson?.displayStartTime ?: startTime,
|
lesson?.displayStartTime ?: startTime,
|
||||||
@ -77,18 +86,25 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
|||||||
)
|
)
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
data.metadataList.add(Metadata(
|
if(type != Attendance.TYPE_PRESENT) {
|
||||||
profileId,
|
data.metadataList.add(Metadata(
|
||||||
Metadata.TYPE_ATTENDANCE,
|
profileId,
|
||||||
id,
|
Metadata.TYPE_ATTENDANCE,
|
||||||
profile.empty,
|
id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
System.currentTimeMillis()
|
profile.empty,
|
||||||
))
|
System.currentTimeMillis()
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
||||||
onSuccess()
|
requestSemester = null
|
||||||
|
getAttendances()
|
||||||
|
} else {
|
||||||
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
||||||
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) }
|
||||||
}
|
}
|
||||||
|
@ -11,14 +11,16 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_EVENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebEvents(override val data: DataEdudziennik,
|
class EdudziennikWebEvents(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebEvents"
|
const val TAG = "EdudziennikWebEvents"
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ class EdudziennikWebEvents(override val data: DataEdudziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) }
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,16 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebExams(override val data: DataEdudziennik,
|
class EdudziennikWebExams(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebExams"
|
const val TAG = "EdudziennikWebExams"
|
||||||
}
|
}
|
||||||
@ -60,7 +62,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
startTime,
|
startTime,
|
||||||
topic,
|
topic,
|
||||||
-1,
|
-1,
|
||||||
eventType.id.toInt(),
|
eventType.id,
|
||||||
false,
|
false,
|
||||||
-1,
|
-1,
|
||||||
subject.id,
|
subject.id,
|
||||||
@ -84,7 +86,7 @@ class EdudziennikWebExams(override val data: DataEdudziennik,
|
|||||||
)))
|
)))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EXAMS)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,10 @@ import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
|
|||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebGetAnnouncement(
|
class EdudziennikWebGetAnnouncement(override val data: DataEdudziennik,
|
||||||
override val data: DataEdudziennik,
|
private val announcement: AnnouncementFull,
|
||||||
private val announcement: AnnouncementFull,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : EdudziennikWeb(data, null) {
|
||||||
) : EdudziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebGetAnnouncement"
|
const val TAG = "EdudziennikWebGetAnnouncement"
|
||||||
}
|
}
|
||||||
|
@ -13,24 +13,39 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_GRADES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
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.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebGrades(override val data: DataEdudziennik,
|
class EdudziennikWebGrades(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebGrades"
|
private const val TAG = "EdudziennikWebGrades"
|
||||||
}
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
private var requestSemester: Int? = null
|
||||||
webGet(TAG, data.studentEndpoint + "start") { text ->
|
|
||||||
val doc = Jsoup.parse(text)
|
|
||||||
|
|
||||||
|
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()
|
val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
|
||||||
|
|
||||||
subjects?.forEach { subjectElement ->
|
subjects?.forEach { subjectElement ->
|
||||||
@ -80,7 +95,7 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
val columnName = info.child(4).text().trim()
|
val columnName = info.child(4).text().trim()
|
||||||
val comment = info.ownText()
|
val comment = info.ownText()
|
||||||
|
|
||||||
val description = columnName + if (comment.isNotBlank()) " - $comment" else ""
|
val description = columnName + if (comment.isNotBlank()) " - $comment" else null
|
||||||
|
|
||||||
val teacherName = info.child(1).text()
|
val teacherName = info.child(1).text()
|
||||||
val teacher = data.getTeacherByLastFirst(teacherName)
|
val teacher = data.getTeacherByLastFirst(teacherName)
|
||||||
@ -99,20 +114,20 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
fullName,
|
name = name,
|
||||||
color,
|
type = gradeType,
|
||||||
description,
|
value = value,
|
||||||
name,
|
weight = if (gradeCountToAverage) weight else 0f,
|
||||||
value,
|
color = color,
|
||||||
if (gradeCountToAverage) weight else 0f,
|
category = fullName,
|
||||||
data.currentSemester,
|
description = description,
|
||||||
teacher.id,
|
comment = null,
|
||||||
subject.id
|
semester = semester,
|
||||||
).apply {
|
teacherId = teacher.id,
|
||||||
type = gradeType
|
subjectId = subject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -129,23 +144,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
if (proposed != null && proposed.isNotBlank()) {
|
if (proposed != null && proposed.isNotBlank()) {
|
||||||
val proposedGradeObject = Grade(
|
val proposedGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
(-1 * subject.id) - 1,
|
id = (-1 * subject.id) - 1,
|
||||||
"",
|
name = proposed,
|
||||||
-1,
|
type = when (semester) {
|
||||||
"",
|
1 -> TYPE_SEMESTER1_PROPOSED
|
||||||
proposed,
|
else -> TYPE_SEMESTER2_PROPOSED
|
||||||
proposed.toFloatOrNull() ?: 0f,
|
},
|
||||||
0f,
|
value = proposed.toFloatOrNull() ?: 0f,
|
||||||
data.currentSemester,
|
weight = 0f,
|
||||||
-1,
|
color = -1,
|
||||||
subject.id
|
category = null,
|
||||||
).apply {
|
description = null,
|
||||||
type = when (semester) {
|
comment = null,
|
||||||
1 -> TYPE_SEMESTER1_PROPOSED
|
semester = semester,
|
||||||
else -> TYPE_SEMESTER2_PROPOSED
|
teacherId = -1,
|
||||||
}
|
subjectId = subject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(proposedGradeObject)
|
data.gradeList.add(proposedGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -162,23 +177,23 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
if (final != null && final.isNotBlank()) {
|
if (final != null && final.isNotBlank()) {
|
||||||
val finalGradeObject = Grade(
|
val finalGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
(-1 * subject.id) - 2,
|
id = (-1 * subject.id) - 2,
|
||||||
"",
|
name = final,
|
||||||
-1,
|
type = when (semester) {
|
||||||
"",
|
1 -> TYPE_SEMESTER1_FINAL
|
||||||
final,
|
else -> TYPE_SEMESTER2_FINAL
|
||||||
final.toFloatOrNull() ?: 0f,
|
},
|
||||||
0f,
|
value = final.toFloatOrNull() ?: 0f,
|
||||||
data.currentSemester,
|
weight = 0f,
|
||||||
-1,
|
color = -1,
|
||||||
subject.id
|
category = null,
|
||||||
).apply {
|
description = null,
|
||||||
type = when (semester) {
|
comment = null,
|
||||||
1 -> TYPE_SEMESTER1_FINAL
|
semester = semester,
|
||||||
else -> TYPE_SEMESTER2_FINAL
|
teacherId = -1,
|
||||||
}
|
subjectId = subject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(finalGradeObject)
|
data.gradeList.add(finalGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -201,12 +216,17 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|||||||
TYPE_SEMESTER1_FINAL,
|
TYPE_SEMESTER1_FINAL,
|
||||||
TYPE_SEMESTER2_FINAL
|
TYPE_SEMESTER2_FINAL
|
||||||
).map {
|
).map {
|
||||||
DataRemoveModel.Grades.semesterWithType(data.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(semester, it)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
||||||
onSuccess()
|
requestSemester = null
|
||||||
|
getGrades()
|
||||||
|
} else {
|
||||||
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
||||||
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,16 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebHomework(override val data: DataEdudziennik,
|
class EdudziennikWebHomework(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebHomework"
|
const val TAG = "EdudziennikWebHomework"
|
||||||
}
|
}
|
||||||
@ -78,7 +80,7 @@ class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) }
|
||||||
}
|
}
|
||||||
|
@ -7,13 +7,15 @@ 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.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER
|
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.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebLuckyNumber"
|
private const val TAG = "EdudziennikWebLuckyNumber"
|
||||||
}
|
}
|
||||||
@ -39,7 +41,7 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) }
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,16 @@ 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.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES
|
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.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebNotes(override val data: DataEdudziennik,
|
class EdudziennikWebNotes(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "EdudziennikWebNotes"
|
const val TAG = "EdudziennikWebNotes"
|
||||||
}
|
}
|
||||||
@ -42,7 +44,7 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
|
|||||||
profileId,
|
profileId,
|
||||||
id,
|
id,
|
||||||
description,
|
description,
|
||||||
data.currentSemester,
|
profile.currentSemester,
|
||||||
Notice.TYPE_NEUTRAL,
|
Notice.TYPE_NEUTRAL,
|
||||||
teacher.id
|
teacher.id
|
||||||
)
|
)
|
||||||
@ -59,7 +61,7 @@ class EdudziennikWebNotes(override val data: DataEdudziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) }
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,9 @@ import pl.szczodrzynski.edziennik.firstLettersName
|
|||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebStart(override val data: DataEdudziennik,
|
class EdudziennikWebStart(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebStart"
|
private const val TAG = "EdudziennikWebStart"
|
||||||
}
|
}
|
||||||
@ -29,7 +31,7 @@ class EdudziennikWebStart(override val data: DataEdudziennik,
|
|||||||
getSubjects(text)
|
getSubjects(text)
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_START)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.Edudzienni
|
|||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
|
||||||
class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebTeachers"
|
private const val TAG = "EdudziennikWebTeachers"
|
||||||
}
|
}
|
||||||
@ -26,7 +28,7 @@ class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,10 @@ 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.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.singleOrNull
|
import pl.szczodrzynski.edziennik.singleOrNull
|
||||||
@ -24,7 +24,9 @@ import pl.szczodrzynski.edziennik.utils.models.Time
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : EdudziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "EdudziennikWebTimetable"
|
private const val TAG = "EdudziennikWebTimetable"
|
||||||
}
|
}
|
||||||
@ -142,7 +144,7 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) }
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit
|
|||||||
private const val TAG = "EdudziennikFirstLogin"
|
private const val TAG = "EdudziennikFirstLogin"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val web = EdudziennikWeb(data)
|
private val web = EdudziennikWeb(data, null)
|
||||||
private val profileList = mutableListOf<Profile>()
|
private val profileList = mutableListOf<Profile>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -13,7 +13,6 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|||||||
import pl.szczodrzynski.edziennik.getUnixDate
|
import pl.szczodrzynski.edziennik.getUnixDate
|
||||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -62,7 +61,6 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
|||||||
|
|
||||||
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
val cookies = data.app.cookieJar.getForDomain("dziennikel.appspot.com")
|
||||||
val sessionId = cookies.firstOrNull { it.name() == "sessionid" }?.value()
|
val sessionId = cookies.firstOrNull { it.name() == "sessionid" }?.value()
|
||||||
val semester = cookies.firstOrNull { it.name() == "semester" }?.value()?.toIntOrNull()
|
|
||||||
|
|
||||||
if (sessionId == null) {
|
if (sessionId == null) {
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
||||||
@ -72,14 +70,6 @@ class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.webSessionId = sessionId
|
data.webSessionId = sessionId
|
||||||
|
|
||||||
if (data.profile != null && semester != null) {
|
|
||||||
data.currentSemester = semester
|
|
||||||
|
|
||||||
if (semester == 2 && data.profile.dateSemester2Start > Date.getToday())
|
|
||||||
data.profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
|
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
|
@ -81,6 +81,11 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
|
|||||||
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
||||||
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
||||||
|
|
||||||
|
private var mWebSelectedRegister: Int? = null
|
||||||
|
var webSelectedRegister: Int
|
||||||
|
get() { mWebSelectedRegister = mWebSelectedRegister ?: loginStore.getLoginData("webSelectedRegister", 0); return mWebSelectedRegister ?: 0 }
|
||||||
|
set(value) { loginStore.putLoginData("webSelectedRegister", value); mWebSelectedRegister = value }
|
||||||
|
|
||||||
/* _
|
/* _
|
||||||
/\ (_)
|
/\ (_)
|
||||||
/ \ _ __ _
|
/ \ _ __ _
|
||||||
|
@ -17,12 +17,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLo
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -43,9 +43,7 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -56,9 +54,9 @@ class Idziennik(val app: App, val profile: Profile?, val loginStore: LoginStore,
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId)
|
data.prepare(idziennikLoginMethods, IdziennikFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import pl.szczodrzynski.edziennik.getString
|
|||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
|
|
||||||
open class IdziennikApi(open val data: DataIdziennik) {
|
open class IdziennikApi(open val data: DataIdziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikApi"
|
const val TAG = "IdziennikApi"
|
||||||
}
|
}
|
||||||
|
@ -30,60 +30,62 @@ class IdziennikData(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useEndpoint(data.targetEndpointIds.removeAt(0)) {
|
val id = data.targetEndpointIds.firstKey()
|
||||||
|
val lastSync = data.targetEndpointIds.remove(id)
|
||||||
|
useEndpoint(id, lastSync) { endpointId ->
|
||||||
data.progress(data.progressStep)
|
data.progress(data.progressStep)
|
||||||
nextEndpoint(onSuccess)
|
nextEndpoint(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
|
ENDPOINT_IDZIENNIK_WEB_TIMETABLE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
||||||
IdziennikWebTimetable(data, onSuccess)
|
IdziennikWebTimetable(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_GRADES -> {
|
ENDPOINT_IDZIENNIK_WEB_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
IdziennikWebGrades(data, onSuccess)
|
IdziennikWebGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES -> {
|
ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_proposed_grades)
|
||||||
IdziennikWebProposedGrades(data, onSuccess)
|
IdziennikWebProposedGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_EXAMS -> {
|
ENDPOINT_IDZIENNIK_WEB_EXAMS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
||||||
IdziennikWebExams(data, onSuccess)
|
IdziennikWebExams(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_HOMEWORK -> {
|
ENDPOINT_IDZIENNIK_WEB_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
IdziennikWebHomework(data, onSuccess)
|
IdziennikWebHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_NOTICES -> {
|
ENDPOINT_IDZIENNIK_WEB_NOTICES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
IdziennikWebNotices(data, onSuccess)
|
IdziennikWebNotices(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
||||||
IdziennikWebAnnouncements(data, onSuccess)
|
IdziennikWebAnnouncements(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_WEB_ATTENDANCE -> {
|
ENDPOINT_IDZIENNIK_WEB_ATTENDANCE -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
IdziennikWebAttendance(data, onSuccess)
|
IdziennikWebAttendance(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER -> {
|
ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
IdziennikApiCurrentRegister(data, onSuccess)
|
IdziennikApiCurrentRegister(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX -> {
|
ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
||||||
IdziennikApiMessagesInbox(data, onSuccess)
|
IdziennikApiMessagesInbox(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT -> {
|
ENDPOINT_IDZIENNIK_API_MESSAGES_SENT -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
||||||
IdziennikApiMessagesSent(data, onSuccess)
|
IdziennikApiMessagesSent(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
else -> onSuccess()
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,14 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSwitchRegister
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
import java.net.HttpURLConnection.HTTP_INTERNAL_ERROR
|
||||||
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
import java.net.HttpURLConnection.HTTP_UNAUTHORIZED
|
||||||
|
|
||||||
open class IdziennikWeb(open val data: DataIdziennik) {
|
open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWeb"
|
const val TAG = "IdziennikWeb"
|
||||||
}
|
}
|
||||||
@ -48,6 +49,17 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response?.code() == HTTP_INTERNAL_ERROR && endpoint == IDZIENNIK_WEB_GRADES) {
|
||||||
|
// special override for accounts where displaying grades
|
||||||
|
// for another student requires switching it manually
|
||||||
|
if (data.registerId != data.webSelectedRegister) {
|
||||||
|
IdziennikWebSwitchRegister(data, data.registerId) {
|
||||||
|
webApiGet(tag, endpoint, parameters, onSuccess)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
||||||
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
||||||
@ -115,7 +127,7 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, onSuccess: (text: String) -> Unit) {
|
fun webGet(tag: String, endpoint: String, parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) {
|
||||||
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
@ -160,7 +172,14 @@ open class IdziennikWeb(open val data: DataIdziennik) {
|
|||||||
Request.builder()
|
Request.builder()
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
.userAgent(IDZIENNIK_USER_AGENT)
|
||||||
.get()
|
.apply {
|
||||||
|
if (parameters.isEmpty()) get()
|
||||||
|
else post()
|
||||||
|
|
||||||
|
parameters.map { (name, value) ->
|
||||||
|
addParameter(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
|
@ -19,7 +19,9 @@ import pl.szczodrzynski.edziennik.utils.models.Date
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiCurrentRegister"
|
private const val TAG = "IdziennikApiCurrentRegister"
|
||||||
}
|
}
|
||||||
@ -27,7 +29,7 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_CURRENT_REGISTER) { json ->
|
apiGet(TAG, IDZIENNIK_API_CURRENT_REGISTER) { json ->
|
||||||
if (json !is JsonObject) {
|
if (json !is JsonObject) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
val luckyNumberObject = LuckyNumber(
|
||||||
data.profileId,
|
data.profileId,
|
||||||
Date.getToday(),
|
luckyNumberDate,
|
||||||
luckyNumber
|
luckyNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -85,7 +87,7 @@ class IdziennikApiCurrentRegister(override val data: DataIdziennik,
|
|||||||
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER, syncAt = nextSync)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER, syncAt = nextSync)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_CURRENT_REGISTER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,20 +10,18 @@ import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_API_MESSAGES_INBOX
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_DELETED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.MessageRecipient
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.getBoolean
|
import pl.szczodrzynski.edziennik.getBoolean
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiMessagesInbox"
|
private const val TAG = "IdziennikApiMessagesInbox"
|
||||||
}
|
}
|
||||||
@ -31,7 +29,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_INBOX) { json ->
|
apiGet(TAG, IDZIENNIK_API_MESSAGES_INBOX) { json ->
|
||||||
if (json !is JsonArray) {
|
if (json !is JsonArray) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +94,7 @@ class IdziennikApiMessagesInbox(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_INBOX)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@ import pl.szczodrzynski.edziennik.utils.Utils.crc32
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikApiMessagesSent"
|
private const val TAG = "IdziennikApiMessagesSent"
|
||||||
}
|
}
|
||||||
@ -28,7 +30,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
init {
|
init {
|
||||||
apiGet(TAG, IDZIENNIK_API_MESSAGES_SENT) { json ->
|
apiGet(TAG, IDZIENNIK_API_MESSAGES_SENT) { json ->
|
||||||
if (json !is JsonArray) {
|
if (json !is JsonArray) {
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
||||||
return@apiGet
|
return@apiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +81,7 @@ class IdziennikApiMessagesSent(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT, DAY, DRAWER_ITEM_MESSAGES)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_API_MESSAGES_SENT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,17 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.getLong
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebAnnouncements"
|
private const val TAG = "IdziennikWebAnnouncements"
|
||||||
}
|
}
|
||||||
@ -41,11 +45,11 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
|||||||
for (jAnnouncementEl in json.getAsJsonArray("ListK")) {
|
for (jAnnouncementEl in json.getAsJsonArray("ListK")) {
|
||||||
val jAnnouncement = jAnnouncementEl.asJsonObject
|
val jAnnouncement = jAnnouncementEl.asJsonObject
|
||||||
// jAnnouncement
|
// jAnnouncement
|
||||||
val announcementId = jAnnouncement.get("Id").asLong
|
val announcementId = jAnnouncement.getLong("Id") ?: -1
|
||||||
|
|
||||||
val rTeacher = data.getTeacherByFirstLast(jAnnouncement.get("Autor").asString)
|
val rTeacher = data.getTeacherByFirstLast(jAnnouncement.getString("Autor") ?: "")
|
||||||
val addedDate = java.lang.Long.parseLong(jAnnouncement.get("DataDodania").asString.replace("[^\\d]".toRegex(), ""))
|
val addedDate = jAnnouncement.getString("DataDodania")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull() ?: System.currentTimeMillis()
|
||||||
val startDate = Date.fromMillis(java.lang.Long.parseLong(jAnnouncement.get("DataWydarzenia").asString.replace("[^\\d]".toRegex(), "")))
|
val startDate = jAnnouncement.getString("DataWydarzenia")?.replace("[^\\d]".toRegex(), "")?.toLongOrNull()?.let { Date.fromMillis(it) }
|
||||||
|
|
||||||
val announcementObject = Announcement(
|
val announcementObject = Announcement(
|
||||||
profileId,
|
profileId,
|
||||||
@ -69,7 +73,7 @@ class IdziennikWebAnnouncements(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_ANNOUNCEMENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,25 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ATTENDANCE
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_ATTENDANCE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ATTENDANCE
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_ATTENDANCE
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance.*
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class IdziennikWebAttendance(override val data: DataIdziennik,
|
class IdziennikWebAttendance(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebAttendance"
|
private const val TAG = "IdziennikWebAttendance"
|
||||||
}
|
}
|
||||||
@ -137,7 +139,7 @@ class IdziennikWebAttendance(override val data: DataIdziennik,
|
|||||||
getAttendance()
|
getAttendance()
|
||||||
} else {
|
} else {
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_ATTENDANCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
class IdziennikWebExams(override val data: DataIdziennik,
|
class IdziennikWebExams(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebExams"
|
private const val TAG = "IdziennikWebExams"
|
||||||
}
|
}
|
||||||
@ -68,9 +71,12 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate)
|
val lessonList = data.db.timetableDao().getForDateNow(profileId, examDate)
|
||||||
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
val startTime = lessonList.firstOrNull { it.subjectId == subjectId }?.startTime
|
||||||
|
|
||||||
val eventType = when (exam.getString("rodzaj")) {
|
val eventType = when (exam.getString("rodzaj")?.toLowerCase(Locale.getDefault())) {
|
||||||
"sprawdzian/praca klasowa" -> Event.TYPE_EXAM
|
"sprawdzian/praca klasowa",
|
||||||
else -> Event.TYPE_SHORT_QUIZ
|
"sprawdzian",
|
||||||
|
"praca klasowa" -> Event.TYPE_EXAM
|
||||||
|
"kartkówka" -> Event.TYPE_SHORT_QUIZ
|
||||||
|
else -> Event.TYPE_EXAM
|
||||||
}
|
}
|
||||||
|
|
||||||
val eventObject = Event(
|
val eventObject = Event(
|
||||||
@ -116,7 +122,7 @@ class IdziennikWebExams(override val data: DataIdziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureExceptType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_EXAMS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,12 @@ import pl.szczodrzynski.edziennik.get
|
|||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class IdziennikWebGetAttachment(
|
class IdziennikWebGetAttachment(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik, val message: Message, val attachmentId: Long,
|
val message: Message,
|
||||||
val attachmentName: String, val onSuccess: () -> Unit
|
val attachmentId: Long,
|
||||||
) : IdziennikWeb(data) {
|
val attachmentName: String,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWebGetAttachment"
|
const val TAG = "IdziennikWebGetAttachment"
|
||||||
}
|
}
|
||||||
|
@ -12,16 +12,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|||||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_RECEIVED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
import pl.szczodrzynski.edziennik.data.db.entity.Message.TYPE_SENT
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
import pl.szczodrzynski.edziennik.data.db.full.MessageRecipientFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebGetMessage(
|
class IdziennikWebGetMessage(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik,
|
private val message: MessageFull,
|
||||||
private val message: MessageFull,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : IdziennikWeb(data, null) {
|
||||||
) : IdziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "IdziennikWebGetMessage"
|
const val TAG = "IdziennikWebGetMessage"
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,9 @@ import pl.szczodrzynski.edziennik.data.api.events.RecipientListGetEvent
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
|
||||||
class IdziennikWebGetRecipientList(
|
class IdziennikWebGetRecipientList(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik, val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebGetRecipientList"
|
private const val TAG = "IdziennikWebGetRecipientList"
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebGrades(override val data: DataIdziennik,
|
class IdziennikWebGrades(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebGrades"
|
private const val TAG = "IdziennikWebGrades"
|
||||||
}
|
}
|
||||||
@ -61,17 +64,19 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
category,
|
name = name,
|
||||||
colorInt,
|
type = TYPE_NORMAL,
|
||||||
"",
|
value = value,
|
||||||
name,
|
weight = weight,
|
||||||
value,
|
color = colorInt,
|
||||||
weight,
|
category = category,
|
||||||
semester,
|
description = null,
|
||||||
teacher.id,
|
comment = null,
|
||||||
subject.id)
|
semester = semester,
|
||||||
|
teacherId = teacher.id,
|
||||||
|
subjectId = subject.id)
|
||||||
|
|
||||||
when (grade.getInt("Typ")) {
|
when (grade.getInt("Typ")) {
|
||||||
0 -> {
|
0 -> {
|
||||||
@ -96,17 +101,19 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
val historyObject = Grade(
|
val historyObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
gradeObject.id * -1,
|
id = gradeObject.id * -1,
|
||||||
historyItem.get("Kategoria").asString,
|
name = historyItem.getString("Ocena") ?: "",
|
||||||
colorInt,
|
type = TYPE_NORMAL,
|
||||||
historyItem.get("Uzasadnienie").asString,
|
value = value,
|
||||||
historyItem.get("Ocena").asString,
|
weight = if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
||||||
value,
|
color = colorInt,
|
||||||
if (value > 0f && countToTheAverage) weight * -1f else 0f,
|
category = historyItem.getString("Kategoria"),
|
||||||
historyItem.get("Semestr").asInt,
|
description = historyItem.getString("Uzasadnienie"),
|
||||||
teacher.id,
|
comment = null,
|
||||||
subject.id)
|
semester = historyItem.getInt("Semestr") ?: 1,
|
||||||
|
teacherId = teacher.id,
|
||||||
|
subjectId = subject.id)
|
||||||
historyObject.parentId = gradeObject.id
|
historyObject.parentId = gradeObject.id
|
||||||
|
|
||||||
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
val addedDate = historyItem.getString("Data_wystaw")?.let { Date.fromY_m_d(it).inMillis } ?: System.currentTimeMillis()
|
||||||
@ -163,7 +170,7 @@ class IdziennikWebGrades(override val data: DataIdziennik,
|
|||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
||||||
})
|
})
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebHomework(override val data: DataIdziennik,
|
class IdziennikWebHomework(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebHomework"
|
private const val TAG = "IdziennikWebHomework"
|
||||||
}
|
}
|
||||||
@ -92,7 +94,7 @@ class IdziennikWebHomework(override val data: DataIdziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_HOMEWORK)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,24 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import pl.szczodrzynski.edziennik.crc16
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
import pl.szczodrzynski.edziennik.data.api.ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA
|
||||||
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_NOTICES
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_NOTICES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_NOTICES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNIK_WEB_NOTICES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.crc16
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice.*
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice.*
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikWebNotices(override val data: DataIdziennik,
|
class IdziennikWebNotices(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebNotices"
|
private const val TAG = "IdziennikWebNotices"
|
||||||
}
|
}
|
||||||
@ -69,7 +71,7 @@ class IdziennikWebNotices(override val data: DataIdziennik,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_NOTICES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_NOTICES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_NOTICES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,18 +12,20 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_SEMESTER1_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_YEAR_PROPOSED
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.getJsonArray
|
import pl.szczodrzynski.edziennik.getJsonArray
|
||||||
import pl.szczodrzynski.edziennik.getJsonObject
|
import pl.szczodrzynski.edziennik.getJsonObject
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue
|
import pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue
|
||||||
|
|
||||||
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebProposedGrades"
|
private const val TAG = "IdziennikWebProposedGrades"
|
||||||
}
|
}
|
||||||
@ -52,20 +54,20 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
|
|
||||||
if (semester1Proposed != "") {
|
if (semester1Proposed != "") {
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
semester1Id,
|
id = semester1Id,
|
||||||
"",
|
name = semester1Value.toString(),
|
||||||
-1,
|
type = TYPE_SEMESTER1_PROPOSED,
|
||||||
"",
|
value = semester1Value.toFloat(),
|
||||||
semester1Value.toString(),
|
weight = 0f,
|
||||||
semester1Value.toFloat(),
|
color = -1,
|
||||||
0f,
|
category = null,
|
||||||
1,
|
description = null,
|
||||||
-1,
|
comment = null,
|
||||||
subjectObject.id
|
semester = 1,
|
||||||
).apply {
|
teacherId = -1,
|
||||||
type = TYPE_SEMESTER1_PROPOSED
|
subjectId = subjectObject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -80,20 +82,25 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
|
|
||||||
if (semester2Proposed != "") {
|
if (semester2Proposed != "") {
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
semester2Id,
|
id = semester2Id,
|
||||||
"",
|
name = semester2Value.toString(),
|
||||||
-1,
|
type = TYPE_YEAR_PROPOSED,
|
||||||
"",
|
value = semester2Value.toFloat(),
|
||||||
semester2Value.toString(),
|
weight = 0f,
|
||||||
semester2Value.toFloat(),
|
color = -1,
|
||||||
0f,
|
category = null,
|
||||||
2,
|
description = null,
|
||||||
-1,
|
comment = null,
|
||||||
subjectObject.id
|
semester = 2,
|
||||||
).apply {
|
teacherId = -1,
|
||||||
type = TYPE_YEAR_PROPOSED
|
subjectId = subjectObject.id
|
||||||
}
|
)
|
||||||
|
|
||||||
|
val addedDate = if (data.profile.empty)
|
||||||
|
data.profile.dateSemester1Start.inMillis
|
||||||
|
else
|
||||||
|
System.currentTimeMillis()
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -102,7 +109,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
gradeObject.id,
|
gradeObject.id,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
profile.empty,
|
profile.empty,
|
||||||
System.currentTimeMillis()
|
addedDate
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +118,7 @@ class IdziennikWebProposedGrades(override val data: DataIdziennik,
|
|||||||
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
|
||||||
})
|
})
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_IDZIENNIK_WEB_PROPOSED_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,12 @@ import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class IdziennikWebSendMessage(
|
class IdziennikWebSendMessage(override val data: DataIdziennik,
|
||||||
override val data: DataIdziennik,
|
val recipients: List<Teacher>,
|
||||||
val recipients: List<Teacher>,
|
val subject: String,
|
||||||
val subject: String,
|
val text: String,
|
||||||
val text: String,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : IdziennikWeb(data, null) {
|
||||||
) : IdziennikWeb(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebSendMessage"
|
private const val TAG = "IdziennikWebSendMessage"
|
||||||
}
|
}
|
||||||
@ -57,7 +56,7 @@ class IdziennikWebSendMessage(
|
|||||||
return@webApiGet
|
return@webApiGet
|
||||||
}
|
}
|
||||||
|
|
||||||
IdziennikApiMessagesSent(data) {
|
IdziennikApiMessagesSent(data, null) {
|
||||||
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
val message = data.messageIgnoreList.firstOrNull { it.type == Message.TYPE_SENT && it.subject == subject }
|
||||||
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
val metadata = data.metadataList.firstOrNull { it.thingType == Metadata.TYPE_MESSAGE && it.thingId == message?.id }
|
||||||
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
val event = MessageSentEvent(data.profileId, message, metadata?.addedDate)
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_HOME
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
|
||||||
|
class IdziennikWebSwitchRegister(override val data: DataIdziennik,
|
||||||
|
val registerId: Int,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "IdziennikWebSwitchRegister"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val hiddenFields = data.loginStore.getLoginData("hiddenFields", JsonObject())
|
||||||
|
// TODO error checking
|
||||||
|
|
||||||
|
webGet(TAG, IDZIENNIK_WEB_HOME, mapOf(
|
||||||
|
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
||||||
|
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
||||||
|
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
||||||
|
"ctl00\$dxComboUczniowie" to registerId
|
||||||
|
)) { text ->
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,17 +13,19 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.ENDPOINT_IDZIENNI
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
|
|
||||||
class IdziennikWebTimetable(override val data: DataIdziennik,
|
class IdziennikWebTimetable(override val data: DataIdziennik,
|
||||||
val onSuccess: () -> Unit) : IdziennikWeb(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : IdziennikWeb(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "IdziennikWebTimetable"
|
private const val TAG = "IdziennikWebTimetable"
|
||||||
}
|
}
|
||||||
@ -187,7 +189,7 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
|
|||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_IDZIENNIK_WEB_TIMETABLE)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ class IdziennikFirstLogin(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
private const val TAG = "IdziennikFirstLogin"
|
private const val TAG = "IdziennikFirstLogin"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val web = IdziennikWeb(data)
|
private val web = IdziennikWeb(data, null)
|
||||||
private val profileList = mutableListOf<Profile>()
|
private val profileList = mutableListOf<Profile>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -8,14 +8,14 @@ import im.wangchao.mhttp.Request
|
|||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import okhttp3.Cookie
|
import okhttp3.Cookie
|
||||||
import pl.szczodrzynski.edziennik.HOUR
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MINUTE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.getUnixDate
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -69,6 +69,40 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
data.apiBearer = cookies.singleOrNull { it.name() == "Bearer" }?.value() ?: return@run ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER
|
||||||
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
||||||
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
||||||
|
|
||||||
|
val hiddenFields = JsonObject()
|
||||||
|
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
||||||
|
hiddenFields[it[1]] = it[2]
|
||||||
|
}
|
||||||
|
data.loginStore.putLoginData("hiddenFields", hiddenFields)
|
||||||
|
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
|
||||||
|
data.profile?.let { profile ->
|
||||||
|
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
|
||||||
|
val number = it[1].toIntOrNull() ?: return@also
|
||||||
|
val luckyNumberObject = LuckyNumber(
|
||||||
|
data.profileId,
|
||||||
|
Date.getToday(),
|
||||||
|
number
|
||||||
|
)
|
||||||
|
|
||||||
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
|
data.metadataList.add(
|
||||||
|
Metadata(
|
||||||
|
profile.id,
|
||||||
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
|
luckyNumberObject.date.value.toLong(),
|
||||||
|
true,
|
||||||
|
profile.empty,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return@run null
|
return@run null
|
||||||
}?.let { errorCode ->
|
}?.let { errorCode ->
|
||||||
data.error(ApiError(TAG, errorCode)
|
data.error(ApiError(TAG, errorCode)
|
||||||
|
@ -191,6 +191,16 @@ class DataLibrus(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
|
|||||||
get() { mApiTokenExpiryTime = mApiTokenExpiryTime ?: profile?.getStudentData("accountTokenTime", 0L); return mApiTokenExpiryTime ?: 0L }
|
get() { mApiTokenExpiryTime = mApiTokenExpiryTime ?: profile?.getStudentData("accountTokenTime", 0L); return mApiTokenExpiryTime ?: 0L }
|
||||||
set(value) { mApiTokenExpiryTime = value; profile?.putStudentData("accountTokenTime", value) ?: return; }
|
set(value) { mApiTokenExpiryTime = value; profile?.putStudentData("accountTokenTime", value) ?: return; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A push device ID, generated by Librus when registering
|
||||||
|
* a FCM token. I don't really know if this has any use,
|
||||||
|
* but it may be worthy to save that ID.
|
||||||
|
*/
|
||||||
|
private var mPushDeviceId: Int? = null
|
||||||
|
var pushDeviceId: Int
|
||||||
|
get() { mPushDeviceId = mPushDeviceId ?: profile?.getStudentData("pushDeviceId", 0); return mPushDeviceId ?: 0 }
|
||||||
|
set(value) { mPushDeviceId = value; profile?.putStudentData("pushDeviceId", value) ?: return; }
|
||||||
|
|
||||||
/* _____ _
|
/* _____ _
|
||||||
/ ____| (_)
|
/ ____| (_)
|
||||||
| (___ _ _ _ __ ___ _ __ __ _ _ __ _
|
| (___ _ _ _ __ ___ _ __ __ _ _ __ _
|
||||||
|
@ -19,12 +19,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLogin
|
|||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||||
@ -45,9 +45,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|
|
||||||
private fun completed() {
|
private fun completed() {
|
||||||
data.saveData()
|
data.saveData()
|
||||||
data.notify {
|
callback.onCompleted()
|
||||||
callback.onCompleted()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _______ _ _ _ _ _
|
/* _______ _ _ _ _ _
|
||||||
@ -58,9 +56,9 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||||
__/ |
|
__/ |
|
||||||
|__*/
|
|__*/
|
||||||
override fun sync(featureIds: List<Int>, viewId: Int?, arguments: JsonObject?) {
|
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||||
data.arguments = arguments
|
data.arguments = arguments
|
||||||
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId)
|
data.prepare(librusLoginMethods, LibrusFeatures, featureIds, viewId, onlyEndpoints)
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,6 +180,7 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
}
|
}
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE,
|
ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING,
|
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING,
|
||||||
|
ERROR_LOGIN_LIBRUS_PORTAL_CSRF_EXPIRED,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED,
|
ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED,
|
||||||
ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED -> {
|
ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED -> {
|
||||||
login()
|
login()
|
||||||
@ -200,7 +199,6 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID -> {
|
ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID -> {
|
||||||
login()
|
login()
|
||||||
}
|
}
|
||||||
// TODO PORTAL CAPTCHA
|
|
||||||
ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC -> {
|
ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC -> {
|
||||||
data.timetableNotPublic = true
|
data.timetableNotPublic = true
|
||||||
data()
|
data()
|
||||||
@ -209,6 +207,11 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va
|
|||||||
ERROR_LIBRUS_API_NOTES_NOT_ACTIVE -> {
|
ERROR_LIBRUS_API_NOTES_NOT_ACTIVE -> {
|
||||||
data()
|
data()
|
||||||
}
|
}
|
||||||
|
ERROR_LIBRUS_API_DEVICE_REGISTERED -> {
|
||||||
|
data.app.config.sync.tokenLibrusList =
|
||||||
|
data.app.config.sync.tokenLibrusList + data.profileId
|
||||||
|
data()
|
||||||
|
}
|
||||||
else -> callback.onError(apiError)
|
else -> callback.onError(apiError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,8 +53,6 @@ const val ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK = 2030
|
|||||||
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 3010
|
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 3010
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_SENT = 3020
|
const val ENDPOINT_LIBRUS_MESSAGES_SENT = 3020
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 3030
|
const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 3030
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_RECEIVERS = 3040
|
|
||||||
const val ENDPOINT_LIBRUS_MESSAGES_GET = 3040
|
|
||||||
|
|
||||||
val LibrusFeatures = listOf(
|
val LibrusFeatures = listOf(
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import pl.szczodrzynski.edziennik.getString
|
|||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import java.net.HttpURLConnection.*
|
import java.net.HttpURLConnection.*
|
||||||
|
|
||||||
open class LibrusApi(open val data: DataLibrus) {
|
open class LibrusApi(open val data: DataLibrus, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LibrusApi"
|
private const val TAG = "LibrusApi"
|
||||||
}
|
}
|
||||||
@ -44,9 +44,12 @@ open class LibrusApi(open val data: DataLibrus) {
|
|||||||
.withResponse(response))
|
.withResponse(response))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
{"Status":"Error","Code":"DeviceRegistered","Message":"This device is alerdy registered.","Resources":{"..":{"Url":"https:\/\/api.librus.pl\/2.0\/Root"}},"Url":"https:\/\/api.librus.pl\/2.0\/ChangeRegister"}*/
|
||||||
val error = if (response?.code() == 200) null else
|
val error = if (response?.code() == 200) null else
|
||||||
json.getString("Code") ?:
|
json.getString("Code") ?:
|
||||||
json.getString("Message") ?:
|
json.getString("Message") ?:
|
||||||
|
json.getString("Status") ?:
|
||||||
response?.parserErrorBody
|
response?.parserErrorBody
|
||||||
error?.let { code ->
|
error?.let { code ->
|
||||||
when (code) {
|
when (code) {
|
||||||
@ -63,6 +66,9 @@ open class LibrusApi(open val data: DataLibrus) {
|
|||||||
"NotesIsNotActive" -> ERROR_LIBRUS_API_NOTES_NOT_ACTIVE
|
"NotesIsNotActive" -> ERROR_LIBRUS_API_NOTES_NOT_ACTIVE
|
||||||
"InvalidRequest" -> ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS
|
"InvalidRequest" -> ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS
|
||||||
"Nieprawidłowy węzeł." -> ERROR_LIBRUS_API_INCORRECT_ENDPOINT
|
"Nieprawidłowy węzeł." -> ERROR_LIBRUS_API_INCORRECT_ENDPOINT
|
||||||
|
"NoticeboardProblem" -> ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM
|
||||||
|
"DeviceRegistered" -> ERROR_LIBRUS_API_DEVICE_REGISTERED
|
||||||
|
"Maintenance" -> ERROR_LIBRUS_API_MAINTENANCE
|
||||||
else -> ERROR_LIBRUS_API_OTHER
|
else -> ERROR_LIBRUS_API_OTHER
|
||||||
}.let { errorCode ->
|
}.let { errorCode ->
|
||||||
if (errorCode !in ignoreErrors) {
|
if (errorCode !in ignoreErrors) {
|
||||||
@ -114,6 +120,8 @@ open class LibrusApi(open val data: DataLibrus) {
|
|||||||
.allowErrorCode(HTTP_FORBIDDEN)
|
.allowErrorCode(HTTP_FORBIDDEN)
|
||||||
.allowErrorCode(HTTP_UNAUTHORIZED)
|
.allowErrorCode(HTTP_UNAUTHORIZED)
|
||||||
.allowErrorCode(HTTP_UNAVAILABLE)
|
.allowErrorCode(HTTP_UNAVAILABLE)
|
||||||
|
.allowErrorCode(HTTP_NOT_FOUND)
|
||||||
|
.allowErrorCode(503)
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
|
@ -31,158 +31,163 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
onSuccess()
|
onSuccess()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
useEndpoint(data.targetEndpointIds.removeAt(0)) {
|
val id = data.targetEndpointIds.firstKey()
|
||||||
|
val lastSync = data.targetEndpointIds.remove(id)
|
||||||
|
useEndpoint(id, lastSync) { endpointId ->
|
||||||
data.progress(data.progressStep)
|
data.progress(data.progressStep)
|
||||||
nextEndpoint(onSuccess)
|
nextEndpoint(onSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun useEndpoint(endpointId: Int, onSuccess: () -> Unit) {
|
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||||
Utils.d(TAG, "Using endpoint $endpointId")
|
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||||
when (endpointId) {
|
when (endpointId) {
|
||||||
/**
|
/**
|
||||||
* API
|
* API
|
||||||
*/
|
*/
|
||||||
ENDPOINT_LIBRUS_API_ME -> {
|
ENDPOINT_LIBRUS_API_ME -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
|
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
|
||||||
LibrusApiMe(data, onSuccess)
|
LibrusApiMe(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_SCHOOLS -> {
|
ENDPOINT_LIBRUS_API_SCHOOLS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_school_info)
|
data.startProgress(R.string.edziennik_progress_endpoint_school_info)
|
||||||
LibrusApiSchools(data, onSuccess)
|
LibrusApiSchools(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_CLASSES -> {
|
ENDPOINT_LIBRUS_API_CLASSES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_classes)
|
data.startProgress(R.string.edziennik_progress_endpoint_classes)
|
||||||
LibrusApiClasses(data, onSuccess)
|
LibrusApiClasses(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES -> {
|
ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teams)
|
data.startProgress(R.string.edziennik_progress_endpoint_teams)
|
||||||
LibrusApiVirtualClasses(data, onSuccess)
|
LibrusApiVirtualClasses(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_UNITS -> {
|
ENDPOINT_LIBRUS_API_UNITS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_units)
|
data.startProgress(R.string.edziennik_progress_endpoint_units)
|
||||||
LibrusApiUnits(data, onSuccess)
|
LibrusApiUnits(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_USERS -> {
|
ENDPOINT_LIBRUS_API_USERS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
||||||
LibrusApiUsers(data, onSuccess)
|
LibrusApiUsers(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_SUBJECTS -> {
|
ENDPOINT_LIBRUS_API_SUBJECTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_subjects)
|
data.startProgress(R.string.edziennik_progress_endpoint_subjects)
|
||||||
LibrusApiSubjects(data, onSuccess)
|
LibrusApiSubjects(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_CLASSROOMS -> {
|
ENDPOINT_LIBRUS_API_CLASSROOMS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_classrooms)
|
data.startProgress(R.string.edziennik_progress_endpoint_classrooms)
|
||||||
LibrusApiClassrooms(data, onSuccess)
|
LibrusApiClassrooms(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_LESSONS -> {
|
ENDPOINT_LIBRUS_API_LESSONS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lessons)
|
data.startProgress(R.string.edziennik_progress_endpoint_lessons)
|
||||||
LibrusApiLessons(data, onSuccess)
|
LibrusApiLessons(data, lastSync, onSuccess)
|
||||||
|
}
|
||||||
|
ENDPOINT_LIBRUS_API_PUSH_CONFIG -> {
|
||||||
|
data.startProgress(R.string.edziennik_progress_endpoint_push_config)
|
||||||
|
LibrusApiPushConfig(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
// TODO push config
|
|
||||||
ENDPOINT_LIBRUS_API_TIMETABLES -> {
|
ENDPOINT_LIBRUS_API_TIMETABLES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
||||||
LibrusApiTimetables(data, onSuccess)
|
LibrusApiTimetables(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES -> {
|
ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
||||||
LibrusApiGradeCategories(data, onSuccess)
|
LibrusApiGradeCategories(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES -> {
|
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
||||||
LibrusApiBehaviourGradeCategories(data, onSuccess)
|
LibrusApiBehaviourGradeCategories(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES -> {
|
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
||||||
LibrusApiDescriptiveGradeCategories(data, onSuccess)
|
LibrusApiDescriptiveGradeCategories(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_TEXT_GRADE_CATEGORIES -> {
|
ENDPOINT_LIBRUS_API_TEXT_GRADE_CATEGORIES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
||||||
LibrusApiTextGradeCategories(data, onSuccess)
|
LibrusApiTextGradeCategories(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES -> {
|
ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_categories)
|
||||||
LibrusApiPointGradeCategories(data, onSuccess)
|
LibrusApiPointGradeCategories(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS -> {
|
ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_comments)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_comments)
|
||||||
LibrusApiGradeComments(data, onSuccess)
|
LibrusApiGradeComments(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS -> {
|
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grade_comments)
|
data.startProgress(R.string.edziennik_progress_endpoint_grade_comments)
|
||||||
LibrusApiBehaviourGradeComments(data, onSuccess)
|
LibrusApiBehaviourGradeComments(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDPOINT_LIBRUS_API_NORMAL_GRADES -> {
|
ENDPOINT_LIBRUS_API_NORMAL_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
||||||
LibrusApiGrades(data, onSuccess)
|
LibrusApiGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES -> {
|
ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_behaviour_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_behaviour_grades)
|
||||||
LibrusApiBehaviourGrades(data, onSuccess)
|
LibrusApiBehaviourGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES -> {
|
ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_descriptive_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_descriptive_grades)
|
||||||
LibrusApiDescriptiveGrades(data, onSuccess)
|
LibrusApiDescriptiveGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_TEXT_GRADES -> {
|
ENDPOINT_LIBRUS_API_TEXT_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_descriptive_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_descriptive_grades)
|
||||||
LibrusApiTextGrades(data, onSuccess)
|
LibrusApiTextGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_POINT_GRADES -> {
|
ENDPOINT_LIBRUS_API_POINT_GRADES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_point_grades)
|
data.startProgress(R.string.edziennik_progress_endpoint_point_grades)
|
||||||
LibrusApiPointGrades(data, onSuccess)
|
LibrusApiPointGrades(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
ENDPOINT_LIBRUS_API_EVENT_TYPES -> {
|
ENDPOINT_LIBRUS_API_EVENT_TYPES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_event_types)
|
data.startProgress(R.string.edziennik_progress_endpoint_event_types)
|
||||||
LibrusApiEventTypes(data, onSuccess)
|
LibrusApiEventTypes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_EVENTS -> {
|
ENDPOINT_LIBRUS_API_EVENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
||||||
LibrusApiEvents(data, onSuccess)
|
LibrusApiEvents(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_HOMEWORK -> {
|
ENDPOINT_LIBRUS_API_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
LibrusApiHomework(data, onSuccess)
|
LibrusApiHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_LUCKY_NUMBER -> {
|
ENDPOINT_LIBRUS_API_LUCKY_NUMBER -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
||||||
LibrusApiLuckyNumber(data, onSuccess)
|
LibrusApiLuckyNumber(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_NOTICE_TYPES -> {
|
ENDPOINT_LIBRUS_API_NOTICE_TYPES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notice_types)
|
data.startProgress(R.string.edziennik_progress_endpoint_notice_types)
|
||||||
LibrusApiNoticeTypes(data, onSuccess)
|
LibrusApiNoticeTypes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_NOTICES -> {
|
ENDPOINT_LIBRUS_API_NOTICES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
||||||
LibrusApiNotices(data, onSuccess)
|
LibrusApiNotices(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES -> {
|
ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance_types)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance_types)
|
||||||
LibrusApiAttendanceTypes(data, onSuccess)
|
LibrusApiAttendanceTypes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_ATTENDANCES -> {
|
ENDPOINT_LIBRUS_API_ATTENDANCES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
||||||
LibrusApiAttendances(data, onSuccess)
|
LibrusApiAttendances(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_ANNOUNCEMENTS -> {
|
ENDPOINT_LIBRUS_API_ANNOUNCEMENTS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
||||||
LibrusApiAnnouncements(data, onSuccess)
|
LibrusApiAnnouncements(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_PT_MEETINGS -> {
|
ENDPOINT_LIBRUS_API_PT_MEETINGS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_pt_meetings)
|
data.startProgress(R.string.edziennik_progress_endpoint_pt_meetings)
|
||||||
LibrusApiPtMeetings(data, onSuccess)
|
LibrusApiPtMeetings(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES -> {
|
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_day_types)
|
data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_day_types)
|
||||||
LibrusApiTeacherFreeDayTypes(data, onSuccess)
|
LibrusApiTeacherFreeDayTypes(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS -> {
|
ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_days)
|
data.startProgress(R.string.edziennik_progress_endpoint_teacher_free_days)
|
||||||
LibrusApiTeacherFreeDays(data, onSuccess)
|
LibrusApiTeacherFreeDays(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,11 +195,11 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
*/
|
*/
|
||||||
ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK -> {
|
ENDPOINT_LIBRUS_SYNERGIA_HOMEWORK -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
||||||
LibrusSynergiaHomework(data, onSuccess)
|
LibrusSynergiaHomework(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_SYNERGIA_INFO -> {
|
ENDPOINT_LIBRUS_SYNERGIA_INFO -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
|
data.startProgress(R.string.edziennik_progress_endpoint_student_info)
|
||||||
LibrusSynergiaInfo(data, onSuccess)
|
LibrusSynergiaInfo(data, lastSync, onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -202,14 +207,14 @@ class LibrusData(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
*/
|
*/
|
||||||
ENDPOINT_LIBRUS_MESSAGES_RECEIVED -> {
|
ENDPOINT_LIBRUS_MESSAGES_RECEIVED -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_inbox)
|
||||||
LibrusMessagesGetList(data, type = Message.TYPE_RECEIVED, onSuccess = onSuccess)
|
LibrusMessagesGetList(data, type = Message.TYPE_RECEIVED, lastSync = lastSync, onSuccess = onSuccess)
|
||||||
}
|
}
|
||||||
ENDPOINT_LIBRUS_MESSAGES_SENT -> {
|
ENDPOINT_LIBRUS_MESSAGES_SENT -> {
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
data.startProgress(R.string.edziennik_progress_endpoint_messages_outbox)
|
||||||
LibrusMessagesGetList(data, type = Message.TYPE_SENT, onSuccess = onSuccess)
|
LibrusMessagesGetList(data, type = Message.TYPE_SENT, lastSync = lastSync, onSuccess = onSuccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> onSuccess()
|
else -> onSuccess(endpointId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import javax.xml.transform.TransformerFactory
|
|||||||
import javax.xml.transform.dom.DOMSource
|
import javax.xml.transform.dom.DOMSource
|
||||||
import javax.xml.transform.stream.StreamResult
|
import javax.xml.transform.stream.StreamResult
|
||||||
|
|
||||||
open class LibrusMessages(open val data: DataLibrus) {
|
open class LibrusMessages(open val data: DataLibrus, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LibrusMessages"
|
private const val TAG = "LibrusMessages"
|
||||||
}
|
}
|
||||||
@ -55,13 +55,20 @@ open class LibrusMessages(open val data: DataLibrus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
text.contains("<message>Niepoprawny login i/lub hasło.</message>") -> data.error(TAG, ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN, response, text)
|
text.contains("<message>Niepoprawny login i/lub hasło.</message>") -> ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN
|
||||||
text.contains("stop.png") -> data.error(TAG, ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED, response, text)
|
text.contains("<message>Nie odnaleziono wiadomości.</message>") -> ERROR_LIBRUS_MESSAGES_NOT_FOUND
|
||||||
text.contains("eAccessDeny") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ACCESS_DENIED, response, text)
|
text.contains("stop.png") -> ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED
|
||||||
text.contains("OffLine") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_MAINTENANCE, response, text)
|
text.contains("eAccessDeny") -> ERROR_LIBRUS_MESSAGES_ACCESS_DENIED
|
||||||
text.contains("<status>error</status>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ERROR, response, text)
|
text.contains("OffLine") -> ERROR_LIBRUS_MESSAGES_MAINTENANCE
|
||||||
text.contains("<type>eVarWhitThisNameNotExists</type>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ACCESS_DENIED, response, text)
|
text.contains("<status>error</status>") -> ERROR_LIBRUS_MESSAGES_ERROR
|
||||||
text.contains("<error>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_OTHER, response, text)
|
text.contains("<type>eVarWhitThisNameNotExists</type>") -> ERROR_LIBRUS_MESSAGES_ACCESS_DENIED
|
||||||
|
text.contains("<error>") -> ERROR_LIBRUS_MESSAGES_OTHER
|
||||||
|
else -> null
|
||||||
|
}?.let { errorCode ->
|
||||||
|
data.error(ApiError(tag, errorCode)
|
||||||
|
.withApiResponse(text)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -139,13 +146,20 @@ open class LibrusMessages(open val data: DataLibrus) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
text.contains("<message>Niepoprawny login i/lub hasło.</message>") -> data.error(TAG, ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN, response, text)
|
text.contains("<message>Niepoprawny login i/lub hasło.</message>") -> ERROR_LOGIN_LIBRUS_MESSAGES_INVALID_LOGIN
|
||||||
text.contains("stop.png") -> data.error(TAG, ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED, response, text)
|
text.contains("<message>Nie odnaleziono wiadomości.</message>") -> ERROR_LIBRUS_MESSAGES_NOT_FOUND
|
||||||
text.contains("eAccessDeny") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ACCESS_DENIED, response, text)
|
text.contains("stop.png") -> ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED
|
||||||
text.contains("OffLine") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_MAINTENANCE, response, text)
|
text.contains("eAccessDeny") -> ERROR_LIBRUS_MESSAGES_ACCESS_DENIED
|
||||||
text.contains("<status>error</status>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ERROR, response, text)
|
text.contains("OffLine") -> ERROR_LIBRUS_MESSAGES_MAINTENANCE
|
||||||
text.contains("<type>eVarWhitThisNameNotExists</type>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_ACCESS_DENIED, response, text)
|
text.contains("<status>error</status>") -> ERROR_LIBRUS_MESSAGES_ERROR
|
||||||
text.contains("<error>") -> data.error(TAG, ERROR_LIBRUS_MESSAGES_OTHER, response, text)
|
text.contains("<type>eVarWhitThisNameNotExists</type>") -> ERROR_LIBRUS_MESSAGES_ACCESS_DENIED
|
||||||
|
text.contains("<error>") -> ERROR_LIBRUS_MESSAGES_OTHER
|
||||||
|
else -> null
|
||||||
|
}?.let { errorCode ->
|
||||||
|
data.error(ApiError(tag, errorCode)
|
||||||
|
.withApiResponse(text)
|
||||||
|
.withResponse(response))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -44,6 +44,7 @@ open class LibrusPortal(open val data: DataLibrus) {
|
|||||||
"Access token is invalid" -> ERROR_LIBRUS_PORTAL_ACCESS_DENIED
|
"Access token is invalid" -> ERROR_LIBRUS_PORTAL_ACCESS_DENIED
|
||||||
"ApiDisabled" -> ERROR_LIBRUS_PORTAL_API_DISABLED
|
"ApiDisabled" -> ERROR_LIBRUS_PORTAL_API_DISABLED
|
||||||
"Account not found" -> ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND
|
"Account not found" -> ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND
|
||||||
|
"Unable to refresh the account" -> ERROR_LIBRUS_PORTAL_MAINTENANCE
|
||||||
else -> when (json.getString("hint")) {
|
else -> when (json.getString("hint")) {
|
||||||
"Error while decoding to JSON" -> ERROR_LIBRUS_PORTAL_ACCESS_DENIED
|
"Error while decoding to JSON" -> ERROR_LIBRUS_PORTAL_ACCESS_DENIED
|
||||||
else -> ERROR_LIBRUS_PORTAL_OTHER
|
else -> ERROR_LIBRUS_PORTAL_OTHER
|
||||||
@ -97,6 +98,7 @@ open class LibrusPortal(open val data: DataLibrus) {
|
|||||||
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
|
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
|
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
|
||||||
.allowErrorCode(HttpURLConnection.HTTP_GONE)
|
.allowErrorCode(HttpURLConnection.HTTP_GONE)
|
||||||
|
.allowErrorCode(424)
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
|
@ -12,7 +12,7 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
|
|
||||||
open class LibrusSynergia(open val data: DataLibrus) {
|
open class LibrusSynergia(open val data: DataLibrus, open val lastSync: Long?) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LibrusSynergia"
|
private const val TAG = "LibrusSynergia"
|
||||||
}
|
}
|
||||||
|
@ -6,25 +6,28 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
|
|||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS
|
import pl.szczodrzynski.edziennik.data.api.ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM
|
||||||
import pl.szczodrzynski.edziennik.data.api.POST
|
import pl.szczodrzynski.edziennik.data.api.POST
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
|
import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||||
|
|
||||||
class LibrusApiAnnouncementMarkAsRead(
|
class LibrusApiAnnouncementMarkAsRead(override val data: DataLibrus,
|
||||||
override val data: DataLibrus,
|
private val announcement: AnnouncementFull,
|
||||||
private val announcement: AnnouncementFull,
|
val onSuccess: () -> Unit
|
||||||
val onSuccess: () -> Unit
|
) : LibrusApi(data, null) {
|
||||||
) : LibrusApi(data) {
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiAnnouncementMarkAsRead"
|
const val TAG = "LibrusApiAnnouncementMarkAsRead"
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
apiGet(TAG, "SchoolNotices/MarkAsRead/${announcement.idString}", method = POST,
|
apiGet(TAG, "SchoolNotices/MarkAsRead/${announcement.idString}", method = POST,
|
||||||
ignoreErrors = listOf(ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS)) {
|
ignoreErrors = listOf(
|
||||||
|
ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS,
|
||||||
|
ERROR_LIBRUS_API_NOTICEBOARD_PROBLEM
|
||||||
|
)) {
|
||||||
announcement.seen = true
|
announcement.seen = true
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(AnnouncementGetEvent(announcement))
|
EventBus.getDefault().postSticky(AnnouncementGetEvent(announcement))
|
||||||
|
@ -9,12 +9,14 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_ANNOUNCEMENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_ANNOUNCEMENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class LibrusApiAnnouncements(override val data: DataLibrus,
|
class LibrusApiAnnouncements(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiAnnouncements"
|
const val TAG = "LibrusApiAnnouncements"
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ class LibrusApiAnnouncements(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_ANNOUNCEMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_ANNOUNCEMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_ANNOUNCEMENTS)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,9 @@ import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
|
import pl.szczodrzynski.edziennik.data.db.entity.AttendanceType
|
||||||
|
|
||||||
class LibrusApiAttendanceTypes(override val data: DataLibrus,
|
class LibrusApiAttendanceTypes(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiAttendanceTypes"
|
const val TAG = "LibrusApiAttendanceTypes"
|
||||||
}
|
}
|
||||||
@ -43,7 +45,7 @@ class LibrusApiAttendanceTypes(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 4*DAY)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES, 4*DAY)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,15 @@ import pl.szczodrzynski.edziennik.*
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_ATTENDANCES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_ATTENDANCES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class LibrusApiAttendances(override val data: DataLibrus,
|
class LibrusApiAttendances(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiAttendances"
|
const val TAG = "LibrusApiAttendances"
|
||||||
}
|
}
|
||||||
@ -33,14 +34,15 @@ class LibrusApiAttendances(override val data: DataLibrus,
|
|||||||
val attendances = json.getJsonArray("Attendances")?.asJsonObjectList()
|
val attendances = json.getJsonArray("Attendances")?.asJsonObjectList()
|
||||||
|
|
||||||
attendances?.forEach { attendance ->
|
attendances?.forEach { attendance ->
|
||||||
val id = Utils.strToInt((attendance.getString("Id") ?: return@forEach)
|
val id = ((attendance.getString("Id") ?: return@forEach)
|
||||||
.replace("[^\\d.]".toRegex(), "")).toLong()
|
.replace("[^\\d.]".toRegex(), "")).toLong()
|
||||||
val lessonId = attendance.getJsonObject("Lesson")?.getLong("Id") ?: -1
|
val lessonId = attendance.getJsonObject("Lesson")?.getLong("Id") ?: -1
|
||||||
val lessonNo = attendance.getInt("LessonNo") ?: return@forEach
|
val lessonNo = attendance.getInt("LessonNo") ?: return@forEach
|
||||||
val lessonDate = Date.fromY_m_d(attendance.getString("Date"))
|
val lessonDate = Date.fromY_m_d(attendance.getString("Date"))
|
||||||
|
val teacherId = attendance.getJsonObject("AddedBy")?.getLong("Id")
|
||||||
val semester = attendance.getInt("Semester") ?: return@forEach
|
val semester = attendance.getInt("Semester") ?: return@forEach
|
||||||
val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
|
val type = attendance.getJsonObject("Type")?.getLong("Id") ?: return@forEach
|
||||||
val typeObject = data.attendanceTypes.get(type)
|
val typeObject = data.attendanceTypes[type] ?: null
|
||||||
val topic = typeObject?.name ?: ""
|
val topic = typeObject?.name ?: ""
|
||||||
|
|
||||||
val startTime = data.lessonRanges.get(lessonNo).startTime
|
val startTime = data.lessonRanges.get(lessonNo).startTime
|
||||||
@ -52,19 +54,19 @@ class LibrusApiAttendances(override val data: DataLibrus,
|
|||||||
val attendanceObject = Attendance(
|
val attendanceObject = Attendance(
|
||||||
profileId,
|
profileId,
|
||||||
id,
|
id,
|
||||||
lesson?.teacherId ?: -1,
|
teacherId ?: lesson?.teacherId ?: -1,
|
||||||
lesson?.subjectId ?: -1,
|
lesson?.subjectId ?: -1,
|
||||||
semester,
|
semester,
|
||||||
topic,
|
topic,
|
||||||
lessonDate,
|
lessonDate,
|
||||||
startTime,
|
startTime,
|
||||||
typeObject.type
|
typeObject?.type ?: Attendance.TYPE_CUSTOM
|
||||||
)
|
)
|
||||||
|
|
||||||
val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach)
|
val addedDate = Date.fromIso(attendance.getString("AddDate") ?: return@forEach)
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
data.attendanceList.add(attendanceObject)
|
||||||
if(typeObject.type != Attendance.TYPE_PRESENT) {
|
if(typeObject?.type != Attendance.TYPE_PRESENT) {
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
profileId,
|
profileId,
|
||||||
Metadata.TYPE_ATTENDANCE,
|
Metadata.TYPE_ATTENDANCE,
|
||||||
@ -77,7 +79,7 @@ class LibrusApiAttendances(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_ATTENDANCES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_ATTENDANCES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
|
|
||||||
class LibrusApiBehaviourGradeCategories(override val data: DataLibrus,
|
class LibrusApiBehaviourGradeCategories(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiBehaviourGradeCategories"
|
const val TAG = "LibrusApiBehaviourGradeCategories"
|
||||||
}
|
}
|
||||||
@ -40,7 +42,7 @@ class LibrusApiBehaviourGradeCategories(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES, 1 * WEEK)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES, 1 * WEEK)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_CATEGORIES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@ import pl.szczodrzynski.edziennik.*
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
|
||||||
class LibrusApiBehaviourGradeComments(override val data: DataLibrus,
|
class LibrusApiBehaviourGradeComments(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiBehaviourGradeComments"
|
const val TAG = "LibrusApiBehaviourGradeComments"
|
||||||
}
|
}
|
||||||
@ -38,7 +40,7 @@ class LibrusApiBehaviourGradeComments(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADE_COMMENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,38 +9,54 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiBehaviourGrades"
|
const val TAG = "LibrusApiBehaviourGrades"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nameFormat by lazy { DecimalFormat("#.##") }
|
private val nameFormat by lazy { DecimalFormat("#.##") }
|
||||||
|
|
||||||
|
private val types by lazy {
|
||||||
|
mapOf(
|
||||||
|
1 to ("wz" to "wzorowe"),
|
||||||
|
2 to ("bdb" to "bardzo dobre"),
|
||||||
|
3 to ("db" to "dobre"),
|
||||||
|
4 to ("popr" to "poprawne"),
|
||||||
|
5 to ("ndp" to "nieodpowiednie"),
|
||||||
|
6 to ("ng" to "naganne")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
init { data.profile?.also { profile ->
|
||||||
apiGet(TAG, "BehaviourGrades/Points") { json ->
|
apiGet(TAG, "BehaviourGrades/Points") { json ->
|
||||||
|
|
||||||
if (data.startPointsSemester1 > 0) {
|
if (data.startPointsSemester1 > 0) {
|
||||||
val semester1StartGradeObject = Grade(
|
val semester1StartGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
-101,
|
id = -101,
|
||||||
data.app.getString(R.string.grade_start_points),
|
name = nameFormat.format(data.startPointsSemester1),
|
||||||
0xffbdbdbd.toInt(),
|
type = TYPE_POINT_SUM,
|
||||||
data.app.getString(R.string.grade_start_points_format, 1),
|
value = data.startPointsSemester1.toFloat(),
|
||||||
nameFormat.format(data.startPointsSemester1),
|
weight = 0f,
|
||||||
data.startPointsSemester1.toFloat(),
|
color = 0xffbdbdbd.toInt(),
|
||||||
-1f,
|
category = data.app.getString(R.string.grade_start_points),
|
||||||
1,
|
description = data.app.getString(R.string.grade_start_points_format, 1),
|
||||||
-1,
|
comment = null,
|
||||||
1
|
semester = 1,
|
||||||
).apply { type = Grade.TYPE_POINT_SUM }
|
teacherId = -1,
|
||||||
|
subjectId = 1
|
||||||
|
)
|
||||||
|
|
||||||
data.gradeList.add(semester1StartGradeObject)
|
data.gradeList.add(semester1StartGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -55,18 +71,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
|||||||
|
|
||||||
if (data.startPointsSemester2 > 0) {
|
if (data.startPointsSemester2 > 0) {
|
||||||
val semester2StartGradeObject = Grade(
|
val semester2StartGradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
-102,
|
id = -102,
|
||||||
data.app.getString(R.string.grade_start_points),
|
name = nameFormat.format(data.startPointsSemester2),
|
||||||
0xffbdbdbd.toInt(),
|
type = TYPE_POINT_SUM,
|
||||||
data.app.getString(R.string.grade_start_points_format, 2),
|
value = data.startPointsSemester2.toFloat(),
|
||||||
nameFormat.format(data.startPointsSemester2),
|
weight = -1f,
|
||||||
data.startPointsSemester2.toFloat(),
|
color = 0xffbdbdbd.toInt(),
|
||||||
-1f,
|
category = data.app.getString(R.string.grade_start_points),
|
||||||
2,
|
description = data.app.getString(R.string.grade_start_points_format, 2),
|
||||||
-1,
|
comment = null,
|
||||||
1
|
semester = 2,
|
||||||
).apply { type = Grade.TYPE_POINT_SUM }
|
teacherId = -1,
|
||||||
|
subjectId = 1
|
||||||
|
)
|
||||||
|
|
||||||
data.gradeList.add(semester2StartGradeObject)
|
data.gradeList.add(semester2StartGradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -88,8 +106,12 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
|||||||
val addedDate = grade.getString("AddDate")?.let { Date.fromIso(it) }
|
val addedDate = grade.getString("AddDate")?.let { Date.fromIso(it) }
|
||||||
?: System.currentTimeMillis()
|
?: System.currentTimeMillis()
|
||||||
|
|
||||||
|
val text = grade.getString("Text")
|
||||||
|
val type = grade.getJsonObject("BehaviourGrade")?.getInt("Id")?.let { types[it] }
|
||||||
|
|
||||||
val name = when {
|
val name = when {
|
||||||
value != null -> (if (value >= 0) "+" else "") + nameFormat.format(value)
|
type != null -> type.first
|
||||||
|
value != null -> (if (value > 0) "+" else "") + nameFormat.format(value)
|
||||||
shortName != null -> shortName
|
shortName != null -> shortName
|
||||||
else -> return@forEach
|
else -> return@forEach
|
||||||
}
|
}
|
||||||
@ -108,32 +130,33 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
|||||||
|
|
||||||
val categoryName = category?.text ?: ""
|
val categoryName = category?.text ?: ""
|
||||||
|
|
||||||
val description = grade.getJsonArray("Comments")?.asJsonObjectList()?.let { comments ->
|
val comments = grade.getJsonArray("Comments")
|
||||||
if (comments.isNotEmpty()) {
|
?.asJsonObjectList()
|
||||||
data.gradeCategories.singleOrNull {
|
?.mapNotNull { comment ->
|
||||||
it.type == GradeCategory.TYPE_BEHAVIOUR_COMMENT
|
val cId = comment.getLong("Id") ?: return@mapNotNull null
|
||||||
&& it.categoryId == comments[0].asJsonObject.getLong("Id")
|
data.gradeCategories[cId]?.text
|
||||||
}?.text
|
} ?: listOf()
|
||||||
} else null
|
|
||||||
} ?: ""
|
val description = listOfNotNull(type?.second) + comments
|
||||||
|
|
||||||
val valueFrom = value ?: category?.valueFrom ?: 0f
|
val valueFrom = value ?: category?.valueFrom ?: 0f
|
||||||
val valueTo = category?.valueTo ?: 0f
|
val valueTo = category?.valueTo ?: 0f
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
categoryName,
|
name = name,
|
||||||
color,
|
type = TYPE_POINT_SUM,
|
||||||
description,
|
value = valueFrom,
|
||||||
name,
|
weight = -1f,
|
||||||
valueFrom,
|
color = color,
|
||||||
-1f,
|
category = categoryName,
|
||||||
semester,
|
description = text ?: description.join(" - "),
|
||||||
teacherId,
|
comment = if (text != null) description.join(" - ") else null,
|
||||||
1
|
semester = semester,
|
||||||
|
teacherId = teacherId,
|
||||||
|
subjectId = 1
|
||||||
).apply {
|
).apply {
|
||||||
type = Grade.TYPE_POINT_SUM
|
|
||||||
valueMax = valueTo
|
valueMax = valueTo
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +173,7 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
|
|||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Grades.semesterWithType(profile.currentSemester, Grade.TYPE_POINT_SUM))
|
data.toRemove.add(DataRemoveModel.Grades.semesterWithType(profile.currentSemester, Grade.TYPE_POINT_SUM))
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ import pl.szczodrzynski.edziennik.getString
|
|||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class LibrusApiClasses(override val data: DataLibrus,
|
class LibrusApiClasses(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiClasses"
|
const val TAG = "LibrusApiClasses"
|
||||||
}
|
}
|
||||||
@ -55,7 +57,7 @@ class LibrusApiClasses(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSES, 4 * DAY)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSES, 4 * DAY)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_CLASSES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@ import pl.szczodrzynski.edziennik.data.db.entity.Classroom
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class LibrusApiClassrooms(override val data: DataLibrus,
|
class LibrusApiClassrooms(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiClassrooms"
|
const val TAG = "LibrusApiClassrooms"
|
||||||
}
|
}
|
||||||
@ -25,9 +27,10 @@ class LibrusApiClassrooms(override val data: DataLibrus,
|
|||||||
val id = classroom.getLong("Id") ?: return@forEach
|
val id = classroom.getLong("Id") ?: return@forEach
|
||||||
val name = classroom.getString("Name")?.toLowerCase(Locale.getDefault()) ?: ""
|
val name = classroom.getString("Name")?.toLowerCase(Locale.getDefault()) ?: ""
|
||||||
val symbol = classroom.getString("Symbol")?.toLowerCase(Locale.getDefault()) ?: ""
|
val symbol = classroom.getString("Symbol")?.toLowerCase(Locale.getDefault()) ?: ""
|
||||||
val nameShort = name.split(" ").onEach { it[0] }.joinToString()
|
val nameShort = name.fixWhiteSpaces().split(" ").onEach { it[0] }.joinToString()
|
||||||
|
val symbolParts = symbol.fixWhiteSpaces().split(" ")
|
||||||
|
|
||||||
val friendlyName = if (name != symbol && !name.contains(symbol) && !nameShort.contains(symbol)) {
|
val friendlyName = if (name != symbol && !name.contains(symbol) && !name.containsAll(symbolParts) && !nameShort.contains(symbol)) {
|
||||||
classroom.getString("Symbol") + " " + classroom.getString("Name")
|
classroom.getString("Symbol") + " " + classroom.getString("Name")
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -38,7 +41,7 @@ class LibrusApiClassrooms(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSROOMS, 4*DAY)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_CLASSROOMS, 4*DAY)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_CLASSROOMS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
|
|
||||||
class LibrusApiDescriptiveGradeCategories(override val data: DataLibrus,
|
class LibrusApiDescriptiveGradeCategories(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiDescriptiveGradeCategories"
|
const val TAG = "LibrusApiDescriptiveGradeCategories"
|
||||||
}
|
}
|
||||||
@ -39,7 +41,7 @@ class LibrusApiDescriptiveGradeCategories(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES, 1 * DAY)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES, 1 * DAY)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADE_CATEGORIES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,16 +9,18 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_DESCRIPTIVE_TEXT
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_DESCRIPTIVE_TEXT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.TYPE_TEXT
|
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_TEXT
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class LibrusApiDescriptiveGrades(override val data: DataLibrus,
|
class LibrusApiDescriptiveGrades(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiDescriptiveGrades"
|
const val TAG = "LibrusApiDescriptiveGrades"
|
||||||
}
|
}
|
||||||
@ -51,20 +53,20 @@ class LibrusApiDescriptiveGrades(override val data: DataLibrus,
|
|||||||
val addedDate = Date.fromIso(grade.getString("AddDate") ?: return@forEach)
|
val addedDate = Date.fromIso(grade.getString("AddDate") ?: return@forEach)
|
||||||
|
|
||||||
val gradeObject = Grade(
|
val gradeObject = Grade(
|
||||||
profileId,
|
profileId = profileId,
|
||||||
id,
|
id = id,
|
||||||
category?.text ?: "",
|
name = " ",
|
||||||
category?.color ?: -1,
|
type = type,
|
||||||
description,
|
value = 0f,
|
||||||
" ",
|
weight = 0f,
|
||||||
0f,
|
color = category?.color ?: -1,
|
||||||
0f,
|
category = category?.text,
|
||||||
semester,
|
description = description,
|
||||||
teacherId,
|
comment = null,
|
||||||
subjectId
|
semester = semester,
|
||||||
).apply {
|
teacherId = teacherId,
|
||||||
this.type = type
|
subjectId = subjectId
|
||||||
}
|
)
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
data.gradeList.add(gradeObject)
|
||||||
data.metadataList.add(Metadata(
|
data.metadataList.add(Metadata(
|
||||||
@ -85,7 +87,7 @@ class LibrusApiDescriptiveGrades(override val data: DataLibrus,
|
|||||||
})
|
})
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES)
|
||||||
}
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess(ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES) }
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
|||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||||
|
|
||||||
class LibrusApiEventTypes(override val data: DataLibrus,
|
class LibrusApiEventTypes(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiEventTypes"
|
const val TAG = "LibrusApiEventTypes"
|
||||||
}
|
}
|
||||||
@ -29,7 +31,7 @@ class LibrusApiEventTypes(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_EVENT_TYPES, 4*DAY)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_EVENT_TYPES, 4*DAY)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_EVENT_TYPES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,16 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_EVENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_EVENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
|
|
||||||
class LibrusApiEvents(override val data: DataLibrus,
|
class LibrusApiEvents(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiEvents"
|
const val TAG = "LibrusApiEvents"
|
||||||
}
|
}
|
||||||
@ -34,7 +36,7 @@ class LibrusApiEvents(override val data: DataLibrus,
|
|||||||
val id = event.getLong("Id") ?: return@forEach
|
val id = event.getLong("Id") ?: return@forEach
|
||||||
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
val eventDate = Date.fromY_m_d(event.getString("Date"))
|
||||||
val topic = event.getString("Content") ?: ""
|
val topic = event.getString("Content") ?: ""
|
||||||
val type = event.getJsonObject("Category")?.getInt("Id") ?: -1
|
val type = event.getJsonObject("Category")?.getLong("Id") ?: -1
|
||||||
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
val teacherId = event.getJsonObject("CreatedBy")?.getLong("Id") ?: -1
|
||||||
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
val subjectId = event.getJsonObject("Subject")?.getLong("Id") ?: -1
|
||||||
val teamId = event.getJsonObject("Class")?.getLong("Id") ?: -1
|
val teamId = event.getJsonObject("Class")?.getLong("Id") ?: -1
|
||||||
@ -76,7 +78,7 @@ class LibrusApiEvents(override val data: DataLibrus,
|
|||||||
)))
|
)))
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_EVENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_EVENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_EVENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,13 @@ import pl.szczodrzynski.edziennik.*
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
|
||||||
class LibrusApiGradeCategories(override val data: DataLibrus,
|
class LibrusApiGradeCategories(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiGradeCategories"
|
const val TAG = "LibrusApiGradeCategories"
|
||||||
}
|
}
|
||||||
@ -42,7 +44,7 @@ class LibrusApiGradeCategories(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_NORMAL_GRADE_CATEGORIES)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,13 @@ import pl.szczodrzynski.edziennik.*
|
|||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
import pl.szczodrzynski.edziennik.data.db.entity.GradeCategory
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
||||||
|
|
||||||
class LibrusApiGradeComments(override val data: DataLibrus,
|
class LibrusApiGradeComments(override val data: DataLibrus,
|
||||||
val onSuccess: () -> Unit) : LibrusApi(data) {
|
override val lastSync: Long?,
|
||||||
|
val onSuccess: (endpointId: Int) -> Unit
|
||||||
|
) : LibrusApi(data, lastSync) {
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LibrusApiGradeComments"
|
const val TAG = "LibrusApiGradeComments"
|
||||||
}
|
}
|
||||||
@ -38,7 +40,7 @@ class LibrusApiGradeComments(override val data: DataLibrus,
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess(ENDPOINT_LIBRUS_API_NORMAL_GRADE_COMMENTS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user