forked from github/szkolny
[APIv2] Add API Service. Update other APIv2 components. Update Profile DAO
This commit is contained in:
parent
5edd4d5922
commit
0bf2026a64
@ -218,6 +218,8 @@
|
|||||||
android:name=".sync.SyncService"
|
android:name=".sync.SyncService"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/sync_service" />
|
android:label="@string/sync_service" />
|
||||||
|
|
||||||
|
<service android:name=".api.v2.ApiService" />
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
@ -19,7 +19,6 @@ import android.provider.Settings;
|
|||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector;
|
import com.chuckerteam.chucker.api.ChuckerCollector;
|
||||||
import com.chuckerteam.chucker.api.ChuckerInterceptor;
|
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.models.AppConfig;
|
||||||
import pl.szczodrzynski.edziennik.network.NetworkUtils;
|
import pl.szczodrzynski.edziennik.network.NetworkUtils;
|
||||||
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
|
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
|
||||||
import pl.szczodrzynski.edziennik.receivers.BootReceiver;
|
|
||||||
import pl.szczodrzynski.edziennik.receivers.JobsCreator;
|
import pl.szczodrzynski.edziennik.receivers.JobsCreator;
|
||||||
import pl.szczodrzynski.edziennik.sync.SyncJob;
|
import pl.szczodrzynski.edziennik.sync.SyncJob;
|
||||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker;
|
import pl.szczodrzynski.edziennik.utils.PermissionChecker;
|
||||||
@ -617,7 +615,7 @@ public class App extends androidx.multidex.MultiDexApplication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ProfileFull profileGetOrNull(int id) {
|
public ProfileFull profileGetOrNull(int id) {
|
||||||
return db.profileDao().getByIdNow(id);
|
return db.profileDao().getFullByIdNow(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void profileLoadById(int id) {
|
public void profileLoadById(int id) {
|
||||||
@ -632,7 +630,7 @@ public class App extends androidx.multidex.MultiDexApplication {
|
|||||||
return;
|
return;
|
||||||
}*/
|
}*/
|
||||||
if (profile == null || profile.getId() != id) {
|
if (profile == null || profile.getId() != id) {
|
||||||
profile = db.profileDao().getByIdNow(id);
|
profile = db.profileDao().getFullByIdNow(id);
|
||||||
/*if (profile == null) {
|
/*if (profile == null) {
|
||||||
profileLoadById(id);
|
profileLoadById(id);
|
||||||
return;
|
return;
|
||||||
@ -659,7 +657,7 @@ public class App extends androidx.multidex.MultiDexApplication {
|
|||||||
|
|
||||||
/*public void profileRemove(int id)
|
/*public void profileRemove(int id)
|
||||||
{
|
{
|
||||||
Profile profile = db.profileDao().getByIdNow(id);
|
Profile profile = db.profileDao().getFullByIdNow(id);
|
||||||
|
|
||||||
if (profile.id == profile.loginStoreId) {
|
if (profile.id == profile.loginStoreId) {
|
||||||
// this profile is the owner of the login store
|
// this profile is the owner of the login store
|
||||||
|
@ -10,10 +10,13 @@ import androidx.core.app.ActivityCompat
|
|||||||
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 im.wangchao.mhttp.Response
|
||||||
import pl.szczodrzynski.edziennik.datamodels.Profile
|
import pl.szczodrzynski.edziennik.datamodels.Profile
|
||||||
import pl.szczodrzynski.edziennik.datamodels.Teacher
|
import pl.szczodrzynski.edziennik.datamodels.Teacher
|
||||||
import pl.szczodrzynski.navlib.crc16
|
import pl.szczodrzynski.navlib.crc16
|
||||||
import pl.szczodrzynski.navlib.getColorFromRes
|
import pl.szczodrzynski.navlib.getColorFromRes
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
fun List<Teacher>.byId(id: Long) = firstOrNull { it.id == id }
|
fun List<Teacher>.byId(id: Long) = firstOrNull { it.id == id }
|
||||||
@ -117,4 +120,11 @@ fun Activity.isStoragePermissionGranted(): Boolean {
|
|||||||
} else {
|
} else {
|
||||||
true
|
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
|
||||||
}
|
}
|
@ -41,7 +41,7 @@ import com.mikepenz.materialdrawer.model.interfaces.IProfile
|
|||||||
import pl.droidsonroids.gif.GifDrawable
|
import pl.droidsonroids.gif.GifDrawable
|
||||||
import pl.szczodrzynski.edziennik.App.APP_URL
|
import pl.szczodrzynski.edziennik.App.APP_URL
|
||||||
import pl.szczodrzynski.edziennik.api.AppError
|
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.api.interfaces.SyncCallback
|
||||||
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
import pl.szczodrzynski.edziennik.databinding.ActivitySzkolnyBinding
|
||||||
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
||||||
|
@ -244,7 +244,7 @@ public class WidgetTimetable extends AppWidgetProvider {
|
|||||||
filterOutArchived(profileList);
|
filterOutArchived(profileList);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Profile profile = app.db.profileDao().getByIdNow(widgetConfig.profileId);
|
Profile profile = app.db.profileDao().getFullByIdNow(widgetConfig.profileId);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
profileList.add(profile);
|
profileList.add(profile);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ import pl.szczodrzynski.edziennik.BuildConfig;
|
|||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.MainActivity;
|
import pl.szczodrzynski.edziennik.MainActivity;
|
||||||
import pl.szczodrzynski.edziennik.WidgetTimetable;
|
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.api.interfaces.SyncCallback;
|
||||||
import pl.szczodrzynski.edziennik.datamodels.AnnouncementFull;
|
import pl.szczodrzynski.edziennik.datamodels.AnnouncementFull;
|
||||||
import pl.szczodrzynski.edziennik.datamodels.Attendance;
|
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.CODE_PROFILE_NOT_FOUND;
|
||||||
import static pl.szczodrzynski.edziennik.api.AppError.stringErrorCode;
|
import static pl.szczodrzynski.edziennik.api.AppError.stringErrorCode;
|
||||||
import static pl.szczodrzynski.edziennik.api.AppError.stringErrorType;
|
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.OldEdziennikInterface.FEATURE_AGENDA;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ALL;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ALL;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ANNOUNCEMENTS;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ANNOUNCEMENTS;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_ATTENDANCES;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_ATTENDANCES;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_GRADES;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_GRADES;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_HOMEWORKS;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_HOMEWORKS;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_MESSAGES_INBOX;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_MESSAGES_INBOX;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_MESSAGES_OUTBOX;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_MESSAGES_OUTBOX;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_NOTICES;
|
import static pl.szczodrzynski.edziennik.api.interfaces.OldEdziennikInterface.FEATURE_NOTICES;
|
||||||
import static pl.szczodrzynski.edziennik.api.interfaces.EdziennikInterface.FEATURE_TIMETABLE;
|
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.Event.TYPE_HOMEWORK;
|
||||||
import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_FINAL;
|
import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_FINAL;
|
||||||
import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_PROPOSED;
|
import static pl.szczodrzynski.edziennik.datamodels.Grade.TYPE_SEMESTER1_PROPOSED;
|
||||||
@ -115,7 +115,7 @@ public class Edziennik {
|
|||||||
private static boolean registerEmpty;
|
private static boolean registerEmpty;
|
||||||
public static int oldLuckyNumber;
|
public static int oldLuckyNumber;
|
||||||
|
|
||||||
public static EdziennikInterface getApi(App app, int loginType) {
|
public static OldEdziennikInterface getApi(App app, int loginType) {
|
||||||
switch (loginType) {
|
switch (loginType) {
|
||||||
default:
|
default:
|
||||||
case LOGIN_TYPE_MOBIDZIENNIK:
|
case LOGIN_TYPE_MOBIDZIENNIK:
|
||||||
@ -625,7 +625,7 @@ public class Edziennik {
|
|||||||
* Used in services, login form and {@code guiSync}
|
* Used in services, login form and {@code guiSync}
|
||||||
* <p>
|
* <p>
|
||||||
* May be ran on worker thread.
|
* 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.
|
* Every callback is ran on the UI thread.
|
||||||
*
|
*
|
||||||
* @param app
|
* @param app
|
||||||
@ -676,7 +676,7 @@ public class Edziennik {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
ProfileFull profile = app.db.profileDao().getByIdNow(profileId);
|
ProfileFull profile = app.db.profileDao().getFullByIdNow(profileId);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
|
|
||||||
if (profile.getArchived()) {
|
if (profile.getArchived()) {
|
||||||
@ -1130,7 +1130,7 @@ public class Edziennik {
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
public void removeProfile(int profileId) {
|
public void removeProfile(int profileId) {
|
||||||
Profile profileObject = app.db.profileDao().getByIdNow(profileId);
|
Profile profileObject = app.db.profileDao().getFullByIdNow(profileId);
|
||||||
if (profileObject == null)
|
if (profileObject == null)
|
||||||
return;
|
return;
|
||||||
app.db.announcementDao().clear(profileId);
|
app.db.announcementDao().clear(profileId);
|
||||||
|
@ -35,7 +35,7 @@ import pl.szczodrzynski.edziennik.App;
|
|||||||
import pl.szczodrzynski.edziennik.BuildConfig;
|
import pl.szczodrzynski.edziennik.BuildConfig;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback;
|
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.LoginCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback;
|
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.d;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue;
|
import static pl.szczodrzynski.edziennik.utils.Utils.getWordGradeValue;
|
||||||
|
|
||||||
public class Iuczniowie implements EdziennikInterface {
|
public class Iuczniowie implements OldEdziennikInterface {
|
||||||
public Iuczniowie(App app) {
|
public Iuczniowie(App app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ import pl.szczodrzynski.edziennik.App;
|
|||||||
import pl.szczodrzynski.edziennik.BuildConfig;
|
import pl.szczodrzynski.edziennik.BuildConfig;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback;
|
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.LoginCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback;
|
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.getGradeValue;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
||||||
|
|
||||||
public class Librus implements EdziennikInterface {
|
public class Librus implements OldEdziennikInterface {
|
||||||
public Librus(App app) {
|
public Librus(App app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
@ -2537,7 +2537,7 @@ public class Librus implements EdziennikInterface {
|
|||||||
&& (el = obj.get("Id")) != null) {
|
&& (el = obj.get("Id")) != null) {
|
||||||
type = el.getAsInt();
|
type = el.getAsInt();
|
||||||
}
|
}
|
||||||
/*EventType typeObject = app.db.eventTypeDao().getByIdNow(profileId, type);
|
/*EventType typeObject = app.db.eventTypeDao().getFullByIdNow(profileId, type);
|
||||||
if (typeObject == null) {
|
if (typeObject == null) {
|
||||||
getCustomTypes = true;
|
getCustomTypes = true;
|
||||||
}*/
|
}*/
|
||||||
|
@ -41,7 +41,7 @@ import pl.szczodrzynski.edziennik.App;
|
|||||||
import pl.szczodrzynski.edziennik.BuildConfig;
|
import pl.szczodrzynski.edziennik.BuildConfig;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback;
|
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.LoginCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback;
|
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.monthFromName;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
import static pl.szczodrzynski.edziennik.utils.Utils.strToInt;
|
||||||
|
|
||||||
public class Mobidziennik implements EdziennikInterface {
|
public class Mobidziennik implements OldEdziennikInterface {
|
||||||
public Mobidziennik(App app) {
|
public Mobidziennik(App app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ import okio.Buffer;
|
|||||||
import pl.szczodrzynski.edziennik.App;
|
import pl.szczodrzynski.edziennik.App;
|
||||||
import pl.szczodrzynski.edziennik.R;
|
import pl.szczodrzynski.edziennik.R;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.AttachmentGetCallback;
|
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.LoginCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
import pl.szczodrzynski.edziennik.api.interfaces.MessageGetCallback;
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.RecipientListGetCallback;
|
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.getVulcanGradeColor;
|
||||||
import static pl.szczodrzynski.edziennik.utils.Utils.intToStr;
|
import static pl.szczodrzynski.edziennik.utils.Utils.intToStr;
|
||||||
|
|
||||||
public class Vulcan implements EdziennikInterface {
|
public class Vulcan implements OldEdziennikInterface {
|
||||||
public Vulcan(App app) {
|
public Vulcan(App app) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import pl.szczodrzynski.edziennik.datamodels.ProfileFull;
|
|||||||
import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo;
|
import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo;
|
||||||
import pl.szczodrzynski.edziennik.models.Endpoint;
|
import pl.szczodrzynski.edziennik.models.Endpoint;
|
||||||
|
|
||||||
public interface EdziennikInterface {
|
public interface OldEdziennikInterface {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sync all Edziennik data.
|
* Sync all Edziennik data.
|
@ -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<ApiTask>()
|
||||||
|
private val errorList = mutableListOf<ApiError>()
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -4,18 +4,6 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.api.v2
|
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 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 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 = "wmSyUMo8llDAs4y9tJVYY92oyZ6h4lAt7KCuy0Gv"
|
||||||
@ -42,7 +30,7 @@ const val LIBRUS_JST_DEMO_CODE = "68656A21"
|
|||||||
const val LIBRUS_JST_DEMO_PIN = "1290"
|
const val LIBRUS_JST_DEMO_PIN = "1290"
|
||||||
|
|
||||||
/** https://synergia.librus.pl/loguj/token/TOKEN/przenies */
|
/** 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_MESSAGES_URL = "https://wiadomosci.librus.pl/module/"
|
||||||
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
const val LIBRUS_SANDBOX_URL = "https://sandbox.librus.pl/index.php?action="
|
@ -4,20 +4,130 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.api.v2
|
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
|
import pl.szczodrzynski.edziennik.api.v2.models.Endpoint
|
||||||
|
|
||||||
const val ENDPOINT_LIBRUS_API_ME = 0
|
const val ENDPOINT_LIBRUS_API_ME = 101
|
||||||
const val ENDPOINT_LIBRUS_API_GRADES = 0
|
const val ENDPOINT_LIBRUS_API_SCHOOLS = 102
|
||||||
const val ENDPOINT_LIBRUS_SYNERGIA_GRADES = 0
|
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(
|
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 },
|
// LIBRUS: API
|
||||||
Endpoint(LOGIN_TYPE_LIBRUS, 1, listOf(), LibrusApiGrades::class.java) { _, _ -> LOGIN_METHOD_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)
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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_CSRF_MISSING = 132
|
||||||
const val ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED = 133
|
const val ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED = 133
|
||||||
const val ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR = 134
|
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_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING = 139
|
||||||
const val ERROR_LIBRUS_API_TOKEN_EXPIRED = 140
|
const val ERROR_LIBRUS_API_TOKEN_EXPIRED = 140
|
||||||
const val ERROR_LIBRUS_API_INSUFFICIENT_SCOPES = 141
|
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_MESSAGES_ACCESS_DENIED = 155
|
||||||
const val ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED = 156
|
const val ERROR_LIBRUS_SYNERGIA_ACCESS_DENIED = 156
|
||||||
const val ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID = 157
|
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_API_TOKEN = 901
|
||||||
const val EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN = 902
|
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
|
const val EXCEPTION_LIBRUS_API_REQUEST = 904
|
@ -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<Int> = 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<Int> = listOf(
|
||||||
|
FEATURE_TIMETABLE,
|
||||||
|
FEATURE_AGENDA,
|
||||||
|
FEATURE_GRADES,
|
||||||
|
FEATURE_HOMEWORK,
|
||||||
|
FEATURE_NOTICES,
|
||||||
|
FEATURE_ATTENDANCES,
|
||||||
|
FEATURE_MESSAGES_INBOX,
|
||||||
|
FEATURE_MESSAGES_OUTBOX,
|
||||||
|
FEATURE_ANNOUNCEMENTS)
|
||||||
|
|
||||||
|
fun getAllIds(): List<Int> = getAllFeatures() + getAllNecessary()
|
||||||
|
|
||||||
|
fun getIdsByView(targetId: Int): List<Int> {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
@ -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.librus.login.LoginLibrusSynergia
|
||||||
import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod
|
import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod
|
||||||
|
|
||||||
|
val SYNERGIA_API_ENABLED = "true".toBoolean()
|
||||||
|
|
||||||
const val LOGIN_TYPE_MOBIDZIENNIK = 1
|
const val LOGIN_TYPE_MOBIDZIENNIK = 1
|
||||||
const val LOGIN_TYPE_LIBRUS = 2
|
const val LOGIN_TYPE_LIBRUS = 2
|
||||||
const val LOGIN_TYPE_IUCZNIOWIE = 3
|
const val LOGIN_TYPE_IUCZNIOWIE = 3
|
||||||
@ -37,14 +39,29 @@ const val LOGIN_METHOD_VULCAN_WEB = 100
|
|||||||
const val LOGIN_METHOD_VULCAN_API = 200
|
const val LOGIN_METHOD_VULCAN_API = 200
|
||||||
|
|
||||||
val librusLoginMethods = listOf(
|
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_PORTAL, LoginLibrusPortal::class.java)
|
||||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_API, null, LoginLibrusApi::class.java) { _, loginStore ->
|
.withIsPossible { _, loginStore ->
|
||||||
if (loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL) LOGIN_METHOD_LIBRUS_PORTAL else LOGIN_METHOD_NOT_NEEDED
|
loginStore.mode == LOGIN_MODE_LIBRUS_EMAIL
|
||||||
},
|
}
|
||||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_SYNERGIA, listOf(FEATURE_GRADES, FEATURE_HOMEWORKS, FEATURE_MESSAGES_INBOX, FEATURE_MESSAGES_OUTBOX), LoginLibrusSynergia::class.java) { profile, _ ->
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED },
|
||||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_API else LOGIN_METHOD_NOT_NEEDED
|
|
||||||
},
|
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_API, LoginLibrusApi::class.java)
|
||||||
LoginMethod(LOGIN_TYPE_LIBRUS, LOGIN_METHOD_LIBRUS_MESSAGES, listOf(FEATURE_MESSAGES_INBOX, FEATURE_MESSAGES_OUTBOX), LoginLibrusMessages::class.java) { profile, _ ->
|
.withIsPossible { _, loginStore ->
|
||||||
if (profile?.hasStudentData("accountPassword") == false) LOGIN_METHOD_LIBRUS_SYNERGIA else LOGIN_METHOD_NOT_NEEDED
|
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
|
||||||
|
}
|
||||||
)
|
)
|
@ -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)
|
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.api.v2.events
|
||||||
|
|
||||||
|
class SyncFinishedEvent
|
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.api.v2.events
|
||||||
|
|
||||||
|
class SyncProfileFinishedEvent(val profileId: Int)
|
@ -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?)
|
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.api.v2.events
|
||||||
|
|
||||||
|
class SyncStartedEvent(val profileId: Int)
|
@ -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)"
|
||||||
|
}
|
||||||
|
}
|
@ -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<Int>?) : ApiTask(profileId) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "SyncProfileRequest(profileId=$profileId, featureIds=$featureIds)"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) Kuba Szczodrzyński 2019-9-28.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package pl.szczodrzynski.edziennik.api.v2.events.requests
|
||||||
|
|
||||||
|
class SyncRequest()
|
@ -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)"
|
||||||
|
}
|
||||||
|
}
|
@ -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()
|
||||||
|
}
|
@ -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<Int>)
|
||||||
|
fun getMessage(messageId: Int)
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
@ -9,22 +9,30 @@ import pl.szczodrzynski.edziennik.App
|
|||||||
import pl.szczodrzynski.edziennik.api.AppError
|
import pl.szczodrzynski.edziennik.api.AppError
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback
|
import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback
|
||||||
import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410
|
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.librus.data.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.datamodels.Profile
|
import pl.szczodrzynski.edziennik.datamodels.Profile
|
||||||
import pl.szczodrzynski.edziennik.datamodels.ProfileFull
|
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<Int>()
|
val internalErrorList = mutableListOf<Int>()
|
||||||
lateinit var data: DataLibrus
|
val data: DataLibrus
|
||||||
|
|
||||||
init {
|
init {
|
||||||
data = DataLibrus(app, profile, loginStore).apply {
|
data = DataLibrus(app, profile, loginStore).apply {
|
||||||
callback = wrapCallback(this@Librus.callback)
|
callback = wrapCallback(this@Librus.callback)
|
||||||
}
|
}
|
||||||
|
data.satisfyLoginMethods()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun sync(featureIds: List<Int>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMessage(messageId: Int) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import pl.szczodrzynski.edziennik.api.interfaces.*
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.*
|
import pl.szczodrzynski.edziennik.api.v2.*
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.firstlogin.FirstLoginLibrus
|
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.firstlogin.FirstLoginSynergia
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.login.SynergiaTokenExtractor
|
|
||||||
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
import pl.szczodrzynski.edziennik.api.v2.models.Data
|
||||||
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
import pl.szczodrzynski.edziennik.datamodels.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.datamodels.MessageFull
|
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.datamodels.ProfileFull
|
||||||
import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo
|
import pl.szczodrzynski.edziennik.messages.MessagesComposeInfo
|
||||||
import pl.szczodrzynski.edziennik.models.Endpoint
|
import pl.szczodrzynski.edziennik.models.Endpoint
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import java.lang.Exception
|
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"
|
private val TAG = "librus.Librus"
|
||||||
|
|
||||||
lateinit var syncCallback: SyncCallback
|
lateinit var syncCallback: SyncCallback
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
package pl.szczodrzynski.edziennik.api.v2.librus
|
package pl.szczodrzynski.edziennik.api.v2.librus
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.api.AppError
|
import pl.szczodrzynski.edziennik.api.AppError
|
||||||
@ -30,21 +31,24 @@ class LibrusTest(val app: App) {
|
|||||||
|
|
||||||
putStudentData("accountLogin", "1234567")
|
putStudentData("accountLogin", "1234567")
|
||||||
|
|
||||||
putStudentData("accountToken", "token")
|
//putStudentData("accountToken", "token")
|
||||||
putStudentData("accountTokenTime", 1569523077)
|
//putStudentData("accountTokenTime", 1569458277)
|
||||||
}
|
}
|
||||||
val loginStore = LoginStore(1, LOGIN_TYPE_LIBRUS, JsonObject().apply {
|
val loginStore = LoginStore(1, LOGIN_TYPE_LIBRUS, JsonObject().apply {
|
||||||
addProperty("email", "test@example.com")
|
addProperty("email", "test@example.com")
|
||||||
addProperty("password", "zaq1@WSX")
|
addProperty("password", "zaq1@WSX")
|
||||||
|
|
||||||
addProperty("accessToken", "token")
|
//addProperty("accessToken", "token")
|
||||||
addProperty("refreshToken", "refresh")
|
//addProperty("refreshToken", "refresh")
|
||||||
addProperty("tokenExpiryTime", 1569523077)
|
//addProperty("tokenExpiryTime", 1569523077)
|
||||||
}).also {
|
}).also {
|
||||||
it.mode = LOGIN_MODE_LIBRUS_EMAIL
|
it.mode = LOGIN_MODE_LIBRUS_EMAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
fun go() {
|
fun go() {
|
||||||
|
|
||||||
|
app.startService(Intent(app, ApiService::class.java))
|
||||||
|
|
||||||
val data = DataLibrus(app, profile, loginStore).apply {
|
val data = DataLibrus(app, profile, loginStore).apply {
|
||||||
callback = object : ProgressCallback {
|
callback = object : ProgressCallback {
|
||||||
override fun onProgress(progressStep: Int) {
|
override fun onProgress(progressStep: Int) {
|
||||||
|
@ -19,10 +19,11 @@ class LoginLibrus(val data: DataLibrus, vararg loginMethodIds: Int, val onSucces
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
for (loginMethodId in loginMethodIds) {
|
for (loginMethodId in loginMethodIds) {
|
||||||
var requiredLoginMethod = loginMethodId
|
var requiredLoginMethod: Int? = loginMethodId
|
||||||
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
while (requiredLoginMethod != LOGIN_METHOD_NOT_NEEDED) {
|
||||||
librusLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
librusLoginMethods.singleOrNull { it.loginMethodId == requiredLoginMethod }?.let { loginMethod ->
|
||||||
loginMethodList.add(requiredLoginMethod)
|
if (requiredLoginMethod != null)
|
||||||
|
loginMethodList.add(requiredLoginMethod!!)
|
||||||
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
requiredLoginMethod = loginMethod.requiredLoginMethod(data.profile, data.loginStore)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,9 @@ import im.wangchao.mhttp.Request
|
|||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.body.MediaTypeUtils
|
import im.wangchao.mhttp.body.MediaTypeUtils
|
||||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
||||||
import pl.szczodrzynski.edziennik.api.AppError
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.api.AppError.*
|
|
||||||
import pl.szczodrzynski.edziennik.api.v2.*
|
import pl.szczodrzynski.edziennik.api.v2.*
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
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.*
|
import java.net.HttpURLConnection.*
|
||||||
|
|
||||||
class LoginLibrusApi {
|
class LoginLibrusApi {
|
||||||
@ -121,7 +116,7 @@ class LoginLibrusApi {
|
|||||||
data.error(TAG, ERROR_RESPONSE_EMPTY, response)
|
data.error(TAG, ERROR_RESPONSE_EMPTY, response)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
json.getString("error")?.let { error ->
|
if (response?.code() != 200) json.getString("error")?.let { error ->
|
||||||
when (error) {
|
when (error) {
|
||||||
"librus_captcha_needed" -> ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED
|
"librus_captcha_needed" -> ERROR_LOGIN_LIBRUS_API_CAPTCHA_NEEDED
|
||||||
"connection_problems" -> ERROR_LOGIN_LIBRUS_API_CONNECTION_PROBLEMS
|
"connection_problems" -> ERROR_LOGIN_LIBRUS_API_CONNECTION_PROBLEMS
|
||||||
@ -140,7 +135,7 @@ class LoginLibrusApi {
|
|||||||
try {
|
try {
|
||||||
data.apiAccessToken = json.getString("access_token")
|
data.apiAccessToken = json.getString("access_token")
|
||||||
data.apiRefreshToken = json.getString("refresh_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()
|
onSuccess()
|
||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
data.error(TAG, EXCEPTION_LOGIN_LIBRUS_API_TOKEN, response, e, json)
|
data.error(TAG, EXCEPTION_LOGIN_LIBRUS_API_TOKEN, response, e, json)
|
||||||
|
@ -13,6 +13,7 @@ import okhttp3.internal.http.HttpDate
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.*
|
import pl.szczodrzynski.edziennik.api.v2.*
|
||||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||||
|
import pl.szczodrzynski.edziennik.getUnixDate
|
||||||
|
|
||||||
class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
|
class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
|
||||||
companion object {
|
companion object {
|
||||||
@ -73,7 +74,7 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.messagesSessionId = sessionId
|
data.messagesSessionId = sessionId
|
||||||
data.messagesSessionIdExpiryTime = currentTimeUnix() + 3600 /* 1h */
|
data.messagesSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45min */
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,52 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
|
|
||||||
private var refreshTokenFailed = false
|
private var refreshTokenFailed = false
|
||||||
private fun accessToken(code: String?, refreshToken: String?) {
|
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<Pair<String, Any>>()
|
val params = ArrayList<Pair<String, Any>>()
|
||||||
params.add(Pair("client_id", LIBRUS_CLIENT_ID))
|
params.add(Pair("client_id", LIBRUS_CLIENT_ID))
|
||||||
if (code != null) {
|
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("grant_type", "refresh_token"))
|
||||||
params.add(Pair("refresh_token", refreshToken))
|
params.add(Pair("refresh_token", refreshToken))
|
||||||
}
|
}
|
||||||
|
|
||||||
Request.builder()
|
Request.builder()
|
||||||
.url(LIBRUS_TOKEN_URL)
|
.url(LIBRUS_TOKEN_URL)
|
||||||
.userAgent(LIBRUS_USER_AGENT)
|
.userAgent(LIBRUS_USER_AGENT)
|
||||||
.addParams(params)
|
.addParams(params)
|
||||||
.allowErrorCode(HTTP_UNAUTHORIZED)
|
|
||||||
.post()
|
.post()
|
||||||
.callback(object : JsonCallbackHandler() {
|
.allowErrorCode(HTTP_UNAUTHORIZED)
|
||||||
override fun onSuccess(json: JsonObject?, response: Response) {
|
.callback(callback)
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import pl.szczodrzynski.edziennik.api.v2.*
|
|||||||
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus
|
||||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||||
import pl.szczodrzynski.edziennik.getString
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.getUnixDate
|
||||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
@ -75,7 +76,10 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
data.error(TAG, ERROR_RESPONSE_EMPTY, response)
|
data.error(TAG, ERROR_RESPONSE_EMPTY, response)
|
||||||
return
|
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 ->
|
error?.let { code ->
|
||||||
when (code) {
|
when (code) {
|
||||||
"TokenIsExpired" -> ERROR_LIBRUS_API_TOKEN_EXPIRED
|
"TokenIsExpired" -> ERROR_LIBRUS_API_TOKEN_EXPIRED
|
||||||
@ -145,7 +149,7 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
data.synergiaSessionId = sessionId
|
data.synergiaSessionId = sessionId
|
||||||
data.synergiaSessionIdExpiryTime = currentTimeUnix() + 3600 /* 1h */
|
data.synergiaSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45min */
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -33,16 +33,80 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!synergiaAccount()) {
|
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 {
|
private fun synergiaAccount(): Boolean {
|
||||||
val accountLogin = data.apiLogin ?: return false
|
val accountLogin = data.apiLogin ?: return false
|
||||||
val accessToken = data.portalAccessToken ?: 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()
|
Request.builder()
|
||||||
.url(LIBRUS_ACCOUNT_URL + accountLogin)
|
.url(LIBRUS_ACCOUNT_URL + accountLogin)
|
||||||
.userAgent(LIBRUS_USER_AGENT)
|
.userAgent(LIBRUS_USER_AGENT)
|
||||||
@ -53,59 +117,7 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) {
|
|||||||
.allowErrorCode(HTTP_UNAUTHORIZED)
|
.allowErrorCode(HTTP_UNAUTHORIZED)
|
||||||
.allowErrorCode(HTTP_BAD_REQUEST)
|
.allowErrorCode(HTTP_BAD_REQUEST)
|
||||||
.allowErrorCode(HTTP_GONE)
|
.allowErrorCode(HTTP_GONE)
|
||||||
.callback(object : JsonCallbackHandler() {
|
.callback(callback)
|
||||||
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)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
return true
|
return true
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
@ -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?)
|
|
@ -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
|
||||||
|
}
|
@ -7,15 +7,24 @@ import com.google.gson.JsonObject
|
|||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.api.AppError
|
import pl.szczodrzynski.edziennik.api.AppError
|
||||||
|
import pl.szczodrzynski.edziennik.api.AppError.*
|
||||||
import pl.szczodrzynski.edziennik.api.interfaces.ProgressCallback
|
import pl.szczodrzynski.edziennik.api.interfaces.ProgressCallback
|
||||||
|
import pl.szczodrzynski.edziennik.api.v2.interfaces.EndpointCallback
|
||||||
import pl.szczodrzynski.edziennik.datamodels.*
|
import pl.szczodrzynski.edziennik.datamodels.*
|
||||||
import pl.szczodrzynski.edziennik.models.Date
|
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) {
|
open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) {
|
||||||
|
|
||||||
var fakeLogin = false
|
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.
|
* 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) {
|
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) {
|
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))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,21 +7,18 @@ import pl.szczodrzynski.edziennik.datamodels.Profile
|
|||||||
* A Endpoint descriptor class.
|
* A Endpoint descriptor class.
|
||||||
*
|
*
|
||||||
* The API runs appropriate endpoints in order to fulfill its
|
* The API runs appropriate endpoints in order to fulfill its
|
||||||
* [Feature] list.
|
* feature list.
|
||||||
* An endpoint may have its [LoginMethod] dependencies which will be
|
* An endpoint may have its [LoginMethod] dependencies which will be
|
||||||
* satisfied by the API before the [endpointClass]'s constructor is invoked.
|
* satisfied by the API before the [endpointClass]'s constructor is invoked.
|
||||||
*
|
*
|
||||||
* @param loginType type of the e-register this endpoint handles
|
* @param loginType type of the e-register this endpoint handles
|
||||||
* @param endpointId a unique ID of this endpoint
|
* @param featureId a feature ID
|
||||||
* @param featureIds a [List] of [Feature]s (their IDs) this endpoint can download
|
* @param endpointIds a [List] of [Endpoint]s that satisfy this feature ID
|
||||||
* May be null if no strict feature set is associated with this method.
|
* @param requiredLoginMethod a required login method, which will have to be executed before this endpoint.
|
||||||
* @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].
|
|
||||||
*/
|
*/
|
||||||
class Endpoint(
|
class Endpoint(
|
||||||
val loginType: Int,
|
val loginType: Int,
|
||||||
val endpointId: Int,
|
val featureId: Int,
|
||||||
val featureIds: List<Int>?,
|
val endpointIds: List<Int>,
|
||||||
val endpointClass: Class<*>,
|
val requiredLoginMethod: Int
|
||||||
val requiredLoginMethod: (profile: Profile?, loginStore: LoginStore) -> Int
|
|
||||||
)
|
)
|
@ -1,11 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.api.v2.models
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data class Feature(val featureId: Int, val loginOptions: Map<Int, List<Int>>) {
|
|
||||||
|
|
||||||
init {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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
|
|
||||||
)
|
|
||||||
))
|
|
||||||
)
|
|
@ -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<Profile>, val error: AppError?)
|
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.api.v2.models
|
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.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.datamodels.Profile
|
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 loginType type of the e-register this login method handles
|
||||||
* @param loginMethodId a unique ID of this login method
|
* @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 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(
|
class LoginMethod(
|
||||||
val loginType: Int,
|
val loginType: Int,
|
||||||
val loginMethodId: Int,
|
val loginMethodId: Int,
|
||||||
val featureIds: List<Int>?,
|
|
||||||
val loginMethodClass: Class<*>,
|
val loginMethodClass: Class<*>,
|
||||||
val requiredLoginMethod: (profile: Profile?, loginStore: LoginStore) -> Int
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,10 @@ public interface ProfileDao {
|
|||||||
LiveData<ProfileFull> getById(int profileId);
|
LiveData<ProfileFull> getById(int profileId);
|
||||||
|
|
||||||
@Query("SELECT profiles.*, loginStores.loginStoreType, loginStores.loginStoreData FROM profiles LEFT JOIN loginStores ON profiles.loginStoreId = loginStores.loginStoreId WHERE profileId = :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")
|
@Query("SELECT * FROM profiles WHERE profileId >= 0 ORDER BY profileId")
|
||||||
LiveData<List<Profile>> getAll();
|
LiveData<List<Profile>> getAll();
|
||||||
@ -45,6 +48,9 @@ public interface ProfileDao {
|
|||||||
@Query("SELECT * FROM profiles WHERE syncEnabled = 1 AND archived = 0 AND profileId >= 0 ORDER BY profileId")
|
@Query("SELECT * FROM profiles WHERE syncEnabled = 1 AND archived = 0 AND profileId >= 0 ORDER BY profileId")
|
||||||
List<Profile> getProfilesForSyncNow();
|
List<Profile> getProfilesForSyncNow();
|
||||||
|
|
||||||
|
@Query("SELECT profileId FROM profiles WHERE syncEnabled = 1 AND archived = 0 AND profileId >= 0 ORDER BY profileId")
|
||||||
|
List<Integer> getIdsForSyncNow();
|
||||||
|
|
||||||
@Query("SELECT profileId FROM profiles WHERE profileId >= 0 ORDER BY profileId")
|
@Query("SELECT profileId FROM profiles WHERE profileId >= 0 ORDER BY profileId")
|
||||||
List<Integer> getIdsNow();
|
List<Integer> getIdsNow();
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ public class EventManualDialog {
|
|||||||
return;
|
return;
|
||||||
this.app = _app;
|
this.app = _app;
|
||||||
AsyncTask.execute(() -> {
|
AsyncTask.execute(() -> {
|
||||||
this.profile = app.db.profileDao().getByIdNow(profileId);
|
this.profile = app.db.profileDao().getFullByIdNow(profileId);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
((Activity) context).runOnUiThread(() -> {
|
((Activity) context).runOnUiThread(() -> {
|
||||||
actualShow(editingEvent, defaultDate, defaultTime, dialogType);
|
actualShow(editingEvent, defaultDate, defaultTime, dialogType);
|
||||||
|
@ -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;
|
IIcon icon = CommunityMaterial.Icon.cmd_emoticon_dead_outline;
|
||||||
boolean noNumberText = false;
|
boolean noNumberText = false;
|
||||||
if (profile == null) {
|
if (profile == null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user