Compare commits

...

93 Commits

Author SHA1 Message Date
55268f1c43 [4.0-beta.11] Update build.gradle, signing and changelog. 2020-03-06 23:23:33 +01:00
1bec6d281c [Grades] Implement Grades editor. 2020-03-06 21:24:01 +01:00
f17a02be54 [Grades] Implement new Grades module (UI & API changes). 2020-03-06 21:09:05 +01:00
4e8fdd2225 [API/Idziennik] Fix incorrect exam type. 2020-03-06 09:25:35 +01:00
59819b4a96 [Base] Update TemplateFragment. 2020-03-04 19:09:53 +01:00
673378d8d9 [UI/Home] Improve no data text font in home cards. 2020-03-04 19:02:50 +01:00
30044d6b21 [Timetable] Ignore last lessons if cancelled and jump to the next day. 2020-03-03 18:06:55 +01:00
ee43d40680 [API/Librus] Fix device not registered error in push config. 2020-03-03 10:35:48 +01:00
1354faf8c7 [Dialog/GenerateBlockTimetable] Make better dialog layout. 2020-02-29 00:43:38 +01:00
1bfb3781ab [UI/Lists] Add missing item dividers. Try to improve attendance & grades design. 2020-02-28 23:45:46 +01:00
d7d0c6f822 [UI/Events] Add button tooltips in dialogs. Add showing weekday in home card. Add 'go to timetable' button in details dialog. 2020-02-28 23:01:38 +01:00
2bea18dc3c [Home/Events] Add new card to home fragment. Disable debug card swapping. 2020-02-28 22:38:03 +01:00
f998f2d956 [Home/Timetable] Remove "?" lessons from timetable card. 2020-02-28 21:10:03 +01:00
faa77ee5fb [Widgets/Timetable] Show crossed out classroom in lesson change if no new classroom specified. 2020-02-28 21:10:03 +01:00
88ec463284 [Gradle] Update gradle. 2020-02-28 18:33:28 +01:00
b7df71d7d9 [API/Grades] Fix proposed/final grades added date in Mobidziennik, Idziennik. 2020-02-27 23:41:41 +01:00
6a28dbd2c4 [API/Idziennik] Add changing the selected student/register (web) to get grades in some cases. 2020-02-27 23:36:41 +01:00
010f7fa1fe [API/Idziennik] Add getting lucky number from website. Fix API lucky number date. 2020-02-27 23:01:47 +01:00
209f98594f [Widgets/Timetable] Show lessons date in unified timetable widget. 2020-02-27 22:32:02 +01:00
54121c99a3 [Login/Captcha] Update captcha to fit smaller screens. Fix Librus invalid login error with captcha. 2020-02-26 21:27:03 +01:00
f6f1370edf [Debug] Add new debug mode. Include hidden Chucker in release. 2020-02-26 20:37:55 +01:00
d5863485f9 [API/Edudziennik] Fix getting attendance for the second semester. 2020-02-25 19:28:53 +01:00
afc88d316b [4.0-beta.10] Update build.gradle, signing and changelog. 2020-02-24 18:27:21 +01:00
b141279811 [API/Librus] Update Client ID. Add handling of invalid Client ID error. 2020-02-24 18:06:53 +01:00
1997ea25d5 [Gradle] Update gradle and libraries. 2020-02-24 15:29:18 +01:00
f4b49eecd4 [UI] Update theme accent colors. 2020-02-24 15:29:18 +01:00
a4493ec964 [Notifications] Add filtering notifications to show during sync. 2020-02-24 15:29:18 +01:00
af8bda9e92 [Dialog/Day] Add showing lessons count and length. 2020-02-23 23:17:28 +01:00
06d252e4ca [Notifications] Fix chucker notifications throwing an error toast. 2020-02-23 17:40:02 +01:00
67be456bb0 [Firebase/Librus] Implement Librus push registration and receiving. Fix not passing lastSync to endpoint. 2020-02-21 22:49:24 +01:00
aa5e225148 [Firebase/Vulcan] Fix not converting received string to JsonObject. 2020-02-21 22:32:50 +01:00
367f46fac8 [API/Librus] Fix captcha showing as incorrect login error. Add handling CSRF error. 2020-02-21 21:32:06 +01:00
d2f14093ec [API] Fix sync error in case of an internal, handled error. 2020-02-21 20:41:57 +01:00
43ed621879 [Errors] Fix error reporting from snackbar. 2020-02-21 20:35:18 +01:00
15c8134d13 [Firebase/Vulcan] Implement push notifications sync. 2020-02-20 21:20:51 +01:00
c2b8f71467 [4.0-beta.9] Update build.gradle, signing and changelog. 2020-02-19 23:33:30 +01:00
a6b91c3a14 [Models] Add basic error protection in Date, Time. 2020-02-19 23:04:28 +01:00
164cfbfd0d [API/Mobidziennik] Fix getting grade added dates, colors and averages. 2020-02-19 22:59:32 +01:00
0bb340e96e [API/Mobidziennik] Implement web attendance scrapper. 2020-02-19 18:58:57 +01:00
f0447dc455 [API/Mobidziennik] Fix too much clearing grades from DB. Add performance debugging to Data and ApiService. 2020-02-19 16:38:11 +01:00
626bbfa7a4 [API/Mobidziennik] Add sent messages endpoint. 2020-02-18 20:10:05 +01:00
169a900f01 [API] Implement passing last sync time to endpoints. 2020-02-18 18:58:51 +01:00
d0992eaf54 [API] Implement error handling and exception catching in Szkolny API. 2020-02-16 22:50:06 +01:00
fc21d757c3 [API/Szkolny] Restrict AppSync to run only every 24 hours (if no WebPush needed). 2020-02-16 14:30:13 +01:00
54363ee919 [UI/Timetable] Add lesson type annotation in LessonDetailsDialog. 2020-02-16 14:12:55 +01:00
fdad3b9997 [Push/Mobidziennik] Add support for behaviour grades push. 2020-02-16 13:44:45 +01:00
4ad826ebe8 [API] Implement Librus Captcha. Refactor notification constants. Update empty account error as a dialog. 2020-02-16 13:42:14 +01:00
f5e1e9fdd9 [Deprecated] Remove ServerRequest, GenericDialog. 2020-02-15 18:53:38 +01:00
82b232d0e5 [Messages/Compose] Add dropdown icon to show all recipient categories. Add before-send confirmation dialog. 2020-02-15 14:36:36 +01:00
c8c1fe5367 [4.0-beta.8] Update build.gradle and signing. 2020-02-14 22:39:13 +01:00
71128e0244 [Messages/Compose] Fix text layout jumping and scrolling off-screen when typing a long message. 2020-02-14 22:28:58 +01:00
453bcaa1f6 [Dialog/Day] Show lesson changes and teacher absences in the day dialog. 2020-02-13 23:04:29 +01:00
48898ab1d4 [Widgets] Fix profile separator text color. 2020-02-13 13:44:20 +01:00
a095520d0d [UI/Agenda] Fix subject, teacher and time display in all day events. 2020-02-13 13:33:04 +01:00
2e0c6fa6a5 [Errors] Add request body in error reporting. 2020-02-13 09:57:59 +01:00
bfbc0861df [Notifications] Disable notifications about past events & timetable changes. 2020-02-12 23:05:03 +01:00
3a500f3f28 [API/Librus] Fix student name not normalized, short name not having a trailing dot (remove legacy code). 2020-02-12 19:20:39 +01:00
df8094c39c [Dialog/LessonChanges] Add a new lesson changes dialog. 2020-02-11 16:34:40 +01:00
448fd0e884 [API/Librus] Fix marking removed announcements as read. 2020-02-10 23:53:04 +01:00
4717b4549e [Feedback] Fix crashing when null message is received. 2020-02-09 23:03:37 +01:00
57a8d72f1c [Feedback] Fix received messages not displaying for user. 2020-02-09 23:00:01 +01:00
7e57617e04 [Feedback] Update proguard rules for feedback message entity. 2020-02-09 22:03:41 +01:00
37ddd643ac [Feedback] Hide notification when feedback is open. Fix mixing messages when a thread is open. 2020-02-09 15:10:03 +01:00
bcf3fef303 [Widget/Timetable] Fix no lessons text not legible on dark background. 2020-02-09 14:34:38 +01:00
7ac4d24106 [4.0-beta.7] Update build.gradle, signing and changelog. 2020-02-08 23:16:54 +01:00
93e5bce778 [Feedback] Fix showing wrong names, improve messages filtering by device id. 2020-02-08 23:12:32 +01:00
d48beba307 [Notifications] Fix timetable notification not having subject name. 2020-02-08 23:11:59 +01:00
760338496c [Dialog/GenerateBlockTimetable] Add option for showing teacher names. 2020-02-08 01:33:34 +01:00
b52e7a3078 [Database] Remove unnecessary migration. 2020-02-04 20:59:13 +01:00
78c5b6b2a5 [Database] Fix migrations from 3.2.1 to 4.0-beta. 2020-02-04 00:31:56 +01:00
60a3c38951 [API/Vulcan] Add automatic semester date and ID updating. 2020-02-01 21:41:09 +01:00
4763033f24 [4.0-beta.6] Update build.gradle, signing and changelog. 2020-01-28 22:53:52 +01:00
3b0570d21c Revert "[Sync] Lower the priority of sync notification."
This reverts commit 1677be9e6fa30478564df94201ea0f8193d6e5b8.
2020-01-28 22:47:59 +01:00
16bf478d1a [UI/Agenda] Rewrite agenda in Kotlin and add lesson change counters. 2020-01-26 22:20:46 +01:00
5bf181b6d1 [Feedback] Implement notifications. 2020-01-26 22:03:20 +01:00
21b2e5d194 [Feedback] Add new feedback fragment and API. 2020-01-26 20:05:32 +01:00
759afcf3ca [Database/Migrations] Move migrations to files. 2020-01-25 17:23:47 +01:00
d48c7844a4 [UI/Settings] Add grades config dialog to settings fragment. 2020-01-25 13:31:40 +01:00
7d8caa8df7 [API/Librus] Use added by teacher id instead of lesson teacher in attendance. 2020-01-25 12:42:03 +01:00
62f53930da [Dialog/GradesConfig] Add grades view config dialog. 2020-01-22 23:09:07 +01:00
9a45cbb679 [UI] Add keepScreenOn in counter activity and bell sync dialog. 2020-01-22 23:08:23 +01:00
8e5a10f6d8 [API/Mobidziennik] Implement getting email for push registration. 2020-01-21 20:44:49 +01:00
10c57d2272 [Sync] Lower the priority of sync notification. 2020-01-20 23:10:35 +01:00
67d4d0f898 [Sync] Fix doubled and dead notifications during sync. 2020-01-20 21:36:53 +01:00
97e0d04842 [API] Partially revert "Include device object in each request." 2020-01-20 21:34:22 +01:00
3ba30ede92 [Sync] Fix sync notification crashing on Oreo+. 2020-01-20 20:26:52 +01:00
1035e411ab [API] Include device object in each request. 2020-01-20 19:43:14 +01:00
d5ae4b7ec9 [Home/Grades] Remove filtering grades by semester. 2020-01-20 19:30:20 +01:00
111d040cf9 [Updates] Fix no update toast not visible. 2020-01-20 19:27:59 +01:00
8cc594d170 [Widget/Timetable] Fix widget crashing with NO_LESSONS item. 2020-01-20 19:27:06 +01:00
d8a8bed68d [4.0-beta.5] Update build.gradle and signing. 2020-01-19 22:42:29 +01:00
eedbd954bd [Updates] Add toast for error while checking and for no updates. 2020-01-19 22:35:12 +01:00
0eb8366027 [Changelog] Fix changelog dialog appearance on Android N+. 2020-01-19 22:29:34 +01:00
428 changed files with 10539 additions and 6336 deletions

