[APIv2] Optimize first login. Add extracting account name, class name, school year. Add Vulcan error handling. Fix Vulcan first login.

This commit is contained in:
Kuba Szczodrzyński 2019-10-27 19:40:50 +01:00
parent 054426c9cc
commit 13b970f4e8
8 changed files with 105 additions and 65 deletions

View File

@ -122,6 +122,29 @@ const val ERROR_LOGIN_VULCAN_INVALID_PIN_1_REMAINING = 311
const val ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING = 312 const val ERROR_LOGIN_VULCAN_INVALID_PIN_2_REMAINING = 312
const val ERROR_LOGIN_VULCAN_EXPIRED_TOKEN = 321 const val ERROR_LOGIN_VULCAN_EXPIRED_TOKEN = 321
const val ERROR_LOGIN_VULCAN_OTHER = 322 const val ERROR_LOGIN_VULCAN_OTHER = 322
const val ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN = 330
const val ERROR_LOGIN_VULCAN_NO_PUPILS = 331
const val ERROR_VULCAN_API_MAINTENANCE = 340
const val ERROR_VULCAN_API_BAD_REQUEST = 341
const val ERROR_VULCAN_API_OTHER = 342
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_LOGIN = 401
const val ERROR_LOGIN_IDZIENNIK_WEB_INVALID_SCHOOL_NAME = 402
const val ERROR_LOGIN_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED = 403
const val ERROR_LOGIN_IDZIENNIK_WEB_MAINTENANCE = 404
const val ERROR_LOGIN_IDZIENNIK_WEB_SERVER_ERROR = 405
const val ERROR_LOGIN_IDZIENNIK_WEB_API_ERROR = 406 /* {"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""} */
const val ERROR_LOGIN_IDZIENNIK_WEB_OTHER = 410
const val ERROR_LOGIN_IDZIENNIK_WEB_API_NO_ACCESS = 411 /* {"d":{"__type":"mds.Web.mod_komunikator.WS_mod_wiadomosci+detailWiadomosci","Wiadomosc":{"_recordId":0,"DataNadania":null,"DataOdczytania":null,"Nadawca":null,"ListaOdbiorcow":[],"Tytul":null,"Text":null,"ListaZal":[]},"Bledy":{"__type":"mds.Module.Globalne+sBledy","CzyJestBlad":true,"ListaBledow":["Nie masz dostępu do tych zasobów!"],"ListaKodowBledow":[]},"czyJestWiecej":false}} */
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_SESSION = 420
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_AUTH = 421
const val ERROR_LOGIN_IDZIENNIK_WEB_NO_BEARER = 422
const val ERROR_IDZIENNIK_WEB_ACCESS_DENIED = 430
const val ERROR_IDZIENNIK_WEB_OTHER = 431
const val ERROR_IDZIENNIK_WEB_MAINTENANCE = 432
const val ERROR_IDZIENNIK_WEB_SERVER_ERROR = 433
const val ERROR_IDZIENNIK_WEB_PASSWORD_CHANGE_NEEDED = 434
const val ERROR_LOGIN_IDZIENNIK_FIRST_NO_SCHOOL_YEAR = 440
const val ERROR_TEMPLATE_WEB_OTHER = 801 const val ERROR_TEMPLATE_WEB_OTHER = 801
@ -134,3 +157,5 @@ const val EXCEPTION_MOBIDZIENNIK_WEB_REQUEST = 906
const val EXCEPTION_VULCAN_API_REQUEST = 907 const val EXCEPTION_VULCAN_API_REQUEST = 907
const val EXCEPTION_NOTIFY_AND_SYNC = 910 const val EXCEPTION_NOTIFY_AND_SYNC = 910
const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911 const val EXCEPTION_LIBRUS_MESSAGES_REQUEST = 911
const val EXCEPTION_IDZIENNIK_WEB_REQUEST = 912
const val EXCEPTION_IDZIENNIK_WEB_API_REQUEST = 913

View File

