From 0bf2026a64b7ce21c568b713fd6c7e5c94f852eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Sun, 29 Sep 2019 17:19:38 +0200 Subject: [PATCH] [APIv2] Add API Service. Update other APIv2 components. Update Profile DAO --- app/src/main/AndroidManifest.xml | 2 + .../java/pl/szczodrzynski/edziennik/App.java | 8 +- .../pl/szczodrzynski/edziennik/Extensions.kt | 10 ++ .../szczodrzynski/edziennik/MainActivity.kt | 2 +- .../edziennik/WidgetTimetable.java | 2 +- .../edziennik/api/Edziennik.java | 30 ++-- .../edziennik/api/Iuczniowie.java | 4 +- .../szczodrzynski/edziennik/api/Librus.java | 6 +- .../edziennik/api/Mobidziennik.java | 4 +- .../szczodrzynski/edziennik/api/Vulcan.java | 4 +- ...erface.java => OldEdziennikInterface.java} | 2 +- .../edziennik/api/v2/ApiService.kt | 158 ++++++++++++++++++ .../edziennik/api/v2/Constants.kt | 14 +- .../edziennik/api/v2/Endpoints.kt | 130 ++++++++++++-- .../szczodrzynski/edziennik/api/v2/Errors.kt | 21 ++- .../edziennik/api/v2/Features.kt | 87 ++++++++++ .../edziennik/api/v2/LoginMethods.kt | 37 ++-- .../edziennik/api/v2/events/SyncErrorEvent.kt | 9 + .../api/v2/events/SyncFinishedEvent.kt | 7 + .../api/v2/events/SyncProfileFinishedEvent.kt | 7 + .../api/v2/events/SyncProgressEvent.kt | 7 + .../api/v2/events/SyncStartedEvent.kt | 7 + .../v2/events/requests/MessageGetRequest.kt | 13 ++ .../v2/events/requests/SyncProfileRequest.kt | 13 ++ .../api/v2/events/requests/SyncRequest.kt | 7 + .../api/v2/events/requests/SyncViewRequest.kt | 13 ++ .../api/v2/interfaces/EdziennikCallback.kt | 17 ++ .../api/v2/interfaces/EdziennikInterface.kt | 10 ++ .../api/v2/interfaces/EndpointCallback.kt | 18 ++ .../api/v2/interfaces/ILoginMethod.kt | 20 --- .../edziennik/api/v2/librus/Librus.kt | 14 +- .../edziennik/api/v2/librus/LibrusOld.kt | 4 +- .../edziennik/api/v2/librus/LibrusTest.kt | 14 +- .../api/v2/librus/login/LoginLibrus.kt | 5 +- .../api/v2/librus/login/LoginLibrusApi.kt | 11 +- .../v2/librus/login/LoginLibrusMessages.kt | 3 +- .../api/v2/librus/login/LoginLibrusPortal.kt | 85 ++++++---- .../v2/librus/login/LoginLibrusSynergia.kt | 8 +- .../v2/librus/login/SynergiaTokenExtractor.kt | 124 +++++++------- .../edziennik/api/v2/models/ApiError.kt | 38 +++++ .../edziennik/api/v2/models/ApiLoginResult.kt | 6 - .../edziennik/api/v2/models/ApiTask.kt | 9 + .../edziennik/api/v2/models/Data.kt | 31 +++- .../edziennik/api/v2/models/Endpoint.kt | 17 +- .../edziennik/api/v2/models/Feature.kt | 11 -- .../edziennik/api/v2/models/Features.kt | 13 -- .../api/v2/models/FirstLoginResult.kt | 6 - .../edziennik/api/v2/models/LoginMethod.kt | 28 +++- .../edziennik/datamodels/ProfileDao.java | 8 +- .../edziennik/dialogs/EventManualDialog.java | 2 +- .../luckynumber/WidgetLuckyNumber.java | 2 +- 51 files changed, 843 insertions(+), 265 deletions(-) rename app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/{EdziennikInterface.java => OldEdziennikInterface.java} (99%) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncErrorEvent.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncFinishedEvent.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProfileFinishedEvent.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProgressEvent.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/MessageGetRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncViewRequest.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikCallback.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EndpointCallback.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/ILoginMethod.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiLoginResult.kt create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiTask.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Feature.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Features.kt delete mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/FirstLoginResult.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1fbc04ec..f5f02d8b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -218,6 +218,8 @@ android:name=".sync.SyncService" android:icon="@mipmap/ic_launcher" android:label="@string/sync_service" /> + + diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/App.java b/app/src/main/java/pl/szczodrzynski/edziennik/App.java index a1360f8d..2938bec2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/App.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/App.java @@ -19,7 +19,6 @@ import android.provider.Settings; import android.util.Base64; import android.util.Log; import android.util.Pair; -import android.widget.Toast; import com.chuckerteam.chucker.api.ChuckerCollector; import com.chuckerteam.chucker.api.ChuckerInterceptor; @@ -81,7 +80,6 @@ import pl.szczodrzynski.edziennik.datamodels.ProfileFull; import pl.szczodrzynski.edziennik.models.AppConfig; import pl.szczodrzynski.edziennik.network.NetworkUtils; import pl.szczodrzynski.edziennik.network.TLSSocketFactory; -import pl.szczodrzynski.edziennik.receivers.BootReceiver; import pl.szczodrzynski.edziennik.receivers.JobsCreator; import pl.szczodrzynski.edziennik.sync.SyncJob; import pl.szczodrzynski.edziennik.utils.PermissionChecker; @@ -617,7 +615,7 @@ public class App extends androidx.multidex.MultiDexApplication { } public ProfileFull profileGetOrNull(int id) { - return db.profileDao().getByIdNow(id); + return db.profileDao().getFullByIdNow(id); } public void profileLoadById(int id) { @@ -632,7 +630,7 @@ public class App extends androidx.multidex.MultiDexApplication { return; }*/ if (profile == null || profile.getId() != id) { - profile = db.profileDao().getByIdNow(id); + profile = db.profileDao().getFullByIdNow(id); /*if (profile == null) { profileLoadById(id); return; @@ -659,7 +657,7 @@ public class App extends androidx.multidex.MultiDexApplication { /*public void profileRemove(int id) { - Profile profile = db.profileDao().getByIdNow(id); + Profile profile = db.profileDao().getFullByIdNow(id); if (profile.id == profile.loginStoreId) { // this profile is the owner of the login store diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt index a6a8ab76..ac4d5366 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/Extensions.kt @@ -10,10 +10,13 @@ import androidx.core.app.ActivityCompat import com.google.gson.JsonArray import com.google.gson.JsonElement import com.google.gson.JsonObject +import im.wangchao.mhttp.Response import pl.szczodrzynski.edziennik.datamodels.Profile import pl.szczodrzynski.edziennik.datamodels.Teacher import pl.szczodrzynski.navlib.crc16 import pl.szczodrzynski.navlib.getColorFromRes +import java.text.SimpleDateFormat +import java.util.* fun List.byId(id: Long) = firstOrNull { it.id == id } @@ -117,4 +120,11 @@ fun Activity.isStoragePermissionGranted(): Boolean { } else { true } +} + +fun Response?.getUnixDate(): Long { + val rfcDate = this?.headers()?.get("date") ?: return currentTimeUnix() + val pattern = "EEE, dd MMM yyyy HH:mm:ss Z" + val format = SimpleDateFormat(pattern, Locale.ENGLISH) + return format.parse(rfcDate).time / 1000 } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt index 1316a91a..414c41f7 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/MainActivity.kt @@ -41,7 +41,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IProfile import pl.droidsonroids.gif.GifDrawable import pl.szczodrzynski.edziennik.App.APP_URL import pl.szczodrzynski.edziennik.api.AppError -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.* +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.* import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding import pl.szczodrzynski.edziennik.datamodels.LoginStore diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java b/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java index 8a2fe720..4f7fb527 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/WidgetTimetable.java @@ -244,7 +244,7 @@ public class WidgetTimetable extends AppWidgetProvider { filterOutArchived(profileList); } else { - Profile profile = app.db.profileDao().getByIdNow(widgetConfig.profileId); + Profile profile = app.db.profileDao().getFullByIdNow(widgetConfig.profileId); if (profile != null) { profileList.add(profile); } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/Edziennik.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/Edziennik.java index e3091ac9..f5125615 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/Edziennik.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/Edziennik.java @@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.WidgetTimetable; -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface; +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface; import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback; import pl.szczodrzynski.edziennik.datamodels.AnnouncementFull; import pl.szczodrzynski.edziennik.datamodels.Attendance; @@ -81,16 +81,16 @@ import static pl.szczodrzynski.edziennik.api.AppError.CODE_PROFILE_ARCHIVED; import static pl.szczodrzynski.edziennik.api.AppError.CODE_PROFILE_NOT_FOUND; import static pl.szczodrzynski.edziennik.api.AppError.stringErrorCode; import static pl.szczodrzynski.edziennik.api.AppError.stringErrorType; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_AGENDA; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ALL; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ANNOUNCEMENTS; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ATTENDANCES; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_GRADES; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_HOMEWORKS; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_MESSAGES_INBOX; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_MESSAGES_OUTBOX; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_NOTICES; -import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_TIMETABLE; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_AGENDA; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ALL; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ANNOUNCEMENTS; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ATTENDANCES; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_GRADES; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_HOMEWORKS; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_MESSAGES_INBOX; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_MESSAGES_OUTBOX; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_NOTICES; +import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_TIMETABLE; import static pl.szczodrzynski.edziennik.datamodels.Event.TYPE_HOMEWORK; import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_FINAL; import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_PROPOSED; @@ -115,7 +115,7 @@ public class Edziennik { private static boolean registerEmpty; public static int oldLuckyNumber; - public static EdziennikInterface getApi(App app, int loginType) { + public static OldEdziennikInterface getApi(App app, int loginType) { switch (loginType) { default: case LOGIN_TYPE_MOBIDZIENNIK: @@ -625,7 +625,7 @@ public class Edziennik { * Used in services, login form and {@code guiSync} *

* May be ran on worker thread. - * {@link EdziennikInterface}.sync is ran always on worker thread. + * {@link OldEdziennikInterface}.sync is ran always on worker thread. * Every callback is ran on the UI thread. * * @param app @@ -676,7 +676,7 @@ public class Edziennik { } }; AsyncTask.execute(() -> { - ProfileFull profile = app.db.profileDao().getByIdNow(profileId); + ProfileFull profile = app.db.profileDao().getFullByIdNow(profileId); if (profile != null) { if (profile.getArchived()) { @@ -1130,7 +1130,7 @@ public class Edziennik { .show(); } public void removeProfile(int profileId) { - Profile profileObject = app.db.profileDao().getByIdNow(profileId); + Profile profileObject = app.db.profileDao().getFullByIdNow(profileId); if (profileObject == null) return; app.db.announcementDao().clear(profileId); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/Iuczniowie.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/Iuczniowie.java index ca74dee7..17b6cc9c 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/Iuczniowie.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/Iuczniowie.java @@ -35,7 +35,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback; -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface; +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface; import pl.szczodrzynski.edziennik.api.interfaces.LoginCallback; import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback; import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback; @@ -91,7 +91,7 @@ import static pl.szczodrzynski.edziennik.utils.Utils.crc32; import static pl.szczodrzynski.edziennik.utils.Utils.d; import static pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue; -public class Iuczniowie implements EdziennikInterface { +public class Iuczniowie implements OldEdziennikInterface { public Iuczniowie(App app) { this.app = app; } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/Librus.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/Librus.java index 4a552dd8..0199f8f0 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/Librus.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/Librus.java @@ -46,7 +46,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback; -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface; +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface; import pl.szczodrzynski.edziennik.api.interfaces.LoginCallback; import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback; import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback; @@ -131,7 +131,7 @@ import static pl.szczodrzynski.edziennik.utils.Utils.d; import static pl.szczodrzynski.edziennik.utils.Utils.getGradeValue; import static pl.szczodrzynski.edziennik.utils.Utils.strToInt; -public class Librus implements EdziennikInterface { +public class Librus implements OldEdziennikInterface { public Librus(App app) { this.app = app; } @@ -2537,7 +2537,7 @@ public class Librus implements EdziennikInterface { && (el = obj.get("Id")) != null) { type = el.getAsInt(); } - /*EventType typeObject = app.db.eventTypeDao().getByIdNow(profileId, type); + /*EventType typeObject = app.db.eventTypeDao().getFullByIdNow(profileId, type); if (typeObject == null) { getCustomTypes = true; }*/ diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/Mobidziennik.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/Mobidziennik.java index 71c200b8..b931ea22 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/Mobidziennik.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/Mobidziennik.java @@ -41,7 +41,7 @@ import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.BuildConfig; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback; -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface; +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface; import pl.szczodrzynski.edziennik.api.interfaces.LoginCallback; import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback; import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback; @@ -99,7 +99,7 @@ import static pl.szczodrzynski.edziennik.utils.Utils.d; import static pl.szczodrzynski.edziennik.utils.Utils.monthFromName; import static pl.szczodrzynski.edziennik.utils.Utils.strToInt; -public class Mobidziennik implements EdziennikInterface { +public class Mobidziennik implements OldEdziennikInterface { public Mobidziennik(App app) { this.app = app; } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/Vulcan.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/Vulcan.java index 32705060..a4838253 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/Vulcan.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/Vulcan.java @@ -36,7 +36,7 @@ import okio.Buffer; import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback; -import pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface; +import pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface; import pl.szczodrzynski.edziennik.api.interfaces.LoginCallback; import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback; import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback; @@ -93,7 +93,7 @@ import static pl.szczodrzynski.edziennik.utils.Utils.getGradeValue; import static pl.szczodrzynski.edziennik.utils.Utils.getVulcanGradeColor; import static pl.szczodrzynski.edziennik.utils.Utils.intToStr; -public class Vulcan implements EdziennikInterface { +public class Vulcan implements OldEdziennikInterface { public Vulcan(App app) { this.app = app; } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/EdziennikInterface.java b/app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/OldEdziennikInterface.java similarity index 99% rename from app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/EdziennikInterface.java rename to app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/OldEdziennikInterface.java index d7bcde5f..47014ad1 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/EdziennikInterface.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/interfaces/OldEdziennikInterface.java @@ -14,7 +14,7 @@ import pl.szczodrzynski.edziennik.datamodels.ProfileFull; import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo; import pl.szczodrzynski.edziennik.models.Endpoint; -public interface EdziennikInterface { +public interface OldEdziennikInterface { /** * Sync all Edziennik data. diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt new file mode 100644 index 00000000..97732a36 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/ApiService.kt @@ -0,0 +1,158 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2 + +import android.app.Service +import android.content.Intent +import android.os.IBinder +import android.util.Log +import androidx.core.app.NotificationCompat +import org.greenrobot.eventbus.EventBus +import org.greenrobot.eventbus.Subscribe +import org.greenrobot.eventbus.ThreadMode +import pl.szczodrzynski.edziennik.App +import pl.szczodrzynski.edziennik.R +import pl.szczodrzynski.edziennik.api.v2.events.requests.MessageGetRequest +import pl.szczodrzynski.edziennik.api.v2.events.SyncProgressEvent +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncProfileRequest +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncRequest +import pl.szczodrzynski.edziennik.api.v2.events.requests.SyncViewRequest +import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback +import pl.szczodrzynski.edziennik.api.v2.librus.Librus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError +import pl.szczodrzynski.edziennik.api.v2.models.ApiTask +import pl.szczodrzynski.edziennik.datamodels.LoginStore +import pl.szczodrzynski.edziennik.datamodels.Profile +import kotlin.math.min + +class ApiService : Service() { + companion object { + const val TAG = "ApiService" + const val NOTIFICATION_API_CHANNEL_ID = "pl.szczodrzynski.edziennik.GET_DATA" + } + + private val app by lazy { applicationContext as App } + + private val taskQueue = mutableListOf() + private val errorList = mutableListOf() + + private var taskRunning = false + private var taskRunningId = -1 + private var taskMaximumId = 0 + + private var taskProfileId = -1 + private var taskProfileName: String? = null + private var taskProgress = 0 + private var taskProgressRes: Int? = null + + private val taskCallback = object : EdziennikCallback { + override fun onCompleted() { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun onError(apiError: ApiError) { + TODO("not implemented") //To change body of created functions use File | Settings | File Templates. + } + + override fun onProgress(step: Int) { + taskProgress += step + taskProgress = min(100, taskProgress) + EventBus.getDefault().post(SyncProgressEvent(taskProfileId, taskProfileName, taskProgress, taskProgressRes)) + } + + override fun onStartProgress(stringRes: Int) { + + } + } + + private fun sync() { + if (taskRunning) + return + if (taskQueue.size <= 0) + return // TODO stopSelf() or sth + + val task = taskQueue.removeAt(0) + taskRunning = true + taskRunningId = task.taskId + + // get the requested profile and login store + val profile: Profile? = app.db.profileDao().getByIdNow(task.profileId) + if (profile == null || !profile.syncEnabled) { + return + } + val loginStore: LoginStore? = app.db.loginStoreDao().getByIdNow(profile.loginStoreId) + if (loginStore == null) { + return + } + // save the profile ID and name as the current task's + taskProfileId = profile.id + taskProfileName = profile.name + taskProgress = 0 + taskProgressRes = null + + + val edziennikInterface = when (loginStore.type) { + LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback) + else -> null + } + if (edziennikInterface == null) { + return + } + + when (task) { + is SyncProfileRequest -> edziennikInterface.sync(task.featureIds ?: Features.getAllIds()) + is SyncViewRequest -> edziennikInterface.sync(Features.getIdsByView(task.targetId)) + is MessageGetRequest -> edziennikInterface.getMessage(task.messageId) + } + } + + + @Subscribe(threadMode = ThreadMode.ASYNC) + fun onSyncRequest(syncRequest: SyncRequest) { + app.db.profileDao().idsForSyncNow.forEach { id -> + taskQueue += SyncProfileRequest(id, null) + } + sync() + } + + @Subscribe(threadMode = ThreadMode.ASYNC) + fun onSyncProfileRequest(syncProfileRequest: SyncProfileRequest) { + Log.d(TAG, syncProfileRequest.toString()) + taskQueue += syncProfileRequest + sync() + } + + @Subscribe(threadMode = ThreadMode.ASYNC) + fun onMessageGetRequest(messageGetRequest: MessageGetRequest) { + Log.d(TAG, messageGetRequest.toString()) + taskQueue += messageGetRequest + sync() + } + + private val notification by lazy { + NotificationCompat.Builder(this, NOTIFICATION_API_CHANNEL_ID) + .setContentTitle("API") + .setContentText("API is running") + .setSmallIcon(R.drawable.ic_notification) + .build() + } + + override fun onCreate() { + EventBus.getDefault().register(this) + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + startForeground(1, notification) + return START_NOT_STICKY + } + + override fun onDestroy() { + EventBus.getDefault().unregister(this) + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt index b80d8494..4992b519 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Constants.kt @@ -4,18 +4,6 @@ package pl.szczodrzynski.edziennik.api.v2 -internal const val FEATURE_ANY = -1 -const val FEATURE_ALL = 0 -const val FEATURE_TIMETABLE = 1 -const val FEATURE_AGENDA = 2 -const val FEATURE_GRADES = 3 -const val FEATURE_HOMEWORKS = 4 -const val FEATURE_NOTICES = 5 -const val FEATURE_ATTENDANCES = 6 -const val FEATURE_MESSAGES_INBOX = 7 -const val FEATURE_MESSAGES_OUTBOX = 8 -const val FEATURE_ANNOUNCEMENTS = 9 - const val LIBRUS_USER_AGENT = "Dalvik/2.1.0 Android LibrusMobileApp" 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" @@ -42,7 +30,7 @@ const val LIBRUS_JST_DEMO_CODE = "68656A21" const val LIBRUS_JST_DEMO_PIN = "1290" /** https://synergia.librus.pl/loguj/token/TOKEN/przenies */ -const val LIBRUS_SYNERGIA_TOKEN_LOGIN_URL = "https://synergia.librus.pl/loguj/token/TOKEN/przenies/" +const val LIBRUS_SYNERGIA_TOKEN_LOGIN_URL = "https://synergia.librus.pl/loguj/token/TOKEN/przenies" const val LIBRUS_MESSAGES_URL = "https://wiadomosci.librus.pl/module/" const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action=" \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt index 8def0345..940fbf57 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Endpoints.kt @@ -4,20 +4,130 @@ package pl.szczodrzynski.edziennik.api.v2 -import android.util.Log -import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApiGrades -import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusApiMe -import pl.szczodrzynski.edziennik.api.v2.librus.data.LibrusSynergiaGrades import pl.szczodrzynski.edziennik.api.v2.models.Endpoint -const val ENDPOINT_LIBRUS_API_ME = 0 -const val ENDPOINT_LIBRUS_API_GRADES = 0 -const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 0 +const val ENDPOINT_LIBRUS_API_ME = 101 +const val ENDPOINT_LIBRUS_API_SCHOOLS = 102 +const val ENDPOINT_LIBRUS_API_CLASSES = 103 +const val ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES = 104 +const val ENDPOINT_LIBRUS_API_UNITS = 105 +const val ENDPOINT_LIBRUS_API_USERS = 106 +const val ENDPOINT_LIBRUS_API_SUBJECTS = 107 +const val ENDPOINT_LIBRUS_API_CLASSROOMS = 108 +const val ENDPOINT_LIBRUS_API_TIMETABLES = 109 +const val ENDPOINT_LIBRUS_API_SUBSTITUTIONS = 110 +const val ENDPOINT_LIBRUS_API_NORMAL_GC = 111 +const val ENDPOINT_LIBRUS_API_POINT_GC = 112 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC = 113 +const val ENDPOINT_LIBRUS_API_TEXT_GC = 114 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC = 115 +const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GC = 116 +const val ENDPOINT_LIBRUS_API_NORMAL_GRADES = 117 +const val ENDPOINT_LIBRUS_API_POINT_GRADES = 118 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES = 119 +const val ENDPOINT_LIBRUS_API_TEXT_GRADES = 120 +const val ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES = 121 +const val ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES = 122 +const val ENDPOINT_LIBRUS_API_EVENTS = 123 +const val ENDPOINT_LIBRUS_API_EVENT_TYPES = 124 +const val ENDPOINT_LIBRUS_API_HOMEWORK = 125 +const val ENDPOINT_LIBRUS_API_LUCKY_NUMBER = 126 +const val ENDPOINT_LIBRUS_API_NOTICES = 127 +const val ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES = 128 +const val ENDPOINT_LIBRUS_API_ATTENDANCE = 129 +const val ENDPOINT_LIBRUS_API_ANNOUNCEMENTS = 130 +const val ENDPOINT_LIBRUS_API_PT_MEETINGS = 131 +const val ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS = 132 +const val ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS = 133 +const val ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS = 134 +const val ENDPOINT_LIBRUS_SYNERGIA_INFO = 201 +const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 202 +const val ENDPOINT_LIBRUS_MESSAGES_RECEIVED = 301 +const val ENDPOINT_LIBRUS_MESSAGES_SENT = 302 +const val ENDPOINT_LIBRUS_MESSAGES_TRASH = 303 +const val ENDPOINT_LIBRUS_MESSAGES_RECEIVERS = 304 +const val ENDPOINT_LIBRUS_MESSAGES_GET = 304 val endpoints = listOf( - Endpoint(LOGIN_TYPE_LIBRUS, ENDPOINT_LIBRUS_API_ME, null, LibrusApiMe::class.java) { _, _ -> LOGIN_METHOD_LIBRUS_API}, - Endpoint(LOGIN_TYPE_LIBRUS, 1, listOf(), LibrusSynergiaGrades::class.java) { _, _ -> LOGIN_METHOD_LIBRUS_SYNERGIA }, - Endpoint(LOGIN_TYPE_LIBRUS, 1, listOf(), LibrusApiGrades::class.java) { _, _ -> LOGIN_METHOD_LIBRUS_API } + + // LIBRUS: API + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TIMETABLE, listOf( + ENDPOINT_LIBRUS_API_TIMETABLES, + ENDPOINT_LIBRUS_API_SUBSTITUTIONS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_AGENDA, listOf( + ENDPOINT_LIBRUS_API_EVENTS, + ENDPOINT_LIBRUS_API_EVENT_TYPES, + ENDPOINT_LIBRUS_API_PT_MEETINGS, + ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS, + ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS, + ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf( + ENDPOINT_LIBRUS_API_NORMAL_GC, + ENDPOINT_LIBRUS_API_POINT_GC, + ENDPOINT_LIBRUS_API_DESCRIPTIVE_GC, + ENDPOINT_LIBRUS_API_TEXT_GC, + ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GC, + ENDPOINT_LIBRUS_API_BEHAVIOUR_GC, + ENDPOINT_LIBRUS_API_NORMAL_GRADES, + ENDPOINT_LIBRUS_API_POINT_GRADES, + ENDPOINT_LIBRUS_API_DESCRIPTIVE_GRADES, + ENDPOINT_LIBRUS_API_TEXT_GRADES, + ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES, + ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf( + ENDPOINT_LIBRUS_API_HOMEWORK + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_NOTICES, listOf( + ENDPOINT_LIBRUS_API_NOTICES + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ATTENDANCES, listOf( + ENDPOINT_LIBRUS_API_ATTENDANCE, + ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ANNOUNCEMENTS, listOf( + ENDPOINT_LIBRUS_API_ANNOUNCEMENTS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf( + ENDPOINT_LIBRUS_API_ME + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SCHOOL_INFO, listOf( + ENDPOINT_LIBRUS_API_SCHOOLS, + ENDPOINT_LIBRUS_API_UNITS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASS_INFO, listOf( + ENDPOINT_LIBRUS_API_CLASSES + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEAM_INFO, listOf( + ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_LUCKY_NUMBER, listOf( + ENDPOINT_LIBRUS_API_LUCKY_NUMBER + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEACHERS, listOf( + ENDPOINT_LIBRUS_API_USERS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SUBJECTS, listOf( + ENDPOINT_LIBRUS_API_SUBJECTS + ), LOGIN_METHOD_LIBRUS_API), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASSROOMS, listOf( + ENDPOINT_LIBRUS_API_CLASSROOMS + ), LOGIN_METHOD_LIBRUS_API), + + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf( + ENDPOINT_LIBRUS_SYNERGIA_INFO + ), LOGIN_METHOD_LIBRUS_SYNERGIA), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_NUMBER, listOf( + ENDPOINT_LIBRUS_SYNERGIA_INFO + ), LOGIN_METHOD_LIBRUS_SYNERGIA), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf( + ENDPOINT_LIBRUS_SYNERGIA_GRADES + ), LOGIN_METHOD_LIBRUS_SYNERGIA), + + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_INBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_RECEIVED), LOGIN_METHOD_LIBRUS_MESSAGES), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_OUTBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_SENT), LOGIN_METHOD_LIBRUS_MESSAGES) ) /* diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt index e28d1afe..f352e2a9 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Errors.kt @@ -59,11 +59,6 @@ const val ERROR_LOGIN_LIBRUS_API_OTHER = 131 const val ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING = 132 const val ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED = 133 const val ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR = 134 -const val ERROR_LOGIN_LIBRUS_PORTAL_TOKEN_ERROR = 135 -const val ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_DISCONNECTED = 136 -const val ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_410 = 137 -const val ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND = 138 -const val ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_OTHER = 139 const val ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING = 139 const val ERROR_LIBRUS_API_TOKEN_EXPIRED = 140 const val ERROR_LIBRUS_API_INSUFFICIENT_SCOPES = 141 @@ -83,8 +78,22 @@ const val ERROR_LOGIN_LIBRUS_SYNERGIA_NO_SESSION_ID = 154 const val ERROR_LIBRUS_MESSAGES_ACCESS_DENIED = 155 const val ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED = 156 const val ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID = 157 +const val ERROR_LIBRUS_PORTAL_TOKEN_EXPIRED = 158 +const val ERROR_LIBRUS_PORTAL_API_DISABLED = 159 +const val ERROR_LIBRUS_PORTAL_SYNERGIA_DISCONNECTED = 160 +const val ERROR_LIBRUS_PORTAL_OTHER = 161 +const val ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND = 162 +const val ERROR_LOGIN_LIBRUS_PORTAL_OTHER = 163 +const val ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED = 164 +const val ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED = 165 +const val ERROR_LOGIN_LIBRUS_PORTAL_NO_CLIENT_ID = 166 +const val ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE = 167 +const val ERROR_LOGIN_LIBRUS_PORTAL_NO_REFRESH = 168 +const val ERROR_LOGIN_LIBRUS_PORTAL_NO_REDIRECT = 169 +const val ERROR_LOGIN_LIBRUS_PORTAL_UNSUPPORTED_GRANT = 170 +const val ERROR_LOGIN_LIBRUS_PORTAL_INVALID_CLIENT_ID = 171 const val EXCEPTION_LOGIN_LIBRUS_API_TOKEN = 901 const val EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN = 902 -const val EXCEPTION_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN = 903 +const val EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN = 903 const val EXCEPTION_LIBRUS_API_REQUEST = 904 \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt new file mode 100644 index 00000000..5f4bab44 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Features.kt @@ -0,0 +1,87 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-29. + */ + +package pl.szczodrzynski.edziennik.api.v2 + +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_AGENDA +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ANNOUNCEMENTS +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_ATTENDANCES +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_GRADES +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOME +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_HOMEWORKS +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_MESSAGES +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_NOTICES +import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE +import pl.szczodrzynski.edziennik.datamodels.Message.TYPE_RECEIVED +import pl.szczodrzynski.edziennik.datamodels.Message.TYPE_SENT +import pl.szczodrzynski.edziennik.messages.MessagesFragment +import pl.szczodrzynski.edziennik.messages.MessagesListFragment + +const val FEATURE_ALL = 0 +const val FEATURE_TIMETABLE = 1 +const val FEATURE_AGENDA = 2 +const val FEATURE_GRADES = 3 +const val FEATURE_HOMEWORK = 4 +const val FEATURE_NOTICES = 5 +const val FEATURE_ATTENDANCES = 6 +const val FEATURE_MESSAGES_INBOX = 7 +const val FEATURE_MESSAGES_OUTBOX = 8 +const val FEATURE_ANNOUNCEMENTS = 9 + +const val FEATURE_STUDENT_INFO = 101 +const val FEATURE_STUDENT_NUMBER = 109 +const val FEATURE_SCHOOL_INFO = 102 +const val FEATURE_CLASS_INFO = 103 +const val FEATURE_TEAM_INFO = 104 +const val FEATURE_LUCKY_NUMBER = 105 +const val FEATURE_TEACHERS = 106 +const val FEATURE_SUBJECTS = 107 +const val FEATURE_CLASSROOMS = 108 + +const val FEATURE_MESSAGE_GET = 201 + +object Features { + private fun getAllNecessary(): List = listOf( + FEATURE_STUDENT_INFO, + FEATURE_STUDENT_NUMBER, + FEATURE_SCHOOL_INFO, + FEATURE_CLASS_INFO, + FEATURE_TEAM_INFO, + FEATURE_LUCKY_NUMBER, + FEATURE_TEACHERS, + FEATURE_SUBJECTS, + FEATURE_CLASSROOMS) + + private fun getAllFeatures(): List = listOf( + FEATURE_TIMETABLE, + FEATURE_AGENDA, + FEATURE_GRADES, + FEATURE_HOMEWORK, + FEATURE_NOTICES, + FEATURE_ATTENDANCES, + FEATURE_MESSAGES_INBOX, + FEATURE_MESSAGES_OUTBOX, + FEATURE_ANNOUNCEMENTS) + + fun getAllIds(): List = getAllFeatures() + getAllNecessary() + + fun getIdsByView(targetId: Int): List { + return when (targetId) { + DRAWER_ITEM_HOME -> getAllFeatures() + DRAWER_ITEM_TIMETABLE -> listOf(FEATURE_TIMETABLE) + DRAWER_ITEM_AGENDA -> listOf(FEATURE_AGENDA) + DRAWER_ITEM_GRADES -> listOf(FEATURE_GRADES) + DRAWER_ITEM_MESSAGES -> when (MessagesFragment.pageSelection) { + TYPE_RECEIVED -> listOf(FEATURE_MESSAGES_INBOX) + TYPE_SENT -> listOf(FEATURE_MESSAGES_OUTBOX) + else -> listOf(FEATURE_MESSAGES_INBOX, FEATURE_MESSAGES_OUTBOX) + } + DRAWER_ITEM_HOMEWORKS -> listOf(FEATURE_HOMEWORK) + DRAWER_ITEM_NOTICES -> listOf(FEATURE_NOTICES) + DRAWER_ITEM_ATTENDANCES -> listOf(FEATURE_ATTENDANCES) + DRAWER_ITEM_ANNOUNCEMENTS -> listOf(FEATURE_ANNOUNCEMENTS) + else -> getAllFeatures() + } + getAllNecessary() + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt index 3e5c1fe6..1efc3bd6 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/LoginMethods.kt @@ -10,6 +10,8 @@ import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusMessages import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusSynergia import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod +val SYNERGIA_API_ENABLED = "true".toBoolean() + const val LOGIN_TYPE_MOBIDZIENNIK = 1 const val LOGIN_TYPE_LIBRUS = 2 const val LOGIN_TYPE_IUCZNIOWIE = 3 @@ -37,14 +39,29 @@ const val LOGIN_METHOD_VULCAN_WEB = 100 const val LOGIN_METHOD_VULCAN_API = 200 val librusLoginMethods = listOf( - LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_PORTAL, null, LoginLibrusPortal::class.java) { _, _ -> LOGIN_METHOD_NOT_NEEDED }, - LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_API, null, LoginLibrusApi::class.java) { _, loginStore -> - if (loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL) LOGIN_METHOD_LIBRUS_PORTAL else LOGIN_METHOD_NOT_NEEDED - }, - LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, listOf(FEATURE_GRADES, FEATURE_HOMEWORKS, FEATURE_MESSAGES_INBOX, FEATURE_MESSAGES_OUTBOX), LoginLibrusSynergia::class.java) { profile, _ -> - if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED - }, - LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, listOf(FEATURE_MESSAGES_INBOX, FEATURE_MESSAGES_OUTBOX), LoginLibrusMessages::class.java) { profile, _ -> - if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED - } + LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_PORTAL, LoginLibrusPortal::class.java) + .withIsPossible { _, loginStore -> + loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL + } + .withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }, + + LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_API, LoginLibrusApi::class.java) + .withIsPossible { _, loginStore -> + loginStore.mode != LOGIN_MODE_LIBRUS_SYNERGIA || SYNERGIA_API_ENABLED + } + .withRequiredLoginMethod { _, loginStore -> + if (loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL) LOGIN_METHOD_LIBRUS_PORTAL else LOGIN_METHOD_NOT_NEEDED + }, + + LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, LoginLibrusSynergia::class.java) + .withIsPossible { _, _ -> true } + .withRequiredLoginMethod { profile, _ -> + if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED + }, + + LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, LoginLibrusMessages::class.java) + .withIsPossible { _, _ -> true } + .withRequiredLoginMethod { profile, _ -> + if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED + } ) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncErrorEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncErrorEvent.kt new file mode 100644 index 00000000..27dcff2c --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncErrorEvent.kt @@ -0,0 +1,9 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +import pl.szczodrzynski.edziennik.api.v2.models.ApiError + +class SyncErrorEvent(val error: ApiError) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncFinishedEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncFinishedEvent.kt new file mode 100644 index 00000000..14b6f682 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncFinishedEvent.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +class SyncFinishedEvent \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProfileFinishedEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProfileFinishedEvent.kt new file mode 100644 index 00000000..087b97f6 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProfileFinishedEvent.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +class SyncProfileFinishedEvent(val profileId: Int) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProgressEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProgressEvent.kt new file mode 100644 index 00000000..83cf57d1 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncProgressEvent.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +class SyncProgressEvent(val profileId: Int, val profileName: String?, val progress: Int, val progressRes: Int?) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt new file mode 100644 index 00000000..86e5bb9d --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/SyncStartedEvent.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events + +class SyncStartedEvent(val profileId: Int) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/MessageGetRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/MessageGetRequest.kt new file mode 100644 index 00000000..50527290 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/MessageGetRequest.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +import pl.szczodrzynski.edziennik.api.v2.models.ApiTask + +data class MessageGetRequest(override val profileId: Int, val messageId: Int) : ApiTask(profileId) { + override fun toString(): String { + return "MessageGetRequest(profileId=$profileId, messageId=$messageId)" + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileRequest.kt new file mode 100644 index 00000000..75e21406 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncProfileRequest.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +import pl.szczodrzynski.edziennik.api.v2.models.ApiTask + +data class SyncProfileRequest(override val profileId: Int, val featureIds: List?) : ApiTask(profileId) { + override fun toString(): String { + return "SyncProfileRequest(profileId=$profileId, featureIds=$featureIds)" + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt new file mode 100644 index 00000000..4570d3a4 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncRequest.kt @@ -0,0 +1,7 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +class SyncRequest() \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncViewRequest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncViewRequest.kt new file mode 100644 index 00000000..316850fa --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/events/requests/SyncViewRequest.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-29. + */ + +package pl.szczodrzynski.edziennik.api.v2.events.requests + +import pl.szczodrzynski.edziennik.api.v2.models.ApiTask + +class SyncViewRequest(override val profileId: Int, val targetId: Int) : ApiTask(profileId) { + override fun toString(): String { + return "SyncViewRequest(profileId=$profileId, targetId=$targetId)" + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikCallback.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikCallback.kt new file mode 100644 index 00000000..4e172a9b --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikCallback.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-29. + */ + +package pl.szczodrzynski.edziennik.api.v2.interfaces + +import pl.szczodrzynski.edziennik.api.v2.models.Endpoint +import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod + +/** + * A callback passed only to an e-register class. + * All [Endpoint]s and [LoginMethod]s receive this callback, + * but may only use [EndpointCallback]'s methods. + */ +interface EdziennikCallback : EndpointCallback { + fun onCompleted() +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt new file mode 100644 index 00000000..8265de7e --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EdziennikInterface.kt @@ -0,0 +1,10 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-29. + */ + +package pl.szczodrzynski.edziennik.api.v2.interfaces + +interface EdziennikInterface { + fun sync(featureIds: List) + fun getMessage(messageId: Int) +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EndpointCallback.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EndpointCallback.kt new file mode 100644 index 00000000..5c2717d2 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/EndpointCallback.kt @@ -0,0 +1,18 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-29. + */ + +package pl.szczodrzynski.edziennik.api.v2.interfaces + +import pl.szczodrzynski.edziennik.api.v2.models.ApiError +import pl.szczodrzynski.edziennik.api.v2.models.Endpoint +import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod + +/** + * A callback passed to all [Endpoint]s and [LoginMethod]s + */ +interface EndpointCallback { + fun onError(apiError: ApiError) + fun onProgress(step: Int) + fun onStartProgress(stringRes: Int) +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/ILoginMethod.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/ILoginMethod.kt deleted file mode 100644 index c1834b29..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/interfaces/ILoginMethod.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) Kuba Szczodrzyński 2019-9-20. - */ - -package pl.szczodrzynski.edziennik.api.v2.interfaces - -import pl.szczodrzynski.edziennik.App -import pl.szczodrzynski.edziennik.api.interfaces.ProgressCallback -import pl.szczodrzynski.edziennik.datamodels.LoginStore -import pl.szczodrzynski.edziennik.datamodels.Profile - -abstract class ILoginMethod( - val app: App, - val profile: Profile?, - val loginStore: LoginStore, - val callback: ProgressCallback, - val onSuccess: () -> Unit -) { - -} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt index b00d7901..6289f6b2 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/Librus.kt @@ -9,22 +9,30 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.api.AppError import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 +import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback +import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus -import pl.szczodrzynski.edziennik.api.v2.models.Data import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.Profile import pl.szczodrzynski.edziennik.datamodels.ProfileFull -class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: SyncCallback) { +class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { val internalErrorList = mutableListOf() - lateinit var data: DataLibrus + val data: DataLibrus init { data = DataLibrus(app, profile, loginStore).apply { callback = wrapCallback(this@Librus.callback) } + data.satisfyLoginMethods() + } + override fun sync(featureIds: List) { + + } + + override fun getMessage(messageId: Int) { } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusOld.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusOld.kt index e04437bf..f801e97b 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusOld.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusOld.kt @@ -7,7 +7,6 @@ import pl.szczodrzynski.edziennik.api.interfaces.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.firstlogin.FirstLoginLibrus import pl.szczodrzynski.edziennik.api.v2.librus.firstlogin.FirstLoginSynergia -import pl.szczodrzynski.edziennik.api.v2.librus.login.SynergiaTokenExtractor import pl.szczodrzynski.edziennik.api.v2.models.Data import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.MessageFull @@ -15,10 +14,9 @@ import pl.szczodrzynski.edziennik.datamodels.Profile import pl.szczodrzynski.edziennik.datamodels.ProfileFull import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo import pl.szczodrzynski.edziennik.models.Endpoint -import pl.szczodrzynski.edziennik.utils.Utils.d import java.lang.Exception -class LibrusOld(val app: App, val profile: Profile?, val loginStore: LoginStore) : EdziennikInterface { +class LibrusOld(val app: App, val profile: Profile?, val loginStore: LoginStore) : OldEdziennikInterface { private val TAG = "librus.Librus" lateinit var syncCallback: SyncCallback diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt index c13369f4..a01bc4df 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/LibrusTest.kt @@ -5,6 +5,7 @@ package pl.szczodrzynski.edziennik.api.v2.librus import android.content.Context +import android.content.Intent import com.google.gson.JsonObject import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.api.AppError @@ -30,21 +31,24 @@ class LibrusTest(val app: App) { putStudentData("accountLogin", "1234567") - putStudentData("accountToken", "token") - putStudentData("accountTokenTime", 1569523077) + //putStudentData("accountToken", "token") + //putStudentData("accountTokenTime", 1569458277) } val loginStore = LoginStore(1, LOGIN_TYPE_LIBRUS, JsonObject().apply { addProperty("email", "test@example.com") addProperty("password", "zaq1@WSX") - addProperty("accessToken", "token") - addProperty("refreshToken", "refresh") - addProperty("tokenExpiryTime", 1569523077) + //addProperty("accessToken", "token") + //addProperty("refreshToken", "refresh") + //addProperty("tokenExpiryTime", 1569523077) }).also { it.mode = LOGIN_MODE_LIBRUS_EMAIL } fun go() { + + app.startService(Intent(app, ApiService::class.java)) + val data = DataLibrus(app, profile, loginStore).apply { callback = object : ProgressCallback { override fun onProgress(progressStep: Int) { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrus.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrus.kt index b370305d..e12d6713 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrus.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrus.kt @@ -19,10 +19,11 @@ class LoginLibrus(val data: DataLibrus, vararg loginMethodIds: Int, val onSucces init { for (loginMethodId in loginMethodIds) { - var requiredLoginMethod = loginMethodId + var requiredLoginMethod: Int? = loginMethodId while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) { librusLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod -> - loginMethodList.add(requiredLoginMethod) + if (requiredLoginMethod != null) + loginMethodList.add(requiredLoginMethod!!) requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore) } } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusApi.kt index ca8cf85e..d687fbdb 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusApi.kt @@ -9,14 +9,9 @@ import im.wangchao.mhttp.Request import im.wangchao.mhttp.Response import im.wangchao.mhttp.body.MediaTypeUtils import im.wangchao.mhttp.callback.JsonCallbackHandler -import pl.szczodrzynski.edziennik.api.AppError -import pl.szczodrzynski.edziennik.api.AppError.* +import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus -import pl.szczodrzynski.edziennik.currentTimeUnix -import pl.szczodrzynski.edziennik.getInt -import pl.szczodrzynski.edziennik.getString -import pl.szczodrzynski.edziennik.isNotNullNorEmpty import java.net.HttpURLConnection.* class LoginLibrusApi { @@ -121,7 +116,7 @@ class LoginLibrusApi { data.error(TAG, ERROR_RESPONSE_EMPTY, response) return } - json.getString("error")?.let { error -> + if (response?.code() != 200) json.getString("error")?.let { error -> when (error) { "librus_captcha_needed" -> ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED "connection_problems" -> ERROR_LOGIN_LIBRUS_API_CONNECTION_PROBLEMS @@ -140,7 +135,7 @@ class LoginLibrusApi { try { data.apiAccessToken = json.getString("access_token") data.apiRefreshToken = json.getString("refresh_token") - data.apiTokenExpiryTime = currentTimeUnix() + json.getInt("expires_in", 86400) + data.apiTokenExpiryTime = response.getUnixDate() + json.getInt("expires_in", 86400) onSuccess() } catch (e: NullPointerException) { data.error(TAG, EXCEPTION_LOGIN_LIBRUS_API_TOKEN, response, e, json) diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusMessages.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusMessages.kt index 3af49a01..17581b03 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusMessages.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusMessages.kt @@ -13,6 +13,7 @@ import okhttp3.internal.http.HttpDate import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus import pl.szczodrzynski.edziennik.currentTimeUnix +import pl.szczodrzynski.edziennik.getUnixDate class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { companion object { @@ -73,7 +74,7 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { return } data.messagesSessionId = sessionId - data.messagesSessionIdExpiryTime = currentTimeUnix() + 3600 /* 1h */ + data.messagesSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45min */ onSuccess() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusPortal.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusPortal.kt index b3fbe09b..71bec763 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusPortal.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusPortal.kt @@ -121,7 +121,52 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { private var refreshTokenFailed = false private fun accessToken(code: String?, refreshToken: String?) { - data.callback.onActionStarted(R.string.sync_action_getting_token) + val onSuccess = { json: JsonObject, response: Response? -> + data.portalAccessToken = json.getString("access_token") + data.portalRefreshToken = json.getString("refresh_token") + data.portalTokenExpiryTime = response.getUnixDate() + json.getInt("expires_in", 86400) + onSuccess() + } + + val callback = object : JsonCallbackHandler() { + override fun onSuccess(json: JsonObject?, response: Response?) { + if (json == null) { + data.error(TAG, ERROR_RESPONSE_EMPTY, response) + return + } + val error = if (response?.code() == 200) null else + json.getString("hint") + error?.let { code -> + when (code) { + "Authorization code has expired" -> ERROR_LOGIN_LIBRUS_PORTAL_CODE_EXPIRED + "Authorization code has been revoked" -> ERROR_LOGIN_LIBRUS_PORTAL_CODE_REVOKED + "Check the `client_id` parameter" -> ERROR_LOGIN_LIBRUS_PORTAL_NO_CLIENT_ID + "Check the `code` parameter" -> ERROR_LOGIN_LIBRUS_PORTAL_NO_CODE + "Check the `refresh_token` parameter" -> ERROR_LOGIN_LIBRUS_PORTAL_NO_REFRESH + "Check the `redirect_uri` parameter" -> ERROR_LOGIN_LIBRUS_PORTAL_NO_REDIRECT + else -> when (json.getString("error")) { + "unsupported_grant_type" -> ERROR_LOGIN_LIBRUS_PORTAL_UNSUPPORTED_GRANT + "invalid_client" -> ERROR_LOGIN_LIBRUS_PORTAL_INVALID_CLIENT_ID + else -> ERROR_LOGIN_LIBRUS_PORTAL_OTHER + } + }.let { errorCode -> + data.error(TAG, errorCode, apiResponse = json, response = response) + return + } + } + + try { + onSuccess(json, response) + } catch (e: NullPointerException) { + data.error(TAG, EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN, response, e, json) + } + } + + override fun onFailure(response: Response?, throwable: Throwable?) { + data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + } + } + val params = ArrayList>() params.add(Pair("client_id", LIBRUS_CLIENT_ID)) if (code != null) { @@ -132,46 +177,14 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { params.add(Pair("grant_type", "refresh_token")) params.add(Pair("refresh_token", refreshToken)) } + Request.builder() .url(LIBRUS_TOKEN_URL) .userAgent(LIBRUS_USER_AGENT) .addParams(params) - .allowErrorCode(HTTP_UNAUTHORIZED) .post() - .callback(object : JsonCallbackHandler() { - override fun onSuccess(json: JsonObject?, response: Response) { - if (json == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) - return - } - json.getString("error")?.let { error -> - val hint = json.getString("hint", "") - //val message = json.getString("message", "") - if (!refreshTokenFailed && refreshToken != null && (hint == "Token has been revoked" || hint == "Token has expired")) { - c(TAG, "refreshing the token failed. Trying to log in again.") - refreshTokenFailed = true - authorize(LIBRUS_AUTHORIZE_URL) - return - } - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_TOKEN_ERROR, response, apiResponse = json) - return - } - - try { - data.portalAccessToken = json.getString("access_token") - data.portalRefreshToken = json.getString("refresh_token") - data.portalTokenExpiryTime = currentTimeUnix() + json.getInt("expires_in", 86400) - onSuccess() - } catch (e: NullPointerException) { - data.error(TAG, EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN, response, e, json) - } - - } - - override fun onFailure(response: Response, throwable: Throwable) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) - } - }) + .allowErrorCode(HTTP_UNAUTHORIZED) + .callback(callback) .build() .enqueue() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusSynergia.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusSynergia.kt index a78ee769..7b405304 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusSynergia.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/LoginLibrusSynergia.kt @@ -15,6 +15,7 @@ import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus import pl.szczodrzynski.edziennik.currentTimeUnix import pl.szczodrzynski.edziennik.getString +import pl.szczodrzynski.edziennik.getUnixDate import pl.szczodrzynski.edziennik.isNotNullNorEmpty import java.lang.Exception import java.net.HttpURLConnection @@ -75,7 +76,10 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { data.error(TAG, ERROR_RESPONSE_EMPTY, response) return } - val error = json.getString("Code") ?: json.getString("Message") ?: response?.parserErrorBody + val error = if (response?.code() == 200) null else + json.getString("Code") ?: + json.getString("Message") ?: + response?.parserErrorBody error?.let { code -> when (code) { "TokenIsExpired" -> ERROR_LIBRUS_API_TOKEN_EXPIRED @@ -145,7 +149,7 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { return } data.synergiaSessionId = sessionId - data.synergiaSessionIdExpiryTime = currentTimeUnix() + 3600 /* 1h */ + data.synergiaSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45min */ onSuccess() } else { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt index f771afde..67a49ffb 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/login/SynergiaTokenExtractor.kt @@ -33,16 +33,80 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { } else { if (!synergiaAccount()) { - + data.error(TAG, ERROR_LOGIN_DATA_MISSING) } } }} + /** + * Get an Api token from the Portal account, using Portal API. + * If necessary, refreshes the token. + */ private fun synergiaAccount(): Boolean { val accountLogin = data.apiLogin ?: return false val accessToken = data.portalAccessToken ?: return false - data.callback.onActionStarted(R.string.sync_action_getting_account) - d(TAG, "Requesting " + (LIBRUS_ACCOUNT_URL + accountLogin)) + + val onSuccess = { json: JsonObject, response: Response? -> + // synergiaAccount is executed when a synergia token needs a refresh + val accountId = json.getInt("id") + val accountToken = json.getString("accessToken") + if (accountId == null || accountToken == null) { + data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING, response, apiResponse = json) + } + else { + data.apiAccessToken = accountToken + data.apiTokenExpiryTime = response.getUnixDate() + 6 * 60 * 60 + + // TODO remove this + data.profile?.studentNameLong = json.getString("studentName") + val nameParts = json.getString("studentName")?.split(" ")?.toTypedArray() + data.profile?.studentNameShort = nameParts?.get(0) + " " + nameParts?.get(1)?.get(0) + + onSuccess() + } + } + + val callback = object : JsonCallbackHandler() { + override fun onSuccess(json: JsonObject?, response: Response?) { + if (json == null) { + data.error(TAG, ERROR_RESPONSE_EMPTY, response) + return + } + val error = if (response?.code() == 200) null else + json.getString("reason") ?: + json.getString("message") ?: + json.getString("hint") ?: + json.getString("Code") + error?.let { code -> + when (code) { + "requires_an_action" -> ERROR_LIBRUS_PORTAL_SYNERGIA_DISCONNECTED + "Access token is invalid" -> ERROR_LIBRUS_PORTAL_TOKEN_EXPIRED + "ApiDisabled" -> ERROR_LIBRUS_PORTAL_API_DISABLED + "Account not found" -> ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND + else -> ERROR_LIBRUS_PORTAL_OTHER + }.let { errorCode -> + data.error(TAG, errorCode, apiResponse = json, response = response) + return + } + } + if (response?.code() == HTTP_OK) { + try { + onSuccess(json, response) + } catch (e: NullPointerException) { + e.printStackTrace() + data.error(TAG, EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN, response, e, json) + } + + } else { + data.error(TAG, ERROR_REQUEST_FAILURE, response, apiResponse = json) + } + } + + override fun onFailure(response: Response?, throwable: Throwable?) { + data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + } + } + Request.builder() .url(LIBRUS_ACCOUNT_URL + accountLogin) .userAgent(LIBRUS_USER_AGENT) @@ -53,59 +117,7 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { .allowErrorCode(HTTP_UNAUTHORIZED) .allowErrorCode(HTTP_BAD_REQUEST) .allowErrorCode(HTTP_GONE) - .callback(object : JsonCallbackHandler() { - override fun onSuccess(json: JsonObject?, response: Response) { - if (json == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) - return - } - if (response.code() == 410) { - val reason = json.get("reason") - if (reason != null && reason !is JsonNull && reason.asString == "requires_an_action") { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_DISCONNECTED, response, apiResponse = json) - return - } - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_410, response, apiResponse = json) - return - } - if (json.get("message") != null) { - val message = json.get("message").asString - if (message == "Account not found") { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND, response, apiResponse = json) - return - } - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_OTHER, response, apiResponse = json) - return - } - if (response.code() == HTTP_OK) { - try { - // synergiaAccount is executed when a synergia token needs a refresh - val accountId = json.getInt("id") - val accountToken = json.getString("accessToken") - if (accountId == null || accountToken == null) { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING, response, apiResponse = json) - return - } - data.apiAccessToken = accountToken - data.apiTokenExpiryTime = currentTimeUnix() + 6*60*60 - data.profile?.studentNameLong = json.getString("studentName") - val nameParts = json.getString("studentName")?.split(" ")?.toTypedArray() - data.profile?.studentNameShort = nameParts?.get(0) + " " + nameParts?.get(1)?.get(0) - onSuccess() - } catch (e: NullPointerException) { - e.printStackTrace() - data.error(TAG, EXCEPTION_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN, response, e, json) - } - - } else { - data.error(TAG, ERROR_REQUEST_FAILURE, response, apiResponse = json) - } - } - - override fun onFailure(response: Response, throwable: Throwable) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) - } - }) + .callback(callback) .build() .enqueue() return true diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt new file mode 100644 index 00000000..b83cf514 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiError.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.models + +import com.google.gson.JsonObject +import im.wangchao.mhttp.Request +import im.wangchao.mhttp.Response + +class ApiError(val profileId: Int, val tag: String, val errorCode: Int) { + private var throwable: Throwable? = null + private var apiResponse: String? = null + private var request: Request? = null + private var response: Response? = null + + fun withThrowable(throwable: Throwable?): ApiError { + this.throwable = throwable + return this + } + fun withApiResponse(apiResponse: String?): ApiError { + this.apiResponse = apiResponse + return this + } + fun withApiResponse(apiResponse: JsonObject?): ApiError { + this.apiResponse = apiResponse?.toString() + return this + } + fun withRequest(request: Request?): ApiError { + this.request = request + return this + } + fun withResponse(response: Response?): ApiError { + this.response = response + this.request = response?.request() + return this + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiLoginResult.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiLoginResult.kt deleted file mode 100644 index 366f7a73..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiLoginResult.kt +++ /dev/null @@ -1,6 +0,0 @@ -package pl.szczodrzynski.edziennik.api.v2.models - -import pl.szczodrzynski.edziennik.api.AppError -import pl.szczodrzynski.edziennik.datamodels.LoginStore - -data class ApiLoginResult(val loginStore: LoginStore, val error: AppError?) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiTask.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiTask.kt new file mode 100644 index 00000000..df289ea6 --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/ApiTask.kt @@ -0,0 +1,9 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-9-28. + */ + +package pl.szczodrzynski.edziennik.api.v2.models + +open class ApiTask(open val profileId: Int) { + var taskId: Int = 0 +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt index 7608c756..024bad40 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Data.kt @@ -7,15 +7,24 @@ import com.google.gson.JsonObject import im.wangchao.mhttp.Response import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.api.AppError +import pl.szczodrzynski.edziennik.api.AppError.* import pl.szczodrzynski.edziennik.api.interfaces.ProgressCallback +import pl.szczodrzynski.edziennik.api.v2.interfaces.EndpointCallback import pl.szczodrzynski.edziennik.datamodels.* import pl.szczodrzynski.edziennik.models.Date +import java.io.InterruptedIOException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import javax.net.ssl.SSLException open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) { var fakeLogin = false - lateinit var callback: ProgressCallback + /** + * A callback passed to all [Endpoint]s and [LoginMethod]s + */ + lateinit var callback: EndpointCallback /** * A list of [LoginMethod]s *already fulfilled* during this sync. @@ -152,9 +161,25 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) } fun error(tag: String, errorCode: Int, response: Response? = null, throwable: Throwable? = null, apiResponse: JsonObject? = null) { - callback.onError(null, AppError(tag, 999, errorCode, response, throwable, apiResponse)) + var code = when (throwable) { + is UnknownHostException, is SSLException, is InterruptedIOException -> CODE_NO_INTERNET + is SocketTimeoutException -> CODE_TIMEOUT + else -> when (response?.code()) { + 400, 401, 424, 500, 503, 404 -> CODE_MAINTENANCE + else -> errorCode + } + } + callback.onError(ApiError(profile?.id ?: -1, tag, code).withResponse(response).withThrowable(throwable).withApiResponse(apiResponse)) } fun error(tag: String, errorCode: Int, response: Response? = null, apiResponse: String? = null) { - callback.onError(null, AppError(tag, 999, errorCode, response, null, apiResponse)) + var code = when (null) { + is UnknownHostException, is SSLException, is InterruptedIOException -> CODE_NO_INTERNET + is SocketTimeoutException -> CODE_TIMEOUT + else -> when (response?.code()) { + 400, 401, 424, 500, 503, 404 -> CODE_MAINTENANCE + else -> errorCode + } + } + callback.onError(ApiError(profile?.id ?: -1, tag, code).withResponse(response).withApiResponse(apiResponse)) } } \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Endpoint.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Endpoint.kt index e2c6281b..55167232 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Endpoint.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Endpoint.kt @@ -7,21 +7,18 @@ import pl.szczodrzynski.edziennik.datamodels.Profile * A Endpoint descriptor class. * * The API runs appropriate endpoints in order to fulfill its - * [Feature] list. + * feature list. * An endpoint may have its [LoginMethod] dependencies which will be * satisfied by the API before the [endpointClass]'s constructor is invoked. * * @param loginType type of the e-register this endpoint handles - * @param endpointId a unique ID of this endpoint - * @param featureIds a [List] of [Feature]s (their IDs) this endpoint can download - * May be null if no strict feature set is associated with this method. - * @param endpointClass a [Class] which constructor will be invoked when a data download is needed - * @param requiredLoginMethod a lambda returning a required login method (which will be called before this). May differ depending on the [Profile] and/or [LoginStore]. + * @param featureId a feature ID + * @param endpointIds a [List] of [Endpoint]s that satisfy this feature ID + * @param requiredLoginMethod a required login method, which will have to be executed before this endpoint. */ class Endpoint( val loginType: Int, - val endpointId: Int, - val featureIds: List?, - val endpointClass: Class<*>, - val requiredLoginMethod: (profile: Profile?, loginStore: LoginStore) -> Int + val featureId: Int, + val endpointIds: List, + val requiredLoginMethod: Int ) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Feature.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Feature.kt deleted file mode 100644 index 3ffda1af..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Feature.kt +++ /dev/null @@ -1,11 +0,0 @@ -package pl.szczodrzynski.edziennik.api.v2.models - - - -data class Feature(val featureId: Int, val loginOptions: Map>) { - - init { - - } - -} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Features.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Features.kt deleted file mode 100644 index bf40bd80..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/Features.kt +++ /dev/null @@ -1,13 +0,0 @@ -package pl.szczodrzynski.edziennik.api.v2.models - -import pl.szczodrzynski.edziennik.api.v2.* - -val Features = listOf( - Feature(FEATURE_TIMETABLE, mapOf( - LOGIN_TYPE_LIBRUS to listOf( - LOGIN_MODE_LIBRUS_EMAIL, - LOGIN_MODE_LIBRUS_SYNERGIA, - LOGIN_MODE_LIBRUS_JST - ) - )) -) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/FirstLoginResult.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/FirstLoginResult.kt deleted file mode 100644 index 362846fd..00000000 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/FirstLoginResult.kt +++ /dev/null @@ -1,6 +0,0 @@ -package pl.szczodrzynski.edziennik.api.v2.models - -import pl.szczodrzynski.edziennik.api.AppError -import pl.szczodrzynski.edziennik.datamodels.Profile - -data class FirstLoginResult(val profileList: ArrayList, val error: AppError?) \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/LoginMethod.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/LoginMethod.kt index 3fda0eb1..af14a6ee 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/LoginMethod.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/models/LoginMethod.kt @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.api.v2.models +import pl.szczodrzynski.edziennik.api.v2.LOGIN_METHOD_NOT_NEEDED import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.Profile @@ -16,15 +17,30 @@ import pl.szczodrzynski.edziennik.datamodels.Profile * * @param loginType type of the e-register this login method handles * @param loginMethodId a unique ID of this login method - * @param featureIds a [List] of [Feature]s (their IDs) this login method can provide access to - * May be null if no strict feature set is associated with this method. * @param loginMethodClass a [Class] which constructor will be invoked when a log in is needed - * @param requiredLoginMethod a lambda returning a required login method (which will be called before this). May differ depending on the [Profile] and/or [LoginStore]. + * @param requiredLoginMethod a required login method (which will be called before this). May differ depending on the [Profile] and/or [LoginStore]. */ class LoginMethod( val loginType: Int, val loginMethodId: Int, - val featureIds: List?, val loginMethodClass: Class<*>, - val requiredLoginMethod: (profile: Profile?, loginStore: LoginStore) -> Int -) \ No newline at end of file + private var mIsPossible: ((profile: Profile?, loginStore: LoginStore) -> Boolean)? = null, + private var mRequiredLoginMethod: ((profile: Profile?, loginStore: LoginStore) -> Int)? = null +) { + + fun withIsPossible(isPossible: (profile: Profile?, loginStore: LoginStore) -> Boolean): LoginMethod { + this.mIsPossible = isPossible + return this + } + fun withRequiredLoginMethod(requiredLoginMethod: (profile: Profile?, loginStore: LoginStore) -> Int): LoginMethod { + this.mRequiredLoginMethod = requiredLoginMethod + return this + } + + fun isPossible(profile: Profile?, loginStore: LoginStore): Boolean { + return mIsPossible?.invoke(profile, loginStore) ?: false + } + fun requiredLoginMethod(profile: Profile?, loginStore: LoginStore): Int { + return mRequiredLoginMethod?.invoke(profile, loginStore) ?: LOGIN_METHOD_NOT_NEEDED + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/datamodels/ProfileDao.java b/app/src/main/java/pl/szczodrzynski/edziennik/datamodels/ProfileDao.java index a22aab66..4257a4db 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/datamodels/ProfileDao.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/datamodels/ProfileDao.java @@ -25,7 +25,10 @@ public interface ProfileDao { LiveData getById(int profileId); @Query("SELECT profiles.*, loginStores.loginStoreType, loginStores.loginStoreData FROM profiles LEFT JOIN loginStores ON profiles.loginStoreId = loginStores.loginStoreId WHERE profileId = :profileId") - ProfileFull getByIdNow(int profileId); + ProfileFull getFullByIdNow(int profileId); + + @Query("SELECT* FROM profiles WHERE profileId = :profileId") + Profile getByIdNow(int profileId); @Query("SELECT * FROM profiles WHERE profileId >= 0 ORDER BY profileId") LiveData> getAll(); @@ -45,6 +48,9 @@ public interface ProfileDao { @Query("SELECT * FROM profiles WHERE syncEnabled = 1 AND archived = 0 AND profileId >= 0 ORDER BY profileId") List getProfilesForSyncNow(); + @Query("SELECT profileId FROM profiles WHERE syncEnabled = 1 AND archived = 0 AND profileId >= 0 ORDER BY profileId") + List getIdsForSyncNow(); + @Query("SELECT profileId FROM profiles WHERE profileId >= 0 ORDER BY profileId") List getIdsNow(); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/dialogs/EventManualDialog.java b/app/src/main/java/pl/szczodrzynski/edziennik/dialogs/EventManualDialog.java index 6b5fca15..6654fa62 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/dialogs/EventManualDialog.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/dialogs/EventManualDialog.java @@ -425,7 +425,7 @@ public class EventManualDialog { return; this.app = _app; AsyncTask.execute(() -> { - this.profile = app.db.profileDao().getByIdNow(profileId); + this.profile = app.db.profileDao().getFullByIdNow(profileId); if (profile != null) { ((Activity) context).runOnUiThread(() -> { actualShow(editingEvent, defaultDate, defaultTime, dialogType); diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java index 7c2b847c..df6bfefb 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java +++ b/app/src/main/java/pl/szczodrzynski/edziennik/widgets/luckynumber/WidgetLuckyNumber.java @@ -159,7 +159,7 @@ public class WidgetLuckyNumber extends AppWidgetProvider { } } - Profile profile = app.db.profileDao().getByIdNow(widgetConfig.profileId); + Profile profile = app.db.profileDao().getFullByIdNow(widgetConfig.profileId); IIcon icon = CommunityMaterial.Icon.cmd_emoticon_dead_outline; boolean noNumberText = false; if (profile == null) {