View File

@ -166,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'
@ -188,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()

View File

@ -24,6 +24,7 @@
-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

View File

@ -1,4 +1,4 @@
<h3>Wersja 4.0-beta.4, 2020-01-19</h3> <h3>Wersja 4.0-beta.11, 2020-03-06</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, szybkosć 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 &#x1F44F;</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 &#x1F44F;</li>
@ -25,17 +25,11 @@
<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>
<li>Cisza nocna w powiadomieniach jeszcze nie działa.</li> <li>Cisza nocna w powiadomieniach jeszcze nie działa.</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>&copy; Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i> <i>&copy; Kuba Szczodrzyński, Kacper Ziubryniewicz 2020</i>

View File

@ -9,7 +9,7 @@
/*secret password - removed for source code publication*/ /*secret password - removed for source code publication*/
static toys AES_IV[16] = { static toys AES_IV[16] = {
0x38, 0x9a, 0x10, 0x56, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 0x00, 0x37, 0x6a, 0x20, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat); unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);

View File

@ -4,9 +4,6 @@
package pl.szczodrzynski.edziennik package pl.szczodrzynski.edziennik
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
@ -48,6 +45,9 @@ import pl.szczodrzynski.edziennik.sync.SyncWorker
import pl.szczodrzynski.edziennik.sync.UpdateWorker import pl.szczodrzynski.edziennik.sync.UpdateWorker
import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity import pl.szczodrzynski.edziennik.ui.modules.base.CrashActivity
import pl.szczodrzynski.edziennik.utils.* 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.UserActionManager
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@ -61,27 +61,12 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
get() = profile.id get() = profile.id
var devMode = false var devMode = false
var debugMode = false
} }
val notifications by lazy { Notifications() } val notificationChannelsManager by lazy { NotificationChannelsManager(this) }
inner class Notifications { val userActionManager by lazy { UserActionManager(this) }
val syncId = 1 val gradesManager by lazy { GradesManager(this) }
val syncKey = "pl.szczodrzynski.edziennik.SYNC"
val syncChannelName: String by lazy { getString(R.string.notification_channel_get_data_name) }
val syncChannelDesc: String by lazy { getString(R.string.notification_channel_get_data_desc) }
val dataId = 50
val dataKey = "pl.szczodrzynski.edziennik.DATA"
val dataChannelName: String by lazy { getString(R.string.notification_channel_notifications_name) }
val dataChannelDesc: String by lazy { getString(R.string.notification_channel_notifications_desc) }
val dataQuietId = 60
val dataQuietKey = "pl.szczodrzynski.edziennik.DATA_QUIET"
val dataQuietChannelName: String by lazy { getString(R.string.notification_channel_notifications_quiet_name) }
val dataQuietChannelDesc: String by lazy { getString(R.string.notification_channel_notifications_quiet_desc) }
val updatesId = 100
val updatesKey = "pl.szczodrzynski.edziennik.UPDATES"
val updatesChannelName: String by lazy { getString(R.string.notification_channel_updates_name) }
val updatesChannelDesc: String by lazy { getString(R.string.notification_channel_updates_desc) }
}
val db val db
get() = App.db get() = App.db
@ -99,7 +84,6 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.setMinimumLoggingLevel(Log.VERBOSE) .setMinimumLoggingLevel(Log.VERBOSE)
.build() .build()
val preferences by lazy { getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE) }
val permissionChecker by lazy { PermissionChecker(this) } val permissionChecker by lazy { PermissionChecker(this) }
val networkUtils by lazy { NetworkUtils(this) } val networkUtils by lazy { NetworkUtils(this) }
val gson by lazy { Gson() } val gson by lazy { Gson() }
@ -122,7 +106,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
.readTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS)
builder.installHttpsSupport(this) 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))
@ -177,6 +161,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
Iconics.registerFont(SzkolnyFont) Iconics.registerFont(SzkolnyFont)
App.db = AppDb(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)) { if (!profileLoadById(config.lastProfileId)) {
@ -193,6 +178,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
if (config.devModePassword != null) if (config.devModePassword != null)
checkDevModePassword() checkDevModePassword()
debugMode = devMode || config.debugMode
if (config.sync.enabled) if (config.sync.enabled)
SyncWorker.scheduleNext(this@App, false) SyncWorker.scheduleNext(this@App, false)
@ -251,29 +237,7 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
) )
} // shortcuts - end } // shortcuts - end
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notificationChannelsManager.registerAllChannels()
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(
NotificationChannel(notifications.syncKey, notifications.syncChannelName, NotificationManager.IMPORTANCE_MIN).apply {
description = notifications.syncChannelDesc
})
notificationManager.createNotificationChannel(
NotificationChannel(notifications.dataKey, notifications.dataChannelName, NotificationManager.IMPORTANCE_HIGH).apply {
description = notifications.dataChannelDesc
enableLights(true)
lightColor = 0xff2196f3.toInt()
})
notificationManager.createNotificationChannel(
NotificationChannel(notifications.dataQuietKey, notifications.dataQuietChannelName, NotificationManager.IMPORTANCE_LOW).apply {
description = notifications.dataQuietChannelDesc
setSound(null, null)
enableVibration(false)
})
notificationManager.createNotificationChannel(
NotificationChannel(notifications.updatesKey, notifications.updatesChannelName, NotificationManager.IMPORTANCE_DEFAULT).apply {
description = notifications.updatesChannelDesc
})
}
if (config.appInstalledTime == 0L) if (config.appInstalledTime == 0L)
@ -394,4 +358,4 @@ class App : MultiDexApplication(), Configuration.Provider, CoroutineScope {
false false
} }
} }
} }

