[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_EXPIRED_TOKEN = 321
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
@ -134,3 +157,5 @@ const val EXCEPTION_MOBIDZIENNIK_WEB_REQUEST = 906
const val EXCEPTION_VULCAN_API_REQUEST = 907
const val EXCEPTION_NOTIFY_AND_SYNC = 910
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
}
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) {
val account = accountEl.asJsonObject
@ -60,26 +55,23 @@ class LibrusFirstLogin(val data: DataLibrus, val onSuccess: () -> Unit) {
return@portalGet
}
accountIds.add(account.getInt("id") ?: continue)
accountLogins.add(account.getString("login") ?: continue)
accountTokens.add(account.getString("accessToken") ?: continue)
accountNamesLong.add(account.getString("studentName") ?: continue)
val nameParts = account.getString("studentName")?.split(" ") ?: continue
accountNamesShort.add(nameParts[0] + " " + nameParts[1][0] + ".")
}
val id = account.getInt("id") ?: continue
val login = account.getString("login") ?: continue
val token = account.getString("accessToken") ?: continue
val tokenTime = (accountDataTime ?: 0) + DAY
val name = account.getString("studentName")?.fixName() ?: ""
for (index in accountIds.indices) {
val newProfile = Profile()
newProfile.studentNameLong = accountNamesLong[index]
newProfile.studentNameShort = accountNamesShort[index]
newProfile.name = newProfile.studentNameLong
newProfile.subname = data.portalEmail
newProfile.empty = true
newProfile.putStudentData("accountId", accountIds[index])
newProfile.putStudentData("accountLogin", accountLogins[index])
newProfile.putStudentData("accountToken", accountTokens[index])
newProfile.putStudentData("accountTokenTime", (accountDataTime ?: 0) + DAY)
profileList.add(newProfile)
val profile = Profile()
profile.studentNameLong = name
profile.studentNameShort = name.getShortName()
profile.name = profile.studentNameLong
profile.subname = data.portalEmail
profile.empty = true
profile.putStudentData("accountId", id)
profile.putStudentData("accountLogin", login)
profile.putStudentData("accountToken", token)
profile.putStudentData("accountTokenTime", tokenTime)
profileList.add(profile)
}
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.login.MobidziennikLoginWeb
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) {
companion object {
@ -20,30 +22,33 @@ class MobidziennikFirstLogin(val data: DataMobidziennik, val onSuccess: () -> Un
web.webGet(TAG, "/api/zrzutbazy") { text ->
val tables = text.split("T@B#LA")
val studentIds = mutableListOf<Int>()
val studentNamesLong = mutableListOf<String>()
val studentNamesShort = mutableListOf<String>()
val student = tables[8].split("\n")
for (aStudent in student) {
if (aStudent.isEmpty())
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] + ".")
val accountNameLong = run {
tables[0]
.split("\n")
.map { it.split("|") }
.singleOrNull { it.getOrNull(1) != "*" }
?.let {
"${it[4]} ${it[5]}".fixName()
}
}
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()
profile.studentNameLong = studentNamesLong[index]
profile.studentNameShort = studentNamesShort[index]
profile.studentNameLong = "${student1[2]} ${student1[4]}".fixName()
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.subname = data.loginUsername
profile.empty = true
profile.putStudentData("studentId", studentIds[index])
profile.putStudentData("studentId", student1[0].toInt())
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) {
if (profile == null) {
onSuccess()
return
}
try {
DataNotifications(this)
ServerSync(this) {

View File

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

View File

@ -81,7 +81,17 @@ open class VulcanApi(open val data: DataVulcan) {
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) {
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_FORBIDDEN)
.allowErrorCode(HttpURLConnection.HTTP_UNAUTHORIZED)
.allowErrorCode(HttpURLConnection.HTTP_UNAVAILABLE)
.callback(callback)
.build()
.enqueue()

View File

@ -5,6 +5,7 @@
package pl.szczodrzynski.edziennik.api.v2.vulcan.firstlogin
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.VULCAN_API_ENDPOINT_STUDENT_LIST
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.login.VulcanLoginApi
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
class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
@ -42,23 +39,19 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
students.forEach { studentEl ->
val student = studentEl.asJsonObject
val schoolSymbol = student.getString("JednostkaSprawozdawczaSymbol") ?: return@forEach
val schoolName = "${data.symbol}_$schoolSymbol"
val studentId = student.getInt("Id") ?: return@forEach
val studentLoginId = student.getInt("UzytkownikLoginId") ?: return@forEach
val studentClassId = student.getInt("IdOddzial") ?: return@forEach
val studentClassNumber = student.getString("OkresPoziom")
val studentClassSymbol = student.getString("OddzialSymbol")
val studentClassName = "$studentClassNumber$studentClassSymbol"
val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny")
?: return@forEach
val studentFirstName = student.getString("Imie")
val studentLastName = student.getString("Nazwisko")
val studentNameLong = "$studentFirstName $studentLastName"
val studentNameShort = "$studentFirstName ${studentLastName?.get(0)}."
val userName = student.getString("UzytkownikNazwa") ?: ""
val studentClassName = student.getString("OkresPoziom").toString() + student.getString("OddzialSymbol")
val studentSemesterId = student.getInt("IdOkresKlasyfikacyjny") ?: return@forEach
val studentFirstName = student.getString("Imie") ?: ""
val studentLastName = student.getString("Nazwisko") ?: ""
val studentNameLong = "$studentFirstName $studentLastName".fixName()
val studentNameShort = "$studentFirstName ${studentLastName[0]}.".fixName()
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 currentSemesterEndDate = (student.getLong("OkresDataDo")
?: return@forEach) + 86400
@ -67,12 +60,20 @@ class VulcanFirstLogin(val data: DataVulcan, val onSuccess: () -> Unit) {
val newProfile = Profile()
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("studentLoginId", studentLoginId)
newProfile.putStudentData("studentClassId", studentClassId)
newProfile.putStudentData("studentClassName", studentClassName)
newProfile.putStudentData("studentSemesterId", studentSemesterId)
newProfile.putStudentData("userName", userName)
newProfile.putStudentData("schoolSymbol", schoolSymbol)
newProfile.putStudentData("schoolName", schoolName)
newProfile.putStudentData("currentSemesterEndDate", currentSemesterEndDate)

View File

@ -54,7 +54,7 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
}}
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() {
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
"OnlyKindergarten" -> ERROR_LOGIN_VULCAN_ONLY_KINDERGARTEN
"NoPupils" -> ERROR_LOGIN_VULCAN_NO_PUPILS
else -> ERROR_LOGIN_VULCAN_OTHER
}.let { errorCode ->
data.error(ApiError(TAG, errorCode)
@ -118,7 +120,7 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
}
Request.builder()
.url(data.apiUrl + VULCAN_API_ENDPOINT_CERTIFICATE)
.url("${data.apiUrl}/$VULCAN_API_ENDPOINT_CERTIFICATE")
.userAgent(VULCAN_API_USER_AGENT)
.addHeader("RequestMobileType", "RegisterDevice")
.addParameter("PIN", data.apiPin)