@ -39,11 +39,6 @@ class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
return@portalGet return@portalGet
} }
val accountDataTime = json.getLong("lastModification") val accountDataTime = json.getLong("lastModification")
val accountIds = mutableListOf<Int>()
val accountLogins = mutableListOf<String>()
val accountTokens = mutableListOf<String>()
val accountNamesLong = mutableListOf<String>()
val accountNamesShort = mutableListOf<String>()
for (accountEl in accounts) { for (accountEl in accounts) {
val account = accountEl.asJsonObject val account = accountEl.asJsonObject
@ -60,26 +55,23 @@ class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
return@portalGet return@portalGet
} }
accountIds.add(account.getInt("id") ?: continue) val id = account.getInt("id") ?: continue
accountLogins.add(account.getString("login") ?: continue) val login = account.getString("login") ?: continue
accountTokens.add(account.getString("accessToken") ?: continue) val token = account.getString("accessToken") ?: continue
accountNamesLong.add(account.getString("studentName") ?: continue) val tokenTime = (accountDataTime ?: 0) + DAY
val nameParts = account.getString("studentName")?.split(" ") ?: continue val name = account.getString("studentName")?.fixName() ?: ""
accountNamesShort.add(nameParts[0] + " " + nameParts[1][0] + ".")
}
for (index in accountIds.indices) { val profile = Profile()
val newProfile = Profile() profile.studentNameLong = name
newProfile.studentNameLong = accountNamesLong[index] profile.studentNameShort = name.getShortName()
newProfile.studentNameShort = accountNamesShort[index] profile.name = profile.studentNameLong
newProfile.name = newProfile.studentNameLong profile.subname = data.portalEmail
newProfile.subname = data.portalEmail profile.empty = true
newProfile.empty = true profile.putStudentData("accountId", id)
newProfile.putStudentData("accountId", accountIds[index]) profile.putStudentData("accountLogin", login)
newProfile.putStudentData("accountLogin", accountLogins[index]) profile.putStudentData("accountToken", token)
newProfile.putStudentData("accountToken", accountTokens[index]) profile.putStudentData("accountTokenTime", tokenTime)
newProfile.putStudentData("accountTokenTime", (accountDataTime ?: 0) + DAY) profileList.add(profile)
profileList.add(newProfile)
} }
EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore)) EventBus.getDefault().post(FirstLoginFinishedEvent(profileList, data.loginStore))

View File