View File

@ -25,6 +25,7 @@ import android.util.Base64.encodeToString
import android.view.View import android.view.View
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
@ -39,6 +40,7 @@ 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
@ -48,15 +50,22 @@ import okhttp3.OkHttpClient
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.TlsVersion import okhttp3.TlsVersion
import okio.Buffer import okio.Buffer
import pl.szczodrzynski.edziennik.data.api.*
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.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.KeyStore
import java.security.MessageDigest import java.security.MessageDigest
@ -66,6 +75,7 @@ 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.SSLContext
import javax.net.ssl.SSLException
import javax.net.ssl.TrustManagerFactory import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager import javax.net.ssl.X509TrustManager
import kotlin.Pair import kotlin.Pair
@ -85,8 +95,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
@ -94,8 +104,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)
@ -1032,3 +1053,42 @@ fun CharSequence.containsAll(list: List<CharSequence>, ignoreCase: Boolean = fal
} }
return true 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
}
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 }

View File

@ -567,7 +567,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
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)
@ -659,6 +659,10 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
.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) {
@ -696,6 +700,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
d(TAG, "}") d(TAG, "}")
var intentProfileId = -1
var intentTargetId = -1
if (extras?.containsKey("action") == true) { if (extras?.containsKey("action") == true) {
val handled = when (extras.getString("action")) { val handled = when (extras.getString("action")) {
"serverMessage" -> { "serverMessage" -> {
@ -706,10 +713,23 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
) )
true true
} }
"feedbackMessage" -> {
intentTargetId = TARGET_FEEDBACK
false
}
"userActionRequired" -> {
app.userActionManager.execute(
this,
extras.getInt("profileId"),
extras.getInt("type")
)
true
}
else -> false else -> false
} }
if (handled) if (handled && !navLoading) {
return return
}
} }
if (extras?.containsKey("reloadProfileId") == true) { if (extras?.containsKey("reloadProfileId") == true) {
@ -721,17 +741,14 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
} }
} }
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) {

View File

@ -75,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 }
@ -100,6 +105,11 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() } get() { mWidgetConfigs = mWidgetConfigs ?: values.get("widgetConfigs", JsonObject()); return mWidgetConfigs ?: JsonObject() }
set(value) { set("widgetConfigs", value); mWidgetConfigs = value } set(value) { set("widgetConfigs", value); mWidgetConfigs = value }
private var mLastAppSync: Long? = null
var lastAppSync: Long
get() { mLastAppSync = mLastAppSync ?: values.get("lastAppSync", 0L); return mLastAppSync ?: 0L }
set(value) { set("lastAppSync", value); mLastAppSync = value }
private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow() private var rawEntries: List<ConfigEntry> = db.configDao().getAllNow()
private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf() private val profileConfigs: HashMap<Int, ProfileConfig> = hashMapOf()
init { init {
@ -125,4 +135,4 @@ class Config(val db: AppDb) : CoroutineScope, AbstractConfig {
db.configDao().add(ConfigEntry(-1, key, value)) db.configDao().add(ConfigEntry(-1, key, value))
} }
} }
} }

