forked from github/szkolny
Compare commits
4 Commits
develop
...
feature/gd
Author | SHA1 | Date | |
---|---|---|---|
|
e761a0ec8a | ||
|
ea27492436 | ||
|
3fcd47cf91 | ||
|
cea5071a34 |
@ -1247,3 +1247,13 @@ operator fun <K, V> Iterable<Pair<K, V>>.get(key: K): V? {
|
||||
}
|
||||
|
||||
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
|
||||
|
||||
fun String?.nullIfEmpty() = when {
|
||||
this.isNullOrEmpty() -> null
|
||||
else -> this
|
||||
}
|
||||
|
||||
fun String?.nullIfBlank() = when {
|
||||
this.isNullOrBlank() -> null
|
||||
else -> this
|
||||
}
|
||||
|
@ -122,3 +122,9 @@ const val EDUDZIENNIK_USER_AGENT = "Szkolny.eu/${BuildConfig.VERSION_NAME}"
|
||||
const val PODLASIE_API_VERSION = "1.0.31"
|
||||
const val PODLASIE_API_URL = "https://cpdklaser.zeto.bialystok.pl/api"
|
||||
const val PODLASIE_API_USER_ENDPOINT = "/pobierzDaneUcznia"
|
||||
|
||||
const val GDYNIA_WEB_URL = "https://nasze.miasto.gdynia.pl/ed_miej"
|
||||
const val GDYNIA_WEB_LOGIN = "login.pl"
|
||||
const val GDYNIA_WEB_LOGIN_CHECK = "login_check.pl"
|
||||
const val GDYNIA_WEB_START = "zest_start.pl"
|
||||
const val GDYNIA_WEB_DISPLAY = "display.pl"
|
||||
|
@ -206,6 +206,10 @@ const val ERROR_PODLASIE_API_NO_TOKEN = 630
|
||||
const val ERROR_PODLASIE_API_OTHER = 631
|
||||
const val ERROR_PODLASIE_API_DATA_MISSING = 632
|
||||
|
||||
const val ERROR_LOGIN_GDYNIA_WEB_INVALID_CREDENTIALS = 701
|
||||
const val ERROR_LOGIN_GDYNIA_WEB_MISSING_SESSION_ID = 709
|
||||
const val ERROR_LOGIN_GDYNIA_WEB_OTHER = 710
|
||||
|
||||
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
||||
|
||||
const val EXCEPTION_API_TASK = 900
|
||||
@ -229,5 +233,6 @@ const val ERROR_ONEDRIVE_DOWNLOAD = 930
|
||||
const val EXCEPTION_VULCAN_WEB_LOGIN = 931
|
||||
const val EXCEPTION_VULCAN_WEB_REQUEST = 932
|
||||
const val EXCEPTION_PODLASIE_API_REQUEST = 940
|
||||
const val EXCEPTION_GDYNIA_WEB_REQUEST = 950
|
||||
|
||||
const val LOGIN_NO_ARGUMENTS = 1201
|
||||
|
@ -5,6 +5,7 @@
|
||||
package pl.szczodrzynski.edziennik.data.api
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.login.GdyniaLoginWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginApi
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.login.IdziennikLoginWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
||||
@ -151,6 +152,15 @@ val podlasieLoginMethods = listOf(
|
||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||
)
|
||||
|
||||
const val LOGIN_TYPE_GDYNIA = 7
|
||||
const val LOGIN_MODE_GDYNIA_WEB = 0
|
||||
const val LOGIN_METHOD_GDYNIA_WEB = 100
|
||||
val gdyniaLoginMethods = listOf(
|
||||
LoginMethod(LOGIN_TYPE_GDYNIA, LOGIN_METHOD_GDYNIA_WEB, GdyniaLoginWeb::class.java)
|
||||
.withIsPossible { _, _ -> true }
|
||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||
)
|
||||
|
||||
val templateLoginMethods = listOf(
|
||||
LoginMethod(LOGIN_TYPE_TEMPLATE, LOGIN_METHOD_TEMPLATE_WEB, TemplateLoginWeb::class.java)
|
||||
.withIsPossible { _, _ -> true }
|
||||
|
@ -9,6 +9,7 @@ import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.Gdynia
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.Idziennik
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
||||
@ -82,6 +83,7 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
||||
LOGIN_TYPE_IDZIENNIK -> Idziennik(app, profile, loginStore, taskCallback)
|
||||
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
||||
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
||||
LOGIN_TYPE_GDYNIA -> Gdynia(app, profile, loginStore, taskCallback)
|
||||
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
||||
else -> null
|
||||
}
|
||||
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia
|
||||
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_GDYNIA_WEB
|
||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
|
||||
class DataGdynia(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
|
||||
|
||||
fun isWebLoginValid() = false
|
||||
|
||||
override fun satisfyLoginMethods() {
|
||||
loginMethods.clear()
|
||||
if (isWebLoginValid())
|
||||
loginMethods += LOGIN_METHOD_GDYNIA_WEB
|
||||
}
|
||||
|
||||
override fun generateUserCode(): String {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
private var mLoginUsername: String? = null
|
||||
var loginUsername: String?
|
||||
get() { mLoginUsername = mLoginUsername ?: loginStore.getLoginData("username", null); return mLoginUsername }
|
||||
set(value) { loginStore.putLoginData("username", value); mLoginUsername = value }
|
||||
|
||||
private var mLoginPassword: String? = null
|
||||
var loginPassword: String?
|
||||
get() { mLoginPassword = mLoginPassword ?: loginStore.getLoginData("password", null); return mLoginPassword }
|
||||
set(value) { loginStore.putLoginData("password", value); mLoginPassword = value }
|
||||
|
||||
private var mStudentLogin: String? = null
|
||||
var studentLogin: String?
|
||||
get() { mStudentLogin = mStudentLogin ?: profile?.getStudentData("studentLogin", null); return mStudentLogin }
|
||||
set(value) { profile?.putStudentData("studentLogin", value) ?: return; mStudentLogin = value }
|
||||
|
||||
private var mStudentAlias: String? = null
|
||||
var studentAlias: String?
|
||||
get() { mStudentAlias = mStudentAlias ?: profile?.getStudentData("studentAlias", null); return mStudentAlias }
|
||||
set(value) { profile?.putStudentData("studentAlias", value) ?: return; mStudentAlias = value }
|
||||
|
||||
private var mStudentEmail: String? = null
|
||||
var studentEmail: String?
|
||||
get() { mStudentEmail = mStudentEmail ?: profile?.getStudentData("studentEmail", null); return mStudentEmail }
|
||||
set(value) { profile?.putStudentData("studentEmail", value) ?: return; mStudentEmail = value }
|
||||
|
||||
/* __ __ _
|
||||
\ \ / / | |
|
||||
\ \ /\ / /__| |__
|
||||
\ \/ \/ / _ \ '_ \
|
||||
\ /\ / __/ |_) |
|
||||
\/ \/ \___|_._*/
|
||||
|
||||
/*
|
||||
.-.
|
||||
_.--"""".o/ .-.-._
|
||||
__' ."""; { _J ,__ `.
|
||||
; o\.-.`._.'J; ; / `- / ;
|
||||
`--i`". `" .'; `._ __.' |
|
||||
\ `""" \ `; :
|
||||
`."-. ; ____/ /
|
||||
`-.` `-.-' `"-..'
|
||||
___ `;__.-'" `.
|
||||
.-{_ `--._ /.-" `-.
|
||||
/ ""T ""---...' _.-"" """-. `.
|
||||
; / __.-"". `. `, _..
|
||||
\ / __.-"" '. \ `.,__ .'L' }
|
||||
`---"`-.__ __." .-. j `. : `. .' ,' /
|
||||
"""" / \ : `. | F' \ ;
|
||||
; `-._,L_,-""-. `-, ; ` ; /
|
||||
`. 7 `-._ `.__/_ \/
|
||||
\ _; \ _.' `-. /
|
||||
`---" `.___,, ;"" \ .'
|
||||
_/ ; `"
|
||||
.-" _,-'
|
||||
{ "";
|
||||
;-.____.'`.
|
||||
`. \ '. :
|
||||
\ : : /
|
||||
`':*/
|
||||
private var mWebSid: String? = null
|
||||
var webSid: String?
|
||||
get() { mWebSid = mWebSid ?: loginStore.getLoginData("webSid", null); return mWebSid }
|
||||
set(value) { loginStore.putLoginData("webSid", value); mWebSid = value }
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.data.GdyniaData
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.firstlogin.GdyniaFirstLogin
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.login.GdyniaLogin
|
||||
import pl.szczodrzynski.edziennik.data.api.gdyniaLoginMethods
|
||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikCallback
|
||||
import pl.szczodrzynski.edziennik.data.api.interfaces.EdziennikInterface
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.prepare
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class Gdynia(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
||||
companion object {
|
||||
private const val TAG = "Gdynia"
|
||||
}
|
||||
|
||||
val internalErrorList = mutableListOf<Int>()
|
||||
val data: DataGdynia
|
||||
|
||||
init {
|
||||
data = DataGdynia(app, profile, loginStore).apply {
|
||||
callback = wrapCallback(this@Gdynia.callback)
|
||||
satisfyLoginMethods()
|
||||
}
|
||||
}
|
||||
|
||||
private fun completed() {
|
||||
data.saveData()
|
||||
callback.onCompleted()
|
||||
}
|
||||
|
||||
/* _______ _ _ _ _ _
|
||||
|__ __| | /\ | | (_) | | |
|
||||
| | | |__ ___ / \ | | __ _ ___ _ __ _| |_| |__ _ __ ___
|
||||
| | | '_ \ / _ \ / /\ \ | |/ _` |/ _ \| '__| | __| '_ \| '_ ` _ \
|
||||
| | | | | | __/ / ____ \| | (_| | (_) | | | | |_| | | | | | | | |
|
||||
|_| |_| |_|\___| /_/ \_\_|\__, |\___/|_| |_|\__|_| |_|_| |_| |_|
|
||||
__/ |
|
||||
|__*/
|
||||
override fun sync(featureIds: List<Int>, viewId: Int?, onlyEndpoints: List<Int>?, arguments: JsonObject?) {
|
||||
data.arguments = arguments
|
||||
data.prepare(gdyniaLoginMethods, GdyniaFeatures, featureIds, viewId, onlyEndpoints)
|
||||
Utils.d(TAG, "LoginMethod IDs: ${data.targetLoginMethodIds}")
|
||||
Utils.d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
||||
GdyniaLogin(data) {
|
||||
GdyniaData(data) {
|
||||
completed()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMessage(message: MessageFull) {
|
||||
|
||||
}
|
||||
|
||||
override fun sendMessage(recipients: List<Teacher>, subject: String, text: String) {
|
||||
|
||||
}
|
||||
|
||||
override fun markAllAnnouncementsAsRead() {
|
||||
|
||||
}
|
||||
|
||||
override fun getAnnouncement(announcement: AnnouncementFull) {
|
||||
|
||||
}
|
||||
|
||||
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {
|
||||
|
||||
}
|
||||
|
||||
override fun getRecipientList() {
|
||||
|
||||
}
|
||||
|
||||
override fun getEvent(eventFull: EventFull) {
|
||||
|
||||
}
|
||||
|
||||
override fun firstLogin() {
|
||||
GdyniaFirstLogin(data) {
|
||||
completed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
Utils.d(TAG, "Cancelled")
|
||||
data.cancel()
|
||||
callback.onCompleted()
|
||||
}
|
||||
|
||||
private fun wrapCallback(callback: EdziennikCallback): EdziennikCallback {
|
||||
return object : EdziennikCallback {
|
||||
override fun onCompleted() {
|
||||
callback.onCompleted()
|
||||
}
|
||||
|
||||
override fun onProgress(step: Float) {
|
||||
callback.onProgress(step)
|
||||
}
|
||||
|
||||
override fun onStartProgress(stringRes: Int) {
|
||||
callback.onStartProgress(stringRes)
|
||||
}
|
||||
|
||||
override fun onError(apiError: ApiError) {
|
||||
// TODO Error handling
|
||||
when (apiError.errorCode) {
|
||||
in internalErrorList -> {
|
||||
// finish immediately if the same error occurs twice during the same sync
|
||||
callback.onError(apiError)
|
||||
}
|
||||
else -> callback.onError(apiError)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
||||
|
||||
val GdyniaFeatures = listOf<Feature>()
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.data
|
||||
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.DataGdynia
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class GdyniaData(val data: DataGdynia, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "GdyniaData"
|
||||
}
|
||||
|
||||
init {
|
||||
nextEndpoint(onSuccess)
|
||||
}
|
||||
|
||||
private fun nextEndpoint(onSuccess: () -> Unit) {
|
||||
if (data.targetEndpointIds.isEmpty()) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
if (data.cancelled) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
val id = data.targetEndpointIds.firstKey()
|
||||
val lastSync = data.targetEndpointIds.remove(id)
|
||||
useEndpoint(id, lastSync) {
|
||||
data.progress(data.progressStep)
|
||||
nextEndpoint(onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
private fun useEndpoint(endpointId: Int, lastSync: Long?, onSuccess: (endpointId: Int) -> Unit) {
|
||||
Utils.d(TAG, "Using endpoint $endpointId. Last sync time = $lastSync")
|
||||
when (endpointId) {
|
||||
else -> onSuccess(endpointId)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.data
|
||||
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.DataGdynia
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
|
||||
open class GdyniaWeb(open val data: DataGdynia, open val lastSync: Long?) {
|
||||
companion object {
|
||||
private const val TAG = "GdyniaWeb"
|
||||
}
|
||||
|
||||
fun webGet(tag: String, endpoint: String, parameters: Map<String, Any?>? = null, onSuccess: (text: String) -> Unit) {
|
||||
val url = "$GDYNIA_WEB_URL/$endpoint"
|
||||
d(tag, "Request: Gdynia/Web - $url")
|
||||
|
||||
val callback = object : TextCallbackHandler() {
|
||||
override fun onSuccess(text: String?, response: Response?) {
|
||||
if (text == null || response == null) {
|
||||
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
|
||||
.withResponse(response)
|
||||
.withApiResponse(text))
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
onSuccess(text)
|
||||
} catch (e: Exception) {
|
||||
data.error(ApiError(tag, EXCEPTION_GDYNIA_WEB_REQUEST)
|
||||
.withApiResponse(text)
|
||||
.withResponse(response)
|
||||
.withThrowable(e))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
||||
.withResponse(response)
|
||||
.withThrowable(throwable))
|
||||
}
|
||||
}
|
||||
|
||||
Request.builder()
|
||||
.url(url)
|
||||
.userAgent(SYSTEM_USER_AGENT)
|
||||
.apply {
|
||||
parameters?.forEach { (key, value) ->
|
||||
addParameter(key, value)
|
||||
}
|
||||
}
|
||||
.get()
|
||||
.callback(callback)
|
||||
.build()
|
||||
.enqueue()
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.firstlogin
|
||||
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.jsoup.Jsoup
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.api.GDYNIA_WEB_DISPLAY
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_GDYNIA
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.DataGdynia
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.data.GdyniaWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.login.GdyniaLoginWeb
|
||||
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
|
||||
class GdyniaFirstLogin(val data: DataGdynia, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "GdyniaFirstLogin"
|
||||
}
|
||||
|
||||
private val web = GdyniaWeb(data, null)
|
||||
private val profileList = mutableListOf<Profile>()
|
||||
|
||||
init {
|
||||
val loginStoreId = data.loginStore.id
|
||||
val loginStoreType = LOGIN_TYPE_GDYNIA
|
||||
|
||||
GdyniaLoginWeb(data) {
|
||||
web.webGet(TAG, GDYNIA_WEB_DISPLAY, parameters = mapOf(
|
||||
"form" to "zmiana_danych"
|
||||
)) { html ->
|
||||
run {
|
||||
val doc = Jsoup.parse(html)
|
||||
|
||||
val firstName = doc.selectFirst("#f_imie")?.`val`() ?: return@run
|
||||
val lastName = doc.selectFirst("#f_nazwisko")?.`val`() ?: return@run
|
||||
val studentNameLong = "$firstName $lastName".fixName()
|
||||
val studentNameShort = studentNameLong.getShortName()
|
||||
|
||||
val login = doc.selectFirst("#f_login").`val`().nullIfBlank()
|
||||
val alias = doc.selectFirst("#f_kod_logowania").`val`().nullIfBlank()
|
||||
val email = doc.selectFirst("#f_email")?.`val`().nullIfBlank()
|
||||
|
||||
val subname = alias ?: email ?: data.loginUsername
|
||||
|
||||
val profile = Profile(
|
||||
loginStoreId,
|
||||
loginStoreId,
|
||||
loginStoreType,
|
||||
studentNameLong,
|
||||
subname,
|
||||
studentNameLong,
|
||||
studentNameShort,
|
||||
null
|
||||
).apply {
|
||||
studentData["studentLogin"] = login
|
||||
studentData["studentAlias"] = alias
|
||||
studentData["studentEmail"] = email
|
||||
}
|
||||
|
||||
profileList.add(profile)
|
||||
}
|
||||
|
||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.login
|
||||
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_GDYNIA_WEB
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.DataGdynia
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class GdyniaLogin(val data: DataGdynia, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "GdyniaLogin"
|
||||
}
|
||||
|
||||
init {
|
||||
nextLoginMethod(onSuccess)
|
||||
}
|
||||
|
||||
private var cancelled = false
|
||||
|
||||
private fun nextLoginMethod(onSuccess: () -> Unit) {
|
||||
if (data.targetLoginMethodIds.isEmpty()) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
if (cancelled) {
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
useLoginMethod(data.targetLoginMethodIds.removeAt(0)) { usedMethodId ->
|
||||
data.progress(data.progressStep)
|
||||
if (usedMethodId != -1)
|
||||
data.loginMethods.add(usedMethodId)
|
||||
nextLoginMethod(onSuccess)
|
||||
}
|
||||
}
|
||||
|
||||
private fun useLoginMethod(loginMethodId: Int, onSuccess: (usedMethodId: Int) -> Unit) {
|
||||
// this should never be true
|
||||
if (data.loginMethods.contains(loginMethodId)) {
|
||||
onSuccess(-1)
|
||||
return
|
||||
}
|
||||
Utils.d(TAG, "Using login method $loginMethodId")
|
||||
when (loginMethodId) {
|
||||
LOGIN_METHOD_GDYNIA_WEB -> {
|
||||
data.startProgress(R.string.edziennik_progress_login_gdynia_web)
|
||||
GdyniaLoginWeb(data) { onSuccess(loginMethodId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (c) Kacper Ziubryniewicz 2020-5-17
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.login
|
||||
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.gdynia.DataGdynia
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.get
|
||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
||||
import pl.szczodrzynski.edziennik.md5
|
||||
|
||||
class GdyniaLoginWeb(val data: DataGdynia, val onSuccess: () -> Unit) {
|
||||
companion object {
|
||||
private const val TAG = "GdyniaLoginWeb"
|
||||
}
|
||||
|
||||
init {
|
||||
run {
|
||||
if (data.isWebLoginValid()) {
|
||||
data.app.cookieJar.set("nasze.miasto.gdynia.pl", "sid", data.webSid)
|
||||
onSuccess()
|
||||
} else {
|
||||
data.app.cookieJar.clear("nasze.miasto.gdynia.pl")
|
||||
if (data.loginUsername.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
||||
loginWithCredentials()
|
||||
} else {
|
||||
data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loginWithCredentials() {
|
||||
val callback = object : TextCallbackHandler() {
|
||||
override fun onSuccess(text: String?, response: Response?) {
|
||||
if (text == null || response == null) {
|
||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
||||
.withResponse(response))
|
||||
return
|
||||
}
|
||||
|
||||
val error = """<p class="logging_error">(.*?)</p>""".toRegex().find(text)?.get(1)?.trim()
|
||||
|
||||
error?.let { code ->
|
||||
when (code) {
|
||||
"Niepoprawna nazwa użytkownika lub hasło" -> ERROR_LOGIN_GDYNIA_WEB_INVALID_CREDENTIALS
|
||||
else -> ERROR_LOGIN_GDYNIA_WEB_OTHER
|
||||
}.let { errorCode ->
|
||||
data.error(ApiError(TAG, errorCode)
|
||||
.withApiResponse(text)
|
||||
.withResponse(response))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val cookies = data.app.cookieJar.getAll("nasze.miasto.gdynia.pl")
|
||||
val sid = cookies["sid"]
|
||||
|
||||
if (sid == null) {
|
||||
data.error(ApiError(TAG, ERROR_LOGIN_GDYNIA_WEB_MISSING_SESSION_ID)
|
||||
.withApiResponse(text)
|
||||
.withResponse(response))
|
||||
return
|
||||
}
|
||||
|
||||
data.webSid = sid
|
||||
|
||||
onSuccess()
|
||||
return
|
||||
}
|
||||
|
||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
||||
.withResponse(response)
|
||||
.withThrowable(throwable))
|
||||
}
|
||||
}
|
||||
|
||||
Request.builder()
|
||||
.url("$GDYNIA_WEB_URL/$GDYNIA_WEB_LOGIN")
|
||||
.userAgent(SYSTEM_USER_AGENT)
|
||||
.addParameter("action", "set")
|
||||
.addParameter("user", data.loginUsername)
|
||||
.addParameter("login", "Zaloguj się")
|
||||
.addParameter("pass_md5", data.loginPassword?.md5())
|
||||
.addParameter("url_back", "")
|
||||
.post()
|
||||
.callback(callback)
|
||||
.build()
|
||||
.enqueue()
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.data
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import im.wangchao.mhttp.Request
|
||||
import im.wangchao.mhttp.RequestParams
|
||||
import im.wangchao.mhttp.Response
|
||||
import im.wangchao.mhttp.callback.JsonCallbackHandler
|
||||
import pl.szczodrzynski.edziennik.data.api.*
|
||||
@ -86,12 +85,11 @@ open class PodlasieApi(open val data: DataPodlasie, open val lastSync: Long?) {
|
||||
Request.builder()
|
||||
.url(url)
|
||||
.userAgent(SYSTEM_USER_AGENT)
|
||||
.requestParams(RequestParams(mapOf(
|
||||
"token" to data.apiToken,
|
||||
"securityToken" to getSecurityToken(),
|
||||
"mobileId" to data.app.deviceId,
|
||||
"ver" to PODLASIE_API_VERSION
|
||||
)))
|
||||
.addParameter("token", data.apiToken)
|
||||
.addParameter("securityToken", getSecurityToken())
|
||||
.addParameter("mobileId", data.app.deviceId)
|
||||
.addParameter("ver", PODLASIE_API_VERSION)
|
||||
.get()
|
||||
.callback(callback)
|
||||
.build()
|
||||
.enqueue()
|
||||
|
@ -34,7 +34,7 @@ class TemplateData(val data: DataTemplate, val onSuccess: () -> Unit) {
|
||||
}
|
||||
val id = data.targetEndpointIds.firstKey()
|
||||
val lastSync = data.targetEndpointIds.remove(id)
|
||||
useEndpoint(id, lastSync) { endpointId ->
|
||||
useEndpoint(id, lastSync) {
|
||||
data.progress(data.progressStep)
|
||||
nextEndpoint(onSuccess)
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.template.login
|
||||
|
||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_DATA_MISSING
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_PROFILE_MISSING
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.template.DataTemplate
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
|
||||
@ -16,11 +15,6 @@ class TemplateLoginWeb(val data: DataTemplate, val onSuccess: () -> Unit) {
|
||||
}
|
||||
|
||||
init { run {
|
||||
if (data.profile == null) {
|
||||
data.error(ApiError(TAG, ERROR_PROFILE_MISSING))
|
||||
return@run
|
||||
}
|
||||
|
||||
if (data.isWebLoginValid()) {
|
||||
data.app.cookieJar.set("eregister.example.com", "AuthCookie", data.webCookie)
|
||||
onSuccess()
|
||||
|
@ -361,6 +361,37 @@ object LoginInfo {
|
||||
errorCodes = mapOf()
|
||||
)
|
||||
)
|
||||
),
|
||||
Register(
|
||||
loginType = LOGIN_TYPE_GDYNIA,
|
||||
internalName = "gdynia",
|
||||
registerName = R.string.login_type_gdynia,
|
||||
registerLogo = R.drawable.login_logo_gdynia,
|
||||
loginModes = listOf(
|
||||
Mode(
|
||||
loginMode = LOGIN_MODE_GDYNIA_WEB,
|
||||
name = R.string.login_mode_gdynia_web,
|
||||
icon = R.drawable.login_mode_gdynia_web,
|
||||
guideText = R.string.login_mode_gdynia_web_guide,
|
||||
credentials = listOf(
|
||||
Credential(
|
||||
keyName = "username",
|
||||
name = R.string.login_hint_username,
|
||||
icon = CommunityMaterial.Icon.cmd_account_outline,
|
||||
emptyText = R.string.login_error_no_username,
|
||||
invalidText = R.string.login_error_incorrect_username,
|
||||
errorCodes = mapOf(),
|
||||
isRequired = true,
|
||||
validationRegex = "^[a-zA-Z0-9_\\-.]+$",
|
||||
caseMode = Credential.CaseMode.UNCHANGED
|
||||
),
|
||||
getPasswordCredential("password")
|
||||
),
|
||||
errorCodes = mapOf(
|
||||
ERROR_LOGIN_GDYNIA_WEB_INVALID_CREDENTIALS to R.string.login_error_incorrect_login_or_password
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
) }
|
||||
|
||||
|
BIN
app/src/main/res/drawable/login_logo_gdynia.png
Normal file
BIN
app/src/main/res/drawable/login_logo_gdynia.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
BIN
app/src/main/res/drawable/login_mode_gdynia_web.png
Normal file
BIN
app/src/main/res/drawable/login_mode_gdynia_web.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
@ -166,6 +166,10 @@
|
||||
<string name="error_631" translatable="false">ERROR_PODLASIE_API_OTHER</string>
|
||||
<string name="error_632" translatable="false">ERROR_PODLASIE_API_DATA_MISSING</string>
|
||||
|
||||
<string name="error_701" translatable="false">ERROR_LOGIN_GDYNIA_WEB_INVALID_CREDENTIALS</string>
|
||||
<string name="error_709" translatable="false">ERROR_LOGIN_GDYNIA_WEB_MISSING_SESSION_ID</string>
|
||||
<string name="error_710" translatable="false">ERROR_LOGIN_GDYNIA_WEB_OTHER</string>
|
||||
|
||||
<string name="error_801" translatable="false">ERROR_TEMPLATE_WEB_OTHER</string>
|
||||
|
||||
<string name="error_900" translatable="false">EXCEPTION_API_TASK</string>
|
||||
@ -189,6 +193,7 @@
|
||||
<string name="error_931" translatable="false">EXCEPTION_VULCAN_WEB_LOGIN</string>
|
||||
<string name="error_932" translatable="false">EXCEPTION_VULCAN_WEB_REQUEST</string>
|
||||
<string name="error_940" translatable="false">EXCEPTION_PODLASIE_API_REQUEST</string>
|
||||
<string name="error_950" translatable="false">EXCEPTION_GDYNIA_WEB_REQUEST</string>
|
||||
|
||||
<string name="error_1201" translatable="false">LOGIN_NO_ARGUMENTS</string>
|
||||
|
||||
@ -354,6 +359,10 @@
|
||||
<string name="error_631_reason">ERROR_PODLASIE_API_OTHER</string>
|
||||
<string name="error_632_reason">Brak danych. Zgłoś błąd programiście.</string>
|
||||
|
||||
<string name="error_701_reason">Niepoprawna nazwa użytkownika lub hasło</string>
|
||||
<string name="error_709_reason">Brakujące ID sesji. Zgłoś błąd programiście.</string>
|
||||
<string name="error_710_reason">Wystąpił błąd podczas logowania</string>
|
||||
|
||||
<string name="error_801_reason">ERROR_TEMPLATE_WEB_OTHER</string>
|
||||
|
||||
<string name="error_900_reason">Błąd synchronizacji. Upewnij się, że masz połączenie z internetem, a następnie zgłoś błąd.</string>
|
||||
@ -377,6 +386,7 @@
|
||||
<string name="error_931_reason">EXCEPTION_VULCAN_WEB_LOGIN</string>
|
||||
<string name="error_932_reason">EXCEPTION_VULCAN_WEB_REQUEST</string>
|
||||
<string name="error_940_reason">Zgłoś błąd: wyjątek w API PPE</string>
|
||||
<string name="error_950_reason">Zgłoś błąd: wyjątek w dzienniku Platformy Miejskiej Gdyni</string>
|
||||
|
||||
<string name="error_1201_reason">Nie podano parametrów</string>
|
||||
</resources>
|
||||
|
@ -1343,7 +1343,7 @@
|
||||
<string name="login_mode_vulcan_api_guide">Zaloguj się do dziennika Vulcan na komputerze, wybierz zakładkę Dostęp Mobilny, kliknij przycisk Zarejestruj urządzenie mobilne. Podaj otrzymany Token, Symbol i PIN w polach poniżej.</string>
|
||||
<string name="login_mode_vulcan_web_guide">Podaj dane, którymi logujesz się na stronie internetowej dziennika VULCAN lub na miejskiej platformie.</string>
|
||||
<string name="login_mode_mobidziennik_web_guide">Podaj dane, których używasz do logowania na stronie MobiDziennika. Jako adres serwera możesz wpisać adres strony internetowej, na której masz MobiDziennik.</string>
|
||||
<string name="edziennik_progress_login_vulcan_web_main">Logowanie do dziennika Vulcan...</string>
|
||||
<string name="edziennik_progress_login_vulcan_web_main">Logowanie do dziennika Vulcan…</string>
|
||||
<string name="login_type_idziennik">iDziennik Progman / iUczniowie</string>
|
||||
<string name="login_mode_idziennik_web">Zaloguj używając nazwy użytkownika i hasła</string>
|
||||
<string name="login_mode_idziennik_web_hint">Podaj dane, których używasz na stronie internetowej e-dziennika</string>
|
||||
@ -1356,4 +1356,8 @@
|
||||
<string name="login_mode_podlasie_api">Zaloguj używając tokenu</string>
|
||||
<string name="login_mode_podlasie_api_guide">Podaj token aplikacji mobilnej.</string>
|
||||
<string name="edziennik_progress_login_podlasie_api">Logowanie do PPE…</string>
|
||||
<string name="edziennik_progress_login_gdynia_web">Logowanie do dziennika gdyńskiego…</string>
|
||||
<string name="login_type_gdynia">Platforma Miejska Gdyni</string>
|
||||
<string name="login_mode_gdynia_web">Zaloguj używając nazwy użytkownika i hasła</string>
|
||||
<string name="login_mode_gdynia_web_guide">Podaj nazwę użytkownika oraz hasło, za pomocą których logujesz się na stronie internetowej dziennika.</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user