@ -6,6 +6,8 @@ import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikWeb import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikWeb
import pl.szczodrzynski.edziennik.api.v2.mobidziennik.login.MobidziennikLoginWeb import pl.szczodrzynski.edziennik.api.v2.mobidziennik.login.MobidziennikLoginWeb
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
import pl.szczodrzynski.edziennik.fixName
import pl.szczodrzynski.edziennik.utils.models.Date
class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) { class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Unit) {
companion object { companion object {
@ -20,30 +22,33 @@ class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Un
web.webGet(TAG, "/api/zrzutbazy") { text -> web.webGet(TAG, "/api/zrzutbazy") { text ->
val tables = text.split("T@B#LA") val tables = text.split("T@B#LA")
val studentIds = mutableListOf<Int>() val accountNameLong = run {
val studentNamesLong = mutableListOf<String>() tables[0]
val studentNamesShort = mutableListOf<String>() .split("\n")
val student = tables[8].split("\n") .map { it.split("|") }
.singleOrNull { it.getOrNull(1) != "*" }
for (aStudent in student) { ?.let {
if (aStudent.isEmpty()) "${it[4]} ${it[5]}".fixName()
continue }
val student1 = aStudent.split("|")
if (student1.size == 2)
continue
studentIds += student1[0].toInt()
studentNamesLong.add(student1[2] + " " + student1[4])
studentNamesShort.add(student1[2] + " " + student1[4][0] + ".")
} }
for (index in studentIds.indices) { tables[8].split("\n").forEach { student ->
if (student.isEmpty())
return@forEach
val student1 = student.split("|")
if (student1.size == 2)
return@forEach
val today = Date.getToday()
val profile = Profile() val profile = Profile()
profile.studentNameLong = studentNamesLong[index] profile.studentNameLong = "${student1[2]} ${student1[4]}".fixName()
profile.studentNameShort = studentNamesShort[index] profile.studentNameShort = "${student1[2]} ${student1[4][0]}.".fixName()
profile.accountNameLong = if (accountNameLong == profile.studentNameLong) null else accountNameLong
profile.studentSchoolYear = "${today.year}/${today.year+1}"
profile.name = profile.studentNameLong profile.name = profile.studentNameLong
profile.subname = data.loginUsername profile.subname = data.loginUsername
profile.empty = true profile.empty = true
profile.putStudentData("studentId", studentIds[index]) profile.putStudentData("studentId", student1[0].toInt())
profileList.add(profile) profileList.add(profile)
} }

View File

@ -307,6 +307,10 @@ open class Data(val app: App, val profile: Profile?, val loginStore: LoginStore)
} }
fun notifyAndSyncEvents(onSuccess: () -> Unit) { fun notifyAndSyncEvents(onSuccess: () -> Unit) {
if (profile == null) {
onSuccess()
return
}
try { try {
DataNotifications(this) DataNotifications(this)
ServerSync(this) { ServerSync(this) {

View File

@ -178,6 +178,6 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
val fullApiUrl: String? val fullApiUrl: String?
get() { get() {
return "${apiUrl}/${schoolSymbol}/" return "$apiUrl/$schoolSymbol/"
} }
} }

View File

@ -81,7 +81,17 @@ open class VulcanApi(open val data: DataVulcan) {
return return
} }
// TODO: Vulcan error handling if (response?.code() ?: 200 != 200) {
when (response?.code()) {
503 -> ERROR_VULCAN_API_MAINTENANCE
400 -> ERROR_VULCAN_API_BAD_REQUEST
else -> ERROR_VULCAN_API_OTHER
}.let {
data.error(ApiError(tag, EXCEPTION_VULCAN_API_REQUEST)
.withResponse(response)
.withApiResponse(json?.toString() ?: response?.parserErrorBody))
}
}
if (json == null) { if (json == null) {
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY) data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
@ -127,6 +137,7 @@ open class VulcanApi(open val data: DataVulcan) {
.allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST) .allowErrorCode(HttpURLConnection.HTTP_BAD_REQUEST)
.allowErrorCode(HttpURLConnection.HTTP_FORBIDDEN) .allowErrorCode(HttpURLConnection.HTTP_FORBIDDEN)
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED) .allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
.allowErrorCode(HttpURLConnection.HTTP_UNAVAILABLE)
.callback(callback) .callback(callback)
.build() .build()
.enqueue() .enqueue()

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.api.v2.vulcan.firstlogin package pl.szczodrzynski.edziennik.api.v2.vulcan.firstlogin
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.api.v2.ERROR_NO_STUDENTS_IN_ACCOUNT import pl.szczodrzynski.edziennik.api.v2.ERROR_NO_STUDENTS_IN_ACCOUNT
import pl.szczodrzynski.edziennik.api.v2.VULCAN_API_ENDPOINT_STUDENT_LIST import pl.szczodrzynski.edziennik.api.v2.VULCAN_API_ENDPOINT_STUDENT_LIST
import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent import pl.szczodrzynski.edziennik.api.v2.events.FirstLoginFinishedEvent
@ -13,10 +14,6 @@ import pl.szczodrzynski.edziennik.api.v2.vulcan.DataVulcan
import pl.szczodrzynski.edziennik.api.v2.vulcan.data.VulcanApi import pl.szczodrzynski.edziennik.api.v2.vulcan.data.VulcanApi
import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLoginApi import pl.szczodrzynski.edziennik.api.v2.vulcan.login.VulcanLoginApi
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
import pl.szczodrzynski.edziennik.getInt
import pl.szczodrzynski.edziennik.getJsonArray
import pl.szczodrzynski.edziennik.getLong
import pl.szczodrzynski.edziennik.getString
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) { class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
@ -42,23 +39,19 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
students.forEach { studentEl -> students.forEach { studentEl ->
val student = studentEl.asJsonObject val student = studentEl.asJsonObject
val schoolSymbol = student.getString("JednostkaSprawozdawczaSymbol") ?: return@forEach
val schoolName = "${data.symbol}_$schoolSymbol"
val studentId = student.getInt("Id") ?: return@forEach val studentId = student.getInt("Id") ?: return@forEach
val studentLoginId = student.getInt("UzytkownikLoginId") ?: return@forEach val studentLoginId = student.getInt("UzytkownikLoginId") ?: return@forEach
val studentClassId = student.getInt("IdOddzial") ?: return@forEach val studentClassId = student.getInt("IdOddzial") ?: return@forEach
val studentClassNumber = student.getString("OkresPoziom") val studentClassName = student.getString("OkresPoziom").toString() + student.getString("OddzialSymbol")
val studentClassSymbol = student.getString("OddzialSymbol") val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny") ?: return@forEach
val studentClassName = "$studentClassNumber$studentClassSymbol" val studentFirstName = student.getString("Imie") ?: ""
val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny") val studentLastName = student.getString("Nazwisko") ?: ""
?: return@forEach val studentNameLong = "$studentFirstName $studentLastName".fixName()
val studentFirstName = student.getString("Imie") val studentNameShort = "$studentFirstName ${studentLastName[0]}.".fixName()
val studentLastName = student.getString("Nazwisko")
val studentNameLong = "$studentFirstName $studentLastName"
val studentNameShort = "$studentFirstName ${studentLastName?.get(0)}."
val userName = student.getString("UzytkownikNazwa") ?: ""
val userLogin = student.getString("UzytkownikLogin") ?: "" val userLogin = student.getString("UzytkownikLogin") ?: ""
val schoolSymbol = student.getString("JednostkaSprawozdawczaSymbol")
?: return@forEach
val schoolName = "${data.symbol}_$schoolSymbol"
val currentSemesterStartDate = student.getLong("OkresDataOd") ?: return@forEach val currentSemesterStartDate = student.getLong("OkresDataOd") ?: return@forEach
val currentSemesterEndDate = (student.getLong("OkresDataDo") val currentSemesterEndDate = (student.getLong("OkresDataDo")
?: return@forEach) + 86400 ?: return@forEach) + 86400
@ -67,12 +60,20 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
val newProfile = Profile() val newProfile = Profile()
newProfile.empty = true newProfile.empty = true
val isParent = student.getString("UzytkownikRola") == "opiekun"
val userName = if (isParent)
student.getString("UzytkownikNazwa")?.swapFirstLastName()?.fixName()
else
null
newProfile.accountNameLong = userName
newProfile.studentClassName = studentClassName
val today = Date.getToday()
newProfile.studentSchoolYear = "${today.year}/${today.year+1}"
newProfile.putStudentData("studentId", studentId) newProfile.putStudentData("studentId", studentId)
newProfile.putStudentData("studentLoginId", studentLoginId) newProfile.putStudentData("studentLoginId", studentLoginId)
newProfile.putStudentData("studentClassId", studentClassId) newProfile.putStudentData("studentClassId", studentClassId)
newProfile.putStudentData("studentClassName", studentClassName)
newProfile.putStudentData("studentSemesterId", studentSemesterId) newProfile.putStudentData("studentSemesterId", studentSemesterId)
newProfile.putStudentData("userName", userName)
newProfile.putStudentData("schoolSymbol", schoolSymbol) newProfile.putStudentData("schoolSymbol", schoolSymbol)
newProfile.putStudentData("schoolName", schoolName) newProfile.putStudentData("schoolName", schoolName)
newProfile.putStudentData("currentSemesterEndDate", currentSemesterEndDate) newProfile.putStudentData("currentSemesterEndDate", currentSemesterEndDate)

View File

@ -54,7 +54,7 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
}} }}
private fun loginWithToken() { private fun loginWithToken() {
d(TAG, "Request: Vulcan/Login/Api - ${data.apiUrl}$VULCAN_API_ENDPOINT_CERTIFICATE") d(TAG, "Request: Vulcan/Login/Api - ${data.apiUrl}/$VULCAN_API_ENDPOINT_CERTIFICATE")
val callback = object : JsonCallbackHandler() { val callback = object : JsonCallbackHandler() {
override fun onSuccess(json: JsonObject?, response: Response?) { override fun onSuccess(json: JsonObject?, response: Response?) {
@ -85,6 +85,8 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
} }
} }
"Broken" -> ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING "Broken" -> ERROR_LOGIN_VULCAN_INVALID_PIN_0_REMAINING
"OnlyKindergarten" -> ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN
"NoPupils" -> ERROR_LOGIN_VULCAN_NO_PUPILS
else -> ERROR_LOGIN_VULCAN_OTHER else -> ERROR_LOGIN_VULCAN_OTHER
}.let { errorCode -> }.let { errorCode ->
data.error(ApiError(TAG, errorCode) data.error(ApiError(TAG, errorCode)
@ -118,7 +120,7 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
} }
Request.builder() Request.builder()
.url(data.apiUrl + VULCAN_API_ENDPOINT_CERTIFICATE) .url("${data.apiUrl}/$VULCAN_API_ENDPOINT_CERTIFICATE")
.userAgent(VULCAN_API_USER_AGENT) .userAgent(VULCAN_API_USER_AGENT)
.addHeader("RequestMobileType", "RegisterDevice") .addHeader("RequestMobileType", "RegisterDevice")
.addParameter("PIN", data.apiPin) .addParameter("PIN", data.apiPin)