View File

@ -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 ?: ORDER_BY_DATE_DESC } 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 }
} }

View File

@ -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,11 +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 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 }

View File

@ -29,8 +29,8 @@ class ProfileConfig(val db: AppDb, val profileId: Int, rawEntries: List<ConfigEn
val grades by lazy { ProfileConfigGrades(this) } val grades by lazy { ProfileConfigGrades(this) }
val ui by lazy { ProfileConfigUI(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) }*/
@ -56,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))
} }
} }
} }

View File

@ -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
@ -24,4 +25,18 @@ class ProfileConfigGrades(private val config: ProfileConfig) {
var countZeroToAvg: Boolean var countZeroToAvg: Boolean
get() { mCountZeroToAvg = mCountZeroToAvg ?: config.values.get("countZeroToAvg", true); return mCountZeroToAvg ?: true } get() { mCountZeroToAvg = mCountZeroToAvg ?: config.values.get("countZeroToAvg", true); return mCountZeroToAvg ?: true }
set(value) { config.set("countZeroToAvg", value); mCountZeroToAvg = value } set(value) { config.set("countZeroToAvg", value); mCountZeroToAvg = 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 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 }
} }

View File

@ -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 }
}

View File

@ -7,10 +7,16 @@ 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.data.db.entity.Profile.Companion.AGENDA_DEFAULT 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) { class ProfileConfigUI(private val config: ProfileConfig) {
private var mAgendaViewType: Int? = null private var mAgendaViewType: Int? = null
var agendaViewType: Int var agendaViewType: Int
get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT } get() { mAgendaViewType = mAgendaViewType ?: config.values.get("agendaViewType", 0); return mAgendaViewType ?: AGENDA_DEFAULT }
set(value) { config.set("agendaViewType", value); mAgendaViewType = value } 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 }
} }

