From d2f06a256fab5d82a3327d2140198f88f4bf4d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Tue, 1 Oct 2019 07:03:12 +0200 Subject: [PATCH] [APIv2] Update API, add endpoint choosing algorithm --- app/debug/output.json | 1 - .../pl/szczodrzynski/edziennik/api/v2/Api.kt | 1 - .../edziennik/api/v2/Constants.kt | 3 + .../edziennik/api/v2/Endpoints.kt | 49 ++--- .../edziennik/api/v2/librus/Librus.kt | 98 ++++++++-- .../edziennik/api/v2/librus/LibrusTest.kt | 11 +- .../edziennik/api/v2/librus/data/LibrusApi.kt | 167 +++++++++--------- .../api/v2/librus/data/LibrusApiMe.kt | 6 +- .../api/v2/librus/login/LoginLibrus.kt | 7 +- .../api/v2/librus/login/LoginLibrusApi.kt | 27 ++- .../v2/librus/login/LoginLibrusMessages.kt | 13 +- .../api/v2/librus/login/LoginLibrusPortal.kt | 46 +++-- .../v2/librus/login/LoginLibrusSynergia.kt | 38 ++-- .../v2/librus/login/SynergiaTokenExtractor.kt | 31 +++- .../edziennik/api/v2/models/ApiError.kt | 3 +- .../edziennik/api/v2/models/Data.kt | 13 +- .../edziennik/api/v2/models/Endpoint.kt | 9 +- app/src/main/res/values/strings.xml | 4 + settings.gradle | 2 +- 19 files changed, 346 insertions(+), 183 deletions(-) delete mode 100644 app/debug/output.json diff --git a/app/debug/output.json b/app/debug/output.json deleted file mode 100644 index db263901..00000000 --- a/app/debug/output.json +++ /dev/null @@ -1 +0,0 @@ -[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":2600,"versionName":"2.6","enabled":true,"outputFile":"Edziennik_2600_debug.apk","fullName":"debug","baseName":"debug"},"path":"Edziennik_2600_debug.apk","properties":{}}] \ No newline at end of file diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Api.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Api.kt index 97060c70..4af2e0e5 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Api.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Api.kt @@ -16,6 +16,5 @@ open class Api(open val data: Data) { Crashlytics.logException(e) } - data.callback.onError(null, error) } } \ 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 4992b519..fa133eda 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,6 +4,9 @@ package pl.szczodrzynski.edziennik.api.v2 +const val GET = 0 +const val POST = 1 + 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" 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 940fbf57..4279ff02 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 @@ -54,7 +54,7 @@ val endpoints = listOf( Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TIMETABLE, listOf( ENDPOINT_LIBRUS_API_TIMETABLES, ENDPOINT_LIBRUS_API_SUBSTITUTIONS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_AGENDA, listOf( ENDPOINT_LIBRUS_API_EVENTS, ENDPOINT_LIBRUS_API_EVENT_TYPES, @@ -62,7 +62,7 @@ val endpoints = listOf( ENDPOINT_LIBRUS_API_TEACHER_FREE_DAYS, ENDPOINT_LIBRUS_API_SCHOOL_FREE_DAYS, ENDPOINT_LIBRUS_API_CLASS_FREE_DAYS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf( ENDPOINT_LIBRUS_API_NORMAL_GC, ENDPOINT_LIBRUS_API_POINT_GC, @@ -76,58 +76,65 @@ val endpoints = listOf( ENDPOINT_LIBRUS_API_TEXT_GRADES, ENDPOINT_LIBRUS_API_DESCRIPTIVE_TEXT_GRADES, ENDPOINT_LIBRUS_API_BEHAVIOUR_GRADES - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_HOMEWORK, listOf( ENDPOINT_LIBRUS_API_HOMEWORK - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_NOTICES, listOf( ENDPOINT_LIBRUS_API_NOTICES - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ATTENDANCES, listOf( ENDPOINT_LIBRUS_API_ATTENDANCE, ENDPOINT_LIBRUS_API_ATTENDANCE_TYPES - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_ANNOUNCEMENTS, listOf( ENDPOINT_LIBRUS_API_ANNOUNCEMENTS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf( ENDPOINT_LIBRUS_API_ME - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SCHOOL_INFO, listOf( ENDPOINT_LIBRUS_API_SCHOOLS, ENDPOINT_LIBRUS_API_UNITS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASS_INFO, listOf( ENDPOINT_LIBRUS_API_CLASSES - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEAM_INFO, listOf( ENDPOINT_LIBRUS_API_VIRTUAL_CLASSES - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_LUCKY_NUMBER, listOf( ENDPOINT_LIBRUS_API_LUCKY_NUMBER - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_TEACHERS, listOf( ENDPOINT_LIBRUS_API_USERS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_SUBJECTS, listOf( ENDPOINT_LIBRUS_API_SUBJECTS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_CLASSROOMS, listOf( ENDPOINT_LIBRUS_API_CLASSROOMS - ), LOGIN_METHOD_LIBRUS_API), + ), listOf(LOGIN_METHOD_LIBRUS_API)), Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_STUDENT_INFO, listOf( ENDPOINT_LIBRUS_SYNERGIA_INFO - ), LOGIN_METHOD_LIBRUS_SYNERGIA), + ), listOf(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( + ), listOf(LOGIN_METHOD_LIBRUS_SYNERGIA)), + /*Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf( ENDPOINT_LIBRUS_SYNERGIA_GRADES - ), LOGIN_METHOD_LIBRUS_SYNERGIA), + ), listOf(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) + + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_GRADES, listOf( + ENDPOINT_LIBRUS_API_NORMAL_GC, + ENDPOINT_LIBRUS_API_NORMAL_GRADES, + ENDPOINT_LIBRUS_SYNERGIA_GRADES + ), listOf(LOGIN_METHOD_LIBRUS_API, LOGIN_METHOD_LIBRUS_SYNERGIA)), + + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_INBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_RECEIVED), listOf(LOGIN_METHOD_LIBRUS_MESSAGES)), + Endpoint(LOGIN_TYPE_LIBRUS, FEATURE_MESSAGES_OUTBOX, listOf(ENDPOINT_LIBRUS_MESSAGES_SENT), listOf(LOGIN_METHOD_LIBRUS_MESSAGES)) ) /* 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 6289f6b2..523df841 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 @@ -5,18 +5,28 @@ package pl.szczodrzynski.edziennik.api.v2.librus import android.content.Context +import android.util.Log import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.api.AppError +import pl.szczodrzynski.edziennik.api.Edziennik import pl.szczodrzynski.edziennik.api.interfaces.SyncCallback import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 +import pl.szczodrzynski.edziennik.api.v2.endpoints 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.librusLoginMethods +import pl.szczodrzynski.edziennik.api.v2.models.ApiError +import pl.szczodrzynski.edziennik.api.v2.models.Endpoint import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.Profile import pl.szczodrzynski.edziennik.datamodels.ProfileFull +import kotlin.math.max class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface { + companion object { + const val TAG = "Librus" + } val internalErrorList = mutableListOf() val data: DataLibrus @@ -29,43 +39,97 @@ class Librus(val app: App, val profile: Profile?, val loginStore: LoginStore, va } override fun sync(featureIds: List) { + val possibleLoginMethods = data.loginMethods.toMutableList() + for (loginMethod in librusLoginMethods) { + if (loginMethod.isPossible(profile, loginStore)) + possibleLoginMethods += loginMethod.loginMethodId + } + + var highestLoginMethod = 0 + var targetEndpointList = mutableListOf() + + for (featureId in featureIds) { + endpoints.filter { it.featureId == featureId }.forEach { endpoint -> + if (possibleLoginMethods.containsAll(endpoint.requiredLoginMethods)) { + targetEndpointList.add(endpoint) + highestLoginMethod = max(highestLoginMethod, endpoint.requiredLoginMethods.max() ?: 0) + } + } + } + + targetEndpointList = targetEndpointList + .sortedWith(compareBy(Endpoint::featureId, Endpoint::priority)) + .distinctBy { it.featureId } + .toMutableList() + + Log.d(TAG, targetEndpointList.toString()) + + /* + + INPUT: [ + FEATURE_GRADES, + FEATURE_STUDENT_INFO, + FEATURE_STUDENT_NUMBER + ] + + OUTPUT: [ + Endpoint(loginType=2, + featureId=FEATURE_GRADES, endpointIds=[ + ENDPOINT_LIBRUS_API_NORMAL_GC, + ENDPOINT_LIBRUS_API_NORMAL_GRADES, + ENDPOINT_LIBRUS_SYNERGIA_GRADES + ], requiredLoginMethods=[ + LOGIN_METHOD_LIBRUS_API, + LOGIN_METHOD_LIBRUS_SYNERGIA + ]), + Endpoint(loginType=2, + featureId=FEATURE_STUDENT_INFO, endpointIds=[ + ENDPOINT_LIBRUS_API_ME + ], requiredLoginMethods=[ + LOGIN_METHOD_LIBRUS_API + ]), + Endpoint(loginType=2, + featureId=FEATURE_STUDENT_NUMBER, endpointIds=[ + ENDPOINT_LIBRUS_SYNERGIA_INFO + ], requiredLoginMethods=[ + LOGIN_METHOD_LIBRUS_SYNERGIA + ]) + ] + + */ } override fun getMessage(messageId: Int) { } - private fun wrapCallback(callback: SyncCallback): SyncCallback { - return object : SyncCallback { - override fun onSuccess(activityContext: Context?, profileFull: ProfileFull?) { - callback.onSuccess(activityContext, profileFull) + private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback { + return object : EdziennikCallback { + override fun onCompleted() { + callback.onCompleted() } - override fun onProgress(progressStep: Int) { - callback.onProgress(progressStep) + override fun onProgress(step: Int) { + callback.onProgress(step) } - override fun onActionStarted(stringResId: Int) { - callback.onActionStarted(stringResId) + override fun onStartProgress(stringRes: Int) { + callback.onStartProgress(stringRes) } - override fun onLoginFirst(profileList: MutableList?, loginStore: LoginStore?) { - callback.onLoginFirst(profileList, loginStore) - } - - override fun onError(activityContext: Context?, error: AppError) { - when (error.errorCode) { + override fun onError(apiError: ApiError) { + when (apiError.errorCode) { in internalErrorList -> { // finish immediately if the same error occurs twice during the same sync - callback.onError(activityContext, error) + callback.onError(apiError) } CODE_INTERNAL_LIBRUS_ACCOUNT_410 -> { - internalErrorList.add(error.errorCode) + internalErrorList.add(apiError.errorCode) loginStore.removeLoginData("refreshToken") // force a clean login //loginLibrus() } - else -> callback.onError(activityContext, error) + else -> callback.onError(apiError) } } } 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 482ba67b..c6c94b80 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 @@ -11,9 +11,11 @@ import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.api.AppError import pl.szczodrzynski.edziennik.api.interfaces.ProgressCallback import pl.szczodrzynski.edziennik.api.v2.* +import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrus import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusPortal +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.datamodels.LoginStore import pl.szczodrzynski.edziennik.datamodels.Profile import pl.szczodrzynski.edziennik.utils.Utils.d @@ -47,7 +49,14 @@ class LibrusTest(val app: App) { fun go() { - app.startService(Intent(app, ApiService::class.java)) + Librus(app, profile, loginStore, object : EdziennikCallback { + override fun onCompleted() {} + override fun onError(apiError: ApiError) {} + override fun onProgress(step: Int) {} + override fun onStartProgress(stringRes: Int) {} + }).sync(listOf(FEATURE_GRADES, FEATURE_STUDENT_INFO, FEATURE_STUDENT_NUMBER)) + + //app.startService(Intent(app, ApiService::class.java)) /*val data = DataLibrus(app, profile, loginStore).apply { callback = object : ProgressCallback { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt index c95dc929..46e172ab 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApi.kt @@ -9,106 +9,101 @@ import com.google.gson.JsonObject import im.wangchao.mhttp.Request import im.wangchao.mhttp.Response import im.wangchao.mhttp.callback.JsonCallbackHandler +import io.fabric.sdk.android.services.network.HttpRequest.post import pl.szczodrzynski.edziennik.api.AppError import pl.szczodrzynski.edziennik.api.AppError.CODE_MAINTENANCE import pl.szczodrzynski.edziennik.api.AppError.CODE_OTHER -import pl.szczodrzynski.edziennik.api.v2.Api -import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED -import pl.szczodrzynski.edziennik.api.v2.LIBRUS_API_URL -import pl.szczodrzynski.edziennik.api.v2.LIBRUS_USER_AGENT +import pl.szczodrzynski.edziennik.api.v2.* +import pl.szczodrzynski.edziennik.api.v2.librus.login.LoginLibrusSynergia +import pl.szczodrzynski.edziennik.api.v2.models.ApiError +import pl.szczodrzynski.edziennik.getString import pl.szczodrzynski.edziennik.utils.Utils.d +import java.lang.Exception +import java.net.HttpURLConnection import java.net.HttpURLConnection.* -open class LibrusApi(override val data: DataLibrus) : Api(data) { +open class LibrusApi(open val data: DataLibrus) { companion object { const val TAG = "LibrusApi" } - fun apiRequest(endpoint: String, callback: (json: JsonObject?) -> Unit) { - d(TAG, "Requesting $LIBRUS_API_URL/$endpoint") + + fun apiGet(tag: String, endpoint: String, method: Int = GET, payload: JsonObject? = null, onSuccess: (json: JsonObject?) -> Unit) { + + val callback = object : JsonCallbackHandler() { + override fun onSuccess(json: JsonObject?, response: Response?) { + if (json == null && response?.parserErrorBody == null) { + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) + return + } + 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 + "Insufficient scopes" -> ERROR_LIBRUS_API_INSUFFICIENT_SCOPES + "Request is denied" -> ERROR_LIBRUS_API_REQUEST_DENIED + "Resource not found" -> ERROR_LIBRUS_API_RESOURCE_NOT_FOUND + "NotFound" -> ERROR_LIBRUS_API_DATA_NOT_FOUND + "AccessDeny" -> when (json.getString("Message")) { + "Student timetable is not public" -> ERROR_LIBRUS_API_TIMETABLE_NOT_PUBLIC + else -> ERROR_LIBRUS_API_RESOURCE_ACCESS_DENIED + } + "LuckyNumberIsNotActive" -> ERROR_LIBRUS_API_LUCKY_NUMBER_NOT_ACTIVE + "NotesIsNotActive" -> ERROR_LIBRUS_API_NOTES_NOT_ACTIVE + "InvalidRequest" -> ERROR_LIBRUS_API_INVALID_REQUEST_PARAMS + "Nieprawidłowy węzeł." -> ERROR_LIBRUS_API_INCORRECT_ENDPOINT + else -> ERROR_LIBRUS_API_OTHER + }.let { errorCode -> + data.error(ApiError(tag, errorCode) + .withApiResponse(json) + .withResponse(response)) + return + } + } + + if (json == null) { + data.error(ApiError(tag, ERROR_RESPONSE_EMPTY) + .withResponse(response)) + return + } + + try { + onSuccess(json) + } catch (e: Exception) { + data.error(ApiError(tag, EXCEPTION_LIBRUS_API_REQUEST) + .withResponse(response) + .withThrowable(e) + .withApiResponse(json)) + } + } + + override fun onFailure(response: Response?, throwable: Throwable?) { + // TODO add hotfix for Classrooms 500 + data.error(ApiError(tag, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) + } + } + Request.builder() - .url(if (data.fakeLogin) "http://szkolny.eu/librus/api/$endpoint" else "$LIBRUS_API_URL/$endpoint") + .url("$LIBRUS_API_URL/$endpoint") .userAgent(LIBRUS_USER_AGENT) .addHeader("Authorization", "Bearer ${data.apiAccessToken}") - .get() + .apply { + when (method) { + GET -> get() + POST -> post() + } + if (payload != null) + setJsonBody(payload) + } + .allowErrorCode(HTTP_BAD_REQUEST) .allowErrorCode(HTTP_FORBIDDEN) .allowErrorCode(HTTP_UNAUTHORIZED) - .allowErrorCode(HTTP_BAD_REQUEST) - .callback(object : JsonCallbackHandler() { - override fun onSuccess(json: JsonObject?, response: Response) { - if (json == null) { - if (response.parserErrorBody != null && response.parserErrorBody == "Nieprawidłowy węzeł.") { - callback(null) - return - } - finishWithError(AppError(TAG, 453, CODE_MAINTENANCE, response)) - return - } - if (json.get("Status") != null) { - val message = json.get("Message") - val code = json.get("Code") - d(TAG, "apiRequest Error " + json.get("Status").asString + " " + (if (message == null) "" else message.asString) + " " + (if (code == null) "" else code.asString) + "\n\n" + response.request().url().toString()) - if (message != null && message !is JsonNull && message.asString == "Student timetable is not public") { - try { - callback(null) - } catch (e: NullPointerException) { - e.printStackTrace() - d(TAG, "apiRequest exception " + e.message) - finishWithError(AppError(TAG, 503, CODE_OTHER, response, e, json)) - } - - return - } - if (code != null - && code !is JsonNull - && (code.asString == "LuckyNumberIsNotActive" - || code.asString == "NotesIsNotActive" - || code.asString == "AccessDeny")) { - try { - callback(null) - } catch (e: NullPointerException) { - e.printStackTrace() - d(TAG, "apiRequest exception " + e.message) - finishWithError(AppError(TAG, 504, CODE_OTHER, response, e, json)) - } - - return - } - val errorText = json.get("Status").asString + " " + (if (message == null) "" else message.asString) + " " + if (code == null) "" else code.asString - if (code != null && code !is JsonNull && code.asString == "TokenIsExpired") { - finishWithError(AppError(TAG, 74, CODE_INTERNAL_LIBRUS_SYNERGIA_EXPIRED, errorText, response, json)) - return - } - finishWithError(AppError(TAG, 497, CODE_OTHER, errorText, response, json)) - return - } - try { - callback(json) - } catch (e: NullPointerException) { - e.printStackTrace() - d(TAG, "apiRequest exception " + e.message) - finishWithError(AppError(TAG, 505, CODE_OTHER, response, e, json)) - } - - } - - override fun onFailure(response: Response, throwable: Throwable) { - if (response.code() == 405) { - // method not allowed - finishWithError(AppError(TAG, 511, CODE_OTHER, response, throwable)) - return - } - if (response.code() == 500) { - // TODO: 2019-09-10 dirty hotfix - if ("Classrooms" == endpoint) { - callback(null) - return - } - finishWithError(AppError(TAG, 516, CODE_MAINTENANCE, response, throwable)) - return - } - finishWithError(AppError(TAG, 520, CODE_OTHER, response, throwable)) - } - }) + .callback(callback) .build() .enqueue() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApiMe.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApiMe.kt index a852de2b..43a60413 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApiMe.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/librus/data/LibrusApiMe.kt @@ -12,8 +12,12 @@ import pl.szczodrzynski.edziennik.datamodels.Profile class LibrusApiMe(override val data: DataLibrus, val onSuccess: () -> Unit) : LibrusApi(data) { + companion object { + const val TAG = "LibrusApiMe" + } + init { - apiRequest("Me") { json -> + apiGet(TAG, "Me") { json -> val me = json?.getJsonObject("Me") val account = me?.getJsonObject("Account") val user = me?.getJsonObject("User") 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 e12d6713..4f28b5d8 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 @@ -4,6 +4,7 @@ package pl.szczodrzynski.edziennik.api.v2.librus.login +import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus import pl.szczodrzynski.edziennik.api.v2.models.LoginMethod @@ -31,7 +32,7 @@ class LoginLibrus(val data: DataLibrus, vararg loginMethodIds: Int, val onSucces loginMethodList = loginMethodList.toHashSet().toMutableList() loginMethodList.sort() - data.satisfyLoginMethods() + //data.satisfyLoginMethods() nextLoginMethod() } @@ -53,24 +54,28 @@ class LoginLibrus(val data: DataLibrus, vararg loginMethodIds: Int, val onSucces d(TAG, "Using login method $loginMethodId") when (loginMethodId) { LOGIN_METHOD_LIBRUS_PORTAL -> { + data.startProgress(R.string.edziennik_progress_login_librus_portal) LoginLibrusPortal(data) { data.loginMethods.add(loginMethodId) onSuccess() } } LOGIN_METHOD_LIBRUS_API -> { + data.startProgress(R.string.edziennik_progress_login_librus_api) LoginLibrusApi(data) { data.loginMethods.add(loginMethodId) onSuccess() } } LOGIN_METHOD_LIBRUS_SYNERGIA -> { + data.startProgress(R.string.edziennik_progress_login_librus_synergia) LoginLibrusSynergia(data) { data.loginMethods.add(loginMethodId) onSuccess() } } LOGIN_METHOD_LIBRUS_MESSAGES -> { + data.startProgress(R.string.edziennik_progress_login_librus_messages) LoginLibrusMessages(data) { data.loginMethods.add(loginMethodId) onSuccess() 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 d687fbdb..56624210 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 @@ -12,6 +12,7 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler import pl.szczodrzynski.edziennik.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import java.net.HttpURLConnection.* class LoginLibrusApi { @@ -28,7 +29,7 @@ class LoginLibrusApi { this.onSuccess = onSuccess if (data.profile == null) { - data.error(TAG, ERROR_PROFILE_MISSING) + data.error(ApiError(TAG, ERROR_PROFILE_MISSING)) return } @@ -41,7 +42,7 @@ class LoginLibrusApi { LOGIN_MODE_LIBRUS_SYNERGIA -> loginWithSynergia() LOGIN_MODE_LIBRUS_JST -> loginWithJst() else -> { - data.error(TAG, ERROR_INVALID_LOGIN_MODE) + data.error(ApiError(TAG, ERROR_INVALID_LOGIN_MODE)) } } } @@ -49,7 +50,7 @@ class LoginLibrusApi { private fun loginWithPortal() { if (!data.loginMethods.contains(LOGIN_METHOD_LIBRUS_PORTAL)) { - data.error(TAG, ERROR_LOGIN_METHOD_NOT_SATISFIED) + data.error(ApiError(TAG, ERROR_LOGIN_METHOD_NOT_SATISFIED)) return } SynergiaTokenExtractor(data) { @@ -89,7 +90,7 @@ class LoginLibrusApi { } else { // cannot log in: token expired, no login data present - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) } } @@ -106,14 +107,15 @@ class LoginLibrusApi { } else { // cannot log in: token expired, no login data present - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) } } private val tokenCallback = object : JsonCallbackHandler() { override fun onSuccess(json: JsonObject?, response: Response?) { if (json == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) return } if (response?.code() != 200) json.getString("error")?.let { error -> @@ -127,7 +129,9 @@ class LoginLibrusApi { "invalid_grant" -> ERROR_LOGIN_LIBRUS_API_INVALID_GRANT else -> ERROR_LOGIN_LIBRUS_API_OTHER }.let { errorCode -> - data.error(TAG, errorCode, apiResponse = json, response = response) + data.error(ApiError(TAG, errorCode) + .withApiResponse(json) + .withResponse(response)) return } } @@ -138,12 +142,17 @@ class LoginLibrusApi { data.apiTokenExpiryTime = response.getUnixDate() + json.getInt("expires_in", 86400) onSuccess() } catch (e: NullPointerException) { - data.error(TAG, EXCEPTION_LOGIN_LIBRUS_API_TOKEN, response, e, json) + data.error(ApiError(TAG, EXCEPTION_LOGIN_LIBRUS_API_TOKEN) + .withResponse(response) + .withThrowable(e) + .withApiResponse(json)) } } override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } 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 17581b03..a6921aee 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 @@ -12,6 +12,7 @@ import okhttp3.HttpUrl import okhttp3.internal.http.HttpDate import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.currentTimeUnix import pl.szczodrzynski.edziennik.getUnixDate @@ -22,7 +23,7 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { init { run { if (data.profile == null) { - data.error(TAG, ERROR_PROFILE_MISSING) + data.error(ApiError(TAG, ERROR_PROFILE_MISSING)) return@run } @@ -45,7 +46,7 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { loginWithCredentials() } else { - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) } } }} @@ -70,7 +71,9 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { var sessionId = data.app.cookieJar.getCookie("wiadomosci.librus.pl", "DZIENNIKSID") sessionId = sessionId?.replace("-MAINT", "") if (sessionId == null) { - data.error(TAG, ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID, response, text) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_MESSAGES_NO_SESSION_ID) + .withResponse(response) + .withApiResponse(text)) return } data.messagesSessionId = sessionId @@ -84,7 +87,9 @@ class LoginLibrusMessages(val data: DataLibrus, val onSuccess: () -> Unit) { } override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } 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 71bec763..7a96ea5d 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 @@ -12,6 +12,7 @@ import pl.szczodrzynski.edziennik.api.AppError import pl.szczodrzynski.edziennik.api.AppError.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.utils.Utils.c import java.net.HttpURLConnection.HTTP_UNAUTHORIZED import java.util.ArrayList @@ -24,11 +25,11 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { init { run { if (data.loginStore.mode != LOGIN_MODE_LIBRUS_EMAIL) { - data.error(TAG, ERROR_INVALID_LOGIN_MODE) + data.error(ApiError(TAG, ERROR_INVALID_LOGIN_MODE)) return@run } if (data.portalEmail == null || data.portalPassword == null) { - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) return@run } @@ -47,7 +48,6 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { }} private fun authorize(url: String?) { - data.callback.onActionStarted(R.string.sync_action_authorizing) Request.builder() .url(url) .userAgent(LIBRUS_USER_AGENT) @@ -67,13 +67,17 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { if (csrfMatcher.find()) { login(csrfMatcher.group(1)) } else { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING, response, json) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_PORTAL_CSRF_MISSING) + .withResponse(response) + .withApiResponse(json)) } } } override fun onFailure(response: Response, throwable: Throwable) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } }) .build() @@ -81,7 +85,6 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { } private fun login(csrfToken: String) { - data.callback.onActionStarted(R.string.sync_action_logging_in) Request.builder() .url(LIBRUS_LOGIN_URL) .userAgent(LIBRUS_USER_AGENT) @@ -94,14 +97,18 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { override fun onSuccess(json: JsonObject?, response: Response) { if (json == null) { if (response.parserErrorBody?.contains("wciąż nieaktywne") == true) { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED, response) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_PORTAL_NOT_ACTIVATED) + .withResponse(response)) return } - data.error(TAG, ERROR_RESPONSE_EMPTY, response) + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) return } if (json.get("errors") != null) { - data.error(TAG, ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR, response, apiResponse = json) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_PORTAL_ACTION_ERROR) + .withResponse(response) + .withApiResponse(json)) return } authorize(json.getString("redirect", LIBRUS_AUTHORIZE_URL)) @@ -109,10 +116,14 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { override fun onFailure(response: Response, throwable: Throwable) { if (response.code() == 403 || response.code() == 401) { - data.error(TAG, ERROR_LOGIN_DATA_INVALID, response, throwable) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_INVALID) + .withResponse(response) + .withThrowable(throwable)) return } - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } }) .build() @@ -150,7 +161,9 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { else -> ERROR_LOGIN_LIBRUS_PORTAL_OTHER } }.let { errorCode -> - data.error(TAG, errorCode, apiResponse = json, response = response) + data.error(ApiError(TAG, errorCode) + .withApiResponse(json) + .withResponse(response)) return } } @@ -158,12 +171,17 @@ class LoginLibrusPortal(val data: DataLibrus, val onSuccess: () -> Unit) { try { onSuccess(json, response) } catch (e: NullPointerException) { - data.error(TAG, EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN, response, e, json) + data.error(ApiError(TAG, EXCEPTION_LOGIN_LIBRUS_PORTAL_TOKEN) + .withResponse(response) + .withThrowable(e) + .withApiResponse(json)) } } override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } 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 7b405304..5c59e431 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 @@ -13,6 +13,7 @@ import okhttp3.Cookie import okhttp3.HttpUrl import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.currentTimeUnix import pl.szczodrzynski.edziennik.getString import pl.szczodrzynski.edziennik.getUnixDate @@ -27,7 +28,7 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { init { run { if (data.profile == null) { - data.error(TAG, ERROR_PROFILE_MISSING) + data.error(ApiError(TAG, ERROR_PROFILE_MISSING)) return@run } @@ -50,7 +51,7 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { loginWithCredentials() } else { - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) } } }} @@ -73,7 +74,8 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { val callback = object : JsonCallbackHandler() { override fun onSuccess(json: JsonObject?, response: Response?) { if (json == null && response?.parserErrorBody == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) return } val error = if (response?.code() == 200) null else @@ -97,26 +99,34 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { "Nieprawidłowy węzeł." -> ERROR_LIBRUS_API_INCORRECT_ENDPOINT else -> ERROR_LIBRUS_API_OTHER }.let { errorCode -> - data.error(TAG, errorCode, apiResponse = json, response = response) + data.error(ApiError(TAG, errorCode) + .withApiResponse(json) + .withResponse(response)) return } } if (json == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) return } try { onSuccess(json) } catch (e: Exception) { - data.error(TAG, EXCEPTION_LIBRUS_API_REQUEST, response, e, json) + data.error(ApiError(TAG, EXCEPTION_LIBRUS_API_REQUEST) + .withResponse(response) + .withThrowable(e) + .withApiResponse(json)) } } override fun onFailure(response: Response?, throwable: Throwable?) { // TODO add hotfix for Classrooms 500 - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } @@ -135,7 +145,7 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { private fun loginWithToken(token: String?) { if (token == null) { - data.error(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_NO_TOKEN) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_NO_TOKEN)) return } @@ -145,7 +155,9 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { if (location?.endsWith("centrum_powiadomien") == true) { val sessionId = data.app.cookieJar.getCookie("synergia.librus.pl", "DZIENNIKSID") if (sessionId == null) { - data.error(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_NO_SESSION_ID, response, json) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_NO_SESSION_ID) + .withResponse(response) + .withApiResponse(json)) return } data.synergiaSessionId = sessionId @@ -153,12 +165,16 @@ class LoginLibrusSynergia(val data: DataLibrus, val onSuccess: () -> Unit) { onSuccess() } else { - data.error(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_TOKEN_INVALID, response, json) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_SYNERGIA_TOKEN_INVALID) + .withResponse(response) + .withApiResponse(json)) } } override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } 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 67a49ffb..8b6a4c3b 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 @@ -10,6 +10,7 @@ import pl.szczodrzynski.edziennik.api.AppError import pl.szczodrzynski.edziennik.api.AppError.* import pl.szczodrzynski.edziennik.api.v2.* import pl.szczodrzynski.edziennik.api.v2.librus.data.DataLibrus +import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.utils.Utils.d import java.net.HttpURLConnection.* @@ -20,11 +21,11 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { init { run { if (data.loginStore.mode != LOGIN_MODE_LIBRUS_EMAIL) { - data.error(TAG, ERROR_INVALID_LOGIN_MODE) + data.error(ApiError(TAG, ERROR_INVALID_LOGIN_MODE)) return@run } if (data.profile == null) { - data.error(TAG, ERROR_PROFILE_MISSING) + data.error(ApiError(TAG, ERROR_PROFILE_MISSING)) return@run } @@ -33,7 +34,7 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { } else { if (!synergiaAccount()) { - data.error(TAG, ERROR_LOGIN_DATA_MISSING) + data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING)) } } }} @@ -51,7 +52,9 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { 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) + data.error(ApiError(TAG, ERROR_LOGIN_LIBRUS_PORTAL_SYNERGIA_TOKEN_MISSING) + .withResponse(response) + .withApiResponse(json)) } else { data.apiAccessToken = accountToken @@ -69,7 +72,8 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { val callback = object : JsonCallbackHandler() { override fun onSuccess(json: JsonObject?, response: Response?) { if (json == null) { - data.error(TAG, ERROR_RESPONSE_EMPTY, response) + data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY) + .withResponse(response)) return } val error = if (response?.code() == 200) null else @@ -85,7 +89,9 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { "Account not found" -> ERROR_LIBRUS_PORTAL_SYNERGIA_NOT_FOUND else -> ERROR_LIBRUS_PORTAL_OTHER }.let { errorCode -> - data.error(TAG, errorCode, apiResponse = json, response = response) + data.error(ApiError(TAG, errorCode) + .withApiResponse(json) + .withResponse(response)) return } } @@ -94,16 +100,23 @@ class SynergiaTokenExtractor(val data: DataLibrus, val onSuccess: () -> Unit) { onSuccess(json, response) } catch (e: NullPointerException) { e.printStackTrace() - data.error(TAG, EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN, response, e, json) + data.error(ApiError(TAG, EXCEPTION_LIBRUS_PORTAL_SYNERGIA_TOKEN) + .withResponse(response) + .withThrowable(e) + .withApiResponse(json)) } } else { - data.error(TAG, ERROR_REQUEST_FAILURE, response, apiResponse = json) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withApiResponse(json)) } } override fun onFailure(response: Response?, throwable: Throwable?) { - data.error(TAG, ERROR_REQUEST_FAILURE, response, throwable) + data.error(ApiError(TAG, ERROR_REQUEST_FAILURE) + .withResponse(response) + .withThrowable(throwable)) } } 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 index b83cf514..d094901e 100644 --- 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 @@ -8,7 +8,8 @@ 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) { +class ApiError(val tag: String, val errorCode: Int) { + var profileId: Int? = null private var throwable: Throwable? = null private var apiResponse: String? = null private var request: Request? = null 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 024bad40..467c4ff9 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 @@ -169,7 +169,7 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) else -> errorCode } } - callback.onError(ApiError(profile?.id ?: -1, tag, code).withResponse(response).withThrowable(throwable).withApiResponse(apiResponse)) + callback.onError(ApiError(tag, code).apply { profileId = profile?.id ?: -1 }.withResponse(response).withThrowable(throwable).withApiResponse(apiResponse)) } fun error(tag: String, errorCode: Int, response: Response? = null, apiResponse: String? = null) { var code = when (null) { @@ -180,6 +180,15 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore) else -> errorCode } } - callback.onError(ApiError(profile?.id ?: -1, tag, code).withResponse(response).withApiResponse(apiResponse)) + callback.onError(ApiError(tag, code).apply { profileId = profile?.id ?: -1 }.withResponse(response).withApiResponse(apiResponse)) + } + fun error(apiError: ApiError) { + callback.onError(apiError) + } + fun progress(step: Int) { + callback.onProgress(step) + } + fun startProgress(stringRes: Int) { + callback.onStartProgress(stringRes) } } \ 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 55167232..b65e4f62 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 @@ -16,9 +16,12 @@ import pl.szczodrzynski.edziennik.datamodels.Profile * @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( +data class Endpoint( val loginType: Int, val featureId: Int, val endpointIds: List, - val requiredLoginMethod: Int -) \ No newline at end of file + val requiredLoginMethods: List +) { + val priority + get() = endpointIds.size +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0dd0cdc8..2559d0d9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -908,4 +908,8 @@ Serwer Discord Dołącz do naszego serwera Discord! Debugowanie + Logowanie do Portalu Librus + Logowanie do API + Logowanie do Librus Synergia + Logowanie do wiadomości Librus diff --git a/settings.gradle b/settings.gradle index 8b001cca..692dbba0 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,4 +1,4 @@ -include ':app', ':agendacalendarview', ':MaterialDrawer', ':mhttp', ':material-about-library', ':cafebar', ':szkolny-font', ':nachos' +include ':app', ':agendacalendarview', ':mhttp', ':material-about-library', ':cafebar', ':szkolny-font', ':nachos' /* include ':Navigation' project(':Navigation').projectDir = new File(settingsDir, '../Navigation/navlib')*/