View File

@ -94,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
} }
} }

View File

@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.BuildConfig
import pl.szczodrzynski.edziennik.HOUR import pl.szczodrzynski.edziennik.HOUR
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.config.Config import pl.szczodrzynski.edziennik.config.Config
import pl.szczodrzynski.edziennik.config.ConfigGrades.Companion.ORDER_BY_DATE_DESC import pl.szczodrzynski.edziennik.utils.managers.GradesManager.Companion.ORDER_BY_DATE_DESC
class ConfigMigration(app: App, config: Config) { class ConfigMigration(app: App, config: Config) {
init { config.apply { init { config.apply {
@ -63,7 +63,6 @@ class ConfigMigration(app: App, config: Config) {
if (dataVersion < 10) { if (dataVersion < 10) {
ui.openDrawerOnBackPressed = false ui.openDrawerOnBackPressed = false
ui.homeCards = listOf()
ui.snowfall = false ui.snowfall = false
ui.bottomSheetOpened = false ui.bottomSheetOpened = false
sync.dontShowAppManagerDialog = false sync.dontShowAppManagerDialog = false

View File

@ -6,8 +6,8 @@ package pl.szczodrzynski.edziennik.config.utils
import pl.szczodrzynski.edziennik.config.ProfileConfig import pl.szczodrzynski.edziennik.config.ProfileConfig
import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT import pl.szczodrzynski.edziennik.data.db.entity.Profile.Companion.AGENDA_DEFAULT
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 ProfileConfigMigration(config: ProfileConfig) { class ProfileConfigMigration(config: ProfileConfig) {
init { config.apply { init { config.apply {
@ -21,4 +21,4 @@ class ProfileConfigMigration(config: ProfileConfig) {
dataVersion = 1 dataVersion = 1
} }
}} }}
} }

View File

@ -29,7 +29,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))
} }
@ -54,13 +54,14 @@ class ApiService : Service() {
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
@ -74,7 +75,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()
@ -86,9 +87,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()
@ -155,7 +163,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()
@ -165,6 +173,7 @@ 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)
@ -301,7 +310,7 @@ 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
} }

View File

@ -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"

View File

@ -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)
@ -41,34 +38,34 @@ class EdziennikNotification(val context: Context) {
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)
} }
@ -82,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()
@ -119,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
@ -129,7 +126,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_cancel), app.getString(R.string.edziennik_notification_api_cancel),
cancelPendingIntent(taskId) cancelPendingIntent(taskId)
)) ))
} }
@ -137,7 +134,7 @@ class EdziennikNotification(val context: Context) {
fun post() { fun post() {
if (serviceClosed) if (serviceClosed)
return return
notificationManager.notify(NOTIFICATION_ID, notification) notificationManager.notify(app.notificationChannelsManager.sync.id, notification)
} }
} }

View File

@ -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()

View File

@ -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
@ -59,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
@ -116,6 +121,9 @@ 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_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

View File

@ -90,7 +90,7 @@ val mobidziennikLoginMethods = listOf(
.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 { profile, _ -> profile?.hasStudentData("email") == true } .withIsPossible { profile, _ -> profile?.getStudentData("email", null) != null }
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED } .withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
) )

View File

@ -54,9 +54,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)
} }
@ -85,6 +109,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()
}

View File

@ -30,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))
@ -85,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)
@ -106,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)

View File

@ -52,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()
} }

View File

@ -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)
} }
} }
} }

View File

@ -14,7 +14,7 @@ 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 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"
} }

View File

@ -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) }
} }

View File

@ -20,13 +20,22 @@ 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", semester = -1) { 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())
@ -89,8 +98,13 @@ class EdudziennikWebAttendance(override val data: DataEdudziennik,
} }
} }
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) }
} }

View File

@ -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) }
} }

View File

@ -20,7 +20,9 @@ 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"
} }
@ -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)
} }
}} }}
} }

View File

@ -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"
} }

View File

@ -14,7 +14,12 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZI
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.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.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.get import pl.szczodrzynski.edziennik.get
@ -22,7 +27,9 @@ 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"
} }
@ -88,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)
@ -107,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,
semester, 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(
@ -137,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,
semester, 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(
@ -170,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,
semester, 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(
@ -218,8 +225,8 @@ class EdudziennikWebGrades(override val data: DataEdudziennik,
getGrades() getGrades()
} else { } else {
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
onSuccess() onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES)
} }
} }
} ?: onSuccess() } } ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) }
} }

View File

@ -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) }
} }

View File

@ -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) }
} }

View File

@ -17,7 +17,9 @@ 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"
} }
@ -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) }
} }

View File

@ -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)
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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) }
} }

View File

@ -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 {

View File

@ -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 }
/* _ /* _
/\ (_) /\ (_)
/ \ _ __ _ / \ _ __ _

View File

@ -54,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()
} }

View File

@ -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"
} }

View File

@ -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)
} }
} }
} }

View File

@ -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()

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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.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.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"
} }
@ -69,7 +71,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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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) }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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) }
} }

View File

@ -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)

View File

@ -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()
}
}
}

View File

@ -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)
} }
}} }}
} }

View File

@ -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 {

View File

@ -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)

View File

@ -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; }
/* _____ _ /* _____ _
/ ____| (_) / ____| (_)
| (___ _ _ _ __ ___ _ __ __ _ _ __ _ | (___ _ _ _ __ ___ _ __ __ _ _ __ _

View File

@ -56,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()
} }
@ -180,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()
@ -198,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()
@ -207,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)
} }
} }

View File

@ -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(

View File

@ -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,6 +44,8 @@ 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") ?:
@ -63,6 +65,8 @@ 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
else -> ERROR_LIBRUS_API_OTHER else -> ERROR_LIBRUS_API_OTHER
}.let { errorCode -> }.let { errorCode ->
if (errorCode !in ignoreErrors) { if (errorCode !in ignoreErrors) {
@ -114,6 +118,7 @@ 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)
.callback(callback) .callback(callback)
.build() .build()
.enqueue() .enqueue()

View File

@ -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)
} }
} }
} }

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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))

View File

@ -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)
} }
}} }}
} }

View File

@ -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)
} }
} }
} }

View File

@ -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,11 +34,12 @@ 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.get(type)
@ -52,7 +54,7 @@ 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,
@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -9,15 +9,18 @@ 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"
} }
@ -29,18 +32,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
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 +60,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(
@ -121,19 +128,20 @@ class LibrusApiBehaviourGrades(override val data: DataLibrus,
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 = description,
teacherId, comment = null,
1 semester = semester,
teacherId = teacherId,
subjectId = 1
).apply { ).apply {
type = Grade.TYPE_POINT_SUM
valueMax = valueTo valueMax = valueTo
} }
@ -150,7 +158,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) }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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"
} }
@ -39,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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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) }
} }

View File

@ -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)
} }
} }
} }

View File

@ -17,7 +17,9 @@ 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"
} }
@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -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)
} }
} }
} }

View File

@ -5,16 +5,24 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_GRADES import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NORMAL_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.* import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
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.Grade.Companion.TYPE_YEAR_FINAL
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_YEAR_PROPOSED
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.Utils import pl.szczodrzynski.edziennik.utils.Utils
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiGrades(override val data: DataLibrus, class LibrusApiGrades(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 = "LibrusApiGrades" const val TAG = "LibrusApiGrades"
} }
@ -52,32 +60,28 @@ class LibrusApiGrades(override val data: DataLibrus,
} ?: "" } ?: ""
val gradeObject = Grade( val gradeObject = Grade(
profileId, profileId = profileId,
id, id = id,
category?.text ?: "", name = name,
category?.color ?: -1, type = when {
description, grade.getBoolean("IsConstituent") ?: false -> TYPE_NORMAL
name, grade.getBoolean("IsSemester") ?: false -> if (semester == 1) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER2_FINAL
value, grade.getBoolean("IsSemesterProposition") ?: false -> if (semester == 1) TYPE_SEMESTER1_PROPOSED else TYPE_SEMESTER2_PROPOSED
weight, grade.getBoolean("IsFinal") ?: false -> TYPE_YEAR_FINAL
semester, grade.getBoolean("IsFinalProposition") ?: false -> TYPE_YEAR_PROPOSED
teacherId, else -> TYPE_NORMAL
subjectId },
value = value,
weight = weight,
color = category?.color ?: -1,
category = category?.text ?: "",
description = description,
comment = null,
semester = semester,
teacherId = teacherId,
subjectId = subjectId
) )
when {
grade.getBoolean("IsConstituent") ?: false ->
gradeObject.type = TYPE_NORMAL
grade.getBoolean("IsSemester") ?: false -> // semester final
gradeObject.type = if (gradeObject.semester == 1) TYPE_SEMESTER1_FINAL else TYPE_SEMESTER2_FINAL
grade.getBoolean("IsSemesterProposition") ?: false -> // semester proposed
gradeObject.type = if (gradeObject.semester == 1) TYPE_SEMESTER1_PROPOSED else TYPE_SEMESTER2_PROPOSED
grade.getBoolean("IsFinal") ?: false -> // year final
gradeObject.type = TYPE_YEAR_FINAL
grade.getBoolean("IsFinalProposition") ?: false -> // year final
gradeObject.type = TYPE_YEAR_PROPOSED
}
grade.getJsonObject("Improvement")?.also { grade.getJsonObject("Improvement")?.also {
val historicalId = it.getLong("Id") val historicalId = it.getLong("Id")
data.gradeList.firstOrNull { grade -> grade.id == historicalId }?.also { grade -> data.gradeList.firstOrNull { grade -> grade.id == historicalId }?.also { grade ->
@ -111,7 +115,7 @@ class LibrusApiGrades(override val data: DataLibrus,
DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it) DataRemoveModel.Grades.semesterWithType(profile.currentSemester, it)
}) })
data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADES, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_LIBRUS_API_NORMAL_GRADES, SYNC_ALWAYS)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_NORMAL_GRADES)
} }
} ?: onSuccess() } } ?: onSuccess(ENDPOINT_LIBRUS_API_NORMAL_GRADES) }
} }

View File

@ -9,13 +9,15 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_HOMEWORK import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_HOMEWORK
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
class LibrusApiHomework(override val data: DataLibrus, class LibrusApiHomework(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 = "LibrusApiHomework" const val TAG = "LibrusApiHomework"
} }
@ -59,7 +61,7 @@ class LibrusApiHomework(override val data: DataLibrus,
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK)) data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
data.setSyncNext(ENDPOINT_LIBRUS_API_HOMEWORK, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_LIBRUS_API_HOMEWORK, SYNC_ALWAYS)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_HOMEWORK)
} }
} }
} }

View File

@ -11,7 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.LibrusLesson import pl.szczodrzynski.edziennik.data.db.entity.LibrusLesson
class LibrusApiLessons(override val data: DataLibrus, class LibrusApiLessons(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 = "LibrusApiLessons" const val TAG = "LibrusApiLessons"
} }
@ -38,7 +40,7 @@ class LibrusApiLessons(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_LESSONS, 4*DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_LESSONS, 4*DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_LESSONS)
} }
} }
} }

View File

@ -17,7 +17,9 @@ import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
class LibrusApiLuckyNumber(override val data: DataLibrus, class LibrusApiLuckyNumber(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 = "LibrusApiLuckyNumber" const val TAG = "LibrusApiLuckyNumber"
} }
@ -57,7 +59,7 @@ class LibrusApiLuckyNumber(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_LUCKY_NUMBER, syncAt = nextSync) data.setSyncNext(ENDPOINT_LIBRUS_API_LUCKY_NUMBER, syncAt = nextSync)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_LUCKY_NUMBER)
} }
} }
} }

View File

@ -10,7 +10,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
class LibrusApiMe(override val data: DataLibrus, class LibrusApiMe(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 = "LibrusApiMe" const val TAG = "LibrusApiMe"
} }
@ -33,7 +35,7 @@ class LibrusApiMe(override val data: DataLibrus,
buildFullName(user?.getString("FirstName"), user?.getString("LastName")) buildFullName(user?.getString("FirstName"), user?.getString("LastName"))
data.setSyncNext(ENDPOINT_LIBRUS_API_ME, 2*DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_ME, 2*DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_ME)
} }
} }
} }

View File

@ -11,7 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.NoticeType import pl.szczodrzynski.edziennik.data.db.entity.NoticeType
class LibrusApiNoticeTypes(override val data: DataLibrus, class LibrusApiNoticeTypes(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 = "LibrusApiNoticeTypes" const val TAG = "LibrusApiNoticeTypes"
} }
@ -28,7 +30,7 @@ class LibrusApiNoticeTypes(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICE_TYPES, 4*DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICE_TYPES, 4*DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_NOTICE_TYPES)
} }
} }
} }

View File

@ -9,13 +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_NOTICES import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_NOTICES
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.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.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
class LibrusApiNotices(override val data: DataLibrus, class LibrusApiNotices(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 = "LibrusApiNotices" const val TAG = "LibrusApiNotices"
} }
@ -65,7 +67,7 @@ class LibrusApiNotices(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICES, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_LIBRUS_API_NOTICES, SYNC_ALWAYS)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_NOTICES)
} }
} }
} }

View File

@ -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 LibrusApiPointGradeCategories(override val data: DataLibrus, class LibrusApiPointGradeCategories(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 = "LibrusApiPointGradeCategories" const val TAG = "LibrusApiPointGradeCategories"
} }
@ -44,7 +46,7 @@ class LibrusApiPointGradeCategories(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES, 1 * DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES, 1 * DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_POINT_GRADE_CATEGORIES)
} }
} }
} }

View File

@ -9,15 +9,17 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_POINT_GRADES import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_POINT_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_POINT_AVG import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_AVG
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 LibrusApiPointGrades(override val data: DataLibrus, class LibrusApiPointGrades(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 = "LibrusApiPointGrades" const val TAG = "LibrusApiPointGrades"
} }
@ -42,19 +44,20 @@ class LibrusApiPointGrades(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 = name,
category?.color ?: -1, type = TYPE_POINT_AVG,
"", value = value,
name, weight = category?.weight ?: 0f,
value, color = category?.color ?: -1,
category?.weight ?: 0f, category = category?.text ?: "",
semester, description = null,
teacherId, comment = null,
subjectId semester = semester,
teacherId = teacherId,
subjectId = subjectId
).apply { ).apply {
type = TYPE_POINT_AVG
valueMax = category?.valueTo ?: 0f valueMax = category?.valueTo ?: 0f
} }
@ -72,7 +75,7 @@ class LibrusApiPointGrades(override val data: DataLibrus,
data.toRemove.add(DataRemoveModel.Grades.semesterWithType(profile.currentSemester, TYPE_POINT_AVG)) data.toRemove.add(DataRemoveModel.Grades.semesterWithType(profile.currentSemester, TYPE_POINT_AVG))
data.setSyncNext(ENDPOINT_LIBRUS_API_POINT_GRADES, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_LIBRUS_API_POINT_GRADES, SYNC_ALWAYS)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_POINT_GRADES)
} }
} ?: onSuccess() } } ?: onSuccess(ENDPOINT_LIBRUS_API_POINT_GRADES) }
} }

View File

@ -15,7 +15,9 @@ import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
class LibrusApiPtMeetings(override val data: DataLibrus, class LibrusApiPtMeetings(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 = "LibrusApiPtMeetings" const val TAG = "LibrusApiPtMeetings"
} }
@ -65,7 +67,7 @@ class LibrusApiPtMeetings(override val data: DataLibrus,
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_PT_MEETING)) data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_PT_MEETING))
data.setSyncNext(ENDPOINT_LIBRUS_API_PT_MEETINGS, 12*HOUR) data.setSyncNext(ENDPOINT_LIBRUS_API_PT_MEETINGS, 12*HOUR)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_PT_MEETINGS)
} }
} }
} }

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) Kuba Szczodrzyński 2020-2-21.
*/
package pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.api
import pl.szczodrzynski.edziennik.JsonObject
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.DataLibrus
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.ENDPOINT_LIBRUS_API_PUSH_CONFIG
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.getInt
import pl.szczodrzynski.edziennik.getJsonObject
class LibrusApiPushConfig(override val data: DataLibrus,
override val lastSync: Long?,
val onSuccess: (endpointId: Int) -> Unit
) : LibrusApi(data, lastSync) {
companion object {
const val TAG = "LibrusApiPushConfig"
}
init { data.app.config.sync.tokenLibrus?.also { tokenLibrus ->
apiGet(TAG, "ChangeRegister", payload = JsonObject(
"provider" to "FCM",
"device" to tokenLibrus,
"sendPush" to "1",
"appVersion" to 4
)) { json ->
json.getJsonObject("ChangeRegister")?.getInt("Id")?.let { data.pushDeviceId = it }
// sync always: this endpoint has .shouldSync set
data.setSyncNext(ENDPOINT_LIBRUS_API_PUSH_CONFIG, SYNC_ALWAYS)
data.app.config.sync.tokenLibrusList =
data.app.config.sync.tokenLibrusList + profileId
onSuccess(ENDPOINT_LIBRUS_API_PUSH_CONFIG)
}
} ?: onSuccess(ENDPOINT_LIBRUS_API_PUSH_CONFIG) }
}

View File

@ -13,7 +13,9 @@ import pl.szczodrzynski.edziennik.utils.models.Time
import java.util.* import java.util.*
class LibrusApiSchools(override val data: DataLibrus, class LibrusApiSchools(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 = "LibrusApiSchools" const val TAG = "LibrusApiSchools"
} }
@ -48,7 +50,7 @@ class LibrusApiSchools(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_SCHOOLS, 4 * DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_SCHOOLS, 4 * DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_SCHOOLS)
} }
} }
} }

View File

@ -11,7 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.Subject import pl.szczodrzynski.edziennik.data.db.entity.Subject
class LibrusApiSubjects(override val data: DataLibrus, class LibrusApiSubjects(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 = "LibrusApiSubjects" const val TAG = "LibrusApiSubjects"
} }
@ -31,7 +33,7 @@ class LibrusApiSubjects(override val data: DataLibrus,
data.subjectList.put(1, Subject(profileId, 1, "Zachowanie", "zach")) data.subjectList.put(1, Subject(profileId, 1, "Zachowanie", "zach"))
data.setSyncNext(ENDPOINT_LIBRUS_API_SUBJECTS, 4*DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_SUBJECTS, 4*DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_SUBJECTS)
} }
} }
} }

View File

@ -11,7 +11,9 @@ import pl.szczodrzynski.edziennik.data.api.edziennik.librus.data.LibrusApi
import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsenceType import pl.szczodrzynski.edziennik.data.db.entity.TeacherAbsenceType
class LibrusApiTeacherFreeDayTypes(override val data: DataLibrus, class LibrusApiTeacherFreeDayTypes(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 = "LibrusApiTeacherFreeDayTypes" const val TAG = "LibrusApiTeacherFreeDayTypes"
} }
@ -34,7 +36,7 @@ class LibrusApiTeacherFreeDayTypes(override val data: DataLibrus,
} }
data.setSyncNext(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES, 7 * DAY) data.setSyncNext(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES, 7 * DAY)
onSuccess() onSuccess(ENDPOINT_LIBRUS_API_TEACHER_FREE_DAY_TYPES)
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More