mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 21:06:44 -06:00
[API/Idziennik] Add changing the selected student/register (web) to get grades in some cases.
This commit is contained in:
parent
010f7fa1fe
commit
6a28dbd2c4
@ -60,6 +60,7 @@ const val IDZIENNIK_USER_AGENT = SYNERGIA_USER_AGENT
|
|||||||
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
const val IDZIENNIK_WEB_URL = "https://iuczniowie.progman.pl/idziennik"
|
||||||
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
const val IDZIENNIK_WEB_LOGIN = "login.aspx"
|
||||||
const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.aspx"
|
const val IDZIENNIK_WEB_SETTINGS = "mod_panelRodzica/Ustawienia.aspx"
|
||||||
|
const val IDZIENNIK_WEB_HOME = "mod_panelRodzica/StronaGlowna.aspx"
|
||||||
const val IDZIENNIK_WEB_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec"
|
const val IDZIENNIK_WEB_TIMETABLE = "mod_panelRodzica/plan/WS_Plan.asmx/pobierzPlanZajec"
|
||||||
const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia"
|
const val IDZIENNIK_WEB_GRADES = "mod_panelRodzica/oceny/WS_ocenyUcznia.asmx/pobierzOcenyUcznia"
|
||||||
const val IDZIENNIK_WEB_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia"
|
const val IDZIENNIK_WEB_MISSING_GRADES = "mod_panelRodzica/brak_ocen/WS_BrakOcenUcznia.asmx/pobierzBrakujaceOcenyUcznia"
|
||||||
|
@ -113,6 +113,9 @@ object Regexes {
|
|||||||
val IDZIENNIK_WEB_LUCKY_NUMBER by lazy {
|
val IDZIENNIK_WEB_LUCKY_NUMBER by lazy {
|
||||||
"""dzisiaj to <b>([0-9]+)</b>""".toRegex()
|
"""dzisiaj to <b>([0-9]+)</b>""".toRegex()
|
||||||
}
|
}
|
||||||
|
val IDZIENNIK_WEB_SELECTED_REGISTER by lazy {
|
||||||
|
"""selected="selected" value="([0-9]+)" data-id-ucznia""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,6 +81,11 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
|
|||||||
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
get() { mWebAuth = mWebAuth ?: loginStore.getLoginData("webAuth", null); return mWebAuth }
|
||||||
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
set(value) { loginStore.putLoginData("webAuth", value); mWebAuth = value }
|
||||||
|
|
||||||
|
private var mWebSelectedRegister: Int? = null
|
||||||
|
var webSelectedRegister: Int
|
||||||
|
get() { mWebSelectedRegister = mWebSelectedRegister ?: loginStore.getLoginData("webSelectedRegister", 0); return mWebSelectedRegister ?: 0 }
|
||||||
|
set(value) { loginStore.putLoginData("webSelectedRegister", value); mWebSelectedRegister = value }
|
||||||
|
|
||||||
/* _
|
/* _
|
||||||
/\ (_)
|
/\ (_)
|
||||||
/ \ _ __ _
|
/ \ _ __ _
|
||||||
|
@ -13,6 +13,7 @@ import im.wangchao.mhttp.callback.JsonCallbackHandler
|
|||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web.IdziennikWebSwitchRegister
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -48,6 +49,17 @@ open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response?.code() == HTTP_INTERNAL_ERROR && endpoint == IDZIENNIK_WEB_GRADES) {
|
||||||
|
// special override for accounts where displaying grades
|
||||||
|
// for another student requires switching it manually
|
||||||
|
if (data.registerId != data.webSelectedRegister) {
|
||||||
|
IdziennikWebSwitchRegister(data, data.registerId) {
|
||||||
|
webApiGet(tag, endpoint, parameters, onSuccess)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
when {
|
when {
|
||||||
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
response?.code() == HTTP_UNAUTHORIZED -> ERROR_IDZIENNIK_WEB_ACCESS_DENIED
|
||||||
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
response?.code() == HTTP_INTERNAL_ERROR -> ERROR_IDZIENNIK_WEB_SERVER_ERROR
|
||||||
@ -115,7 +127,7 @@ open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?)
|
|||||||
.enqueue()
|
.enqueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, onSuccess: (text: String) -> Unit) {
|
fun webGet(tag: String, endpoint: String, parameters: Map<String, Any> = emptyMap(), onSuccess: (text: String) -> Unit) {
|
||||||
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
d(tag, "Request: Idziennik/Web - $IDZIENNIK_WEB_URL/$endpoint")
|
||||||
|
|
||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
@ -160,7 +172,14 @@ open class IdziennikWeb(open val data: DataIdziennik, open val lastSync: Long?)
|
|||||||
Request.builder()
|
Request.builder()
|
||||||
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
.url("$IDZIENNIK_WEB_URL/$endpoint")
|
||||||
.userAgent(IDZIENNIK_USER_AGENT)
|
.userAgent(IDZIENNIK_USER_AGENT)
|
||||||
.get()
|
.apply {
|
||||||
|
if (parameters.isEmpty()) get()
|
||||||
|
else post()
|
||||||
|
|
||||||
|
parameters.map { (name, value) ->
|
||||||
|
addParameter(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
.callback(callback)
|
.callback(callback)
|
||||||
.build()
|
.build()
|
||||||
.enqueue()
|
.enqueue()
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
package pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.web
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.IDZIENNIK_WEB_HOME
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.data.IdziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
|
||||||
|
class IdziennikWebSwitchRegister(override val data: DataIdziennik,
|
||||||
|
val registerId: Int,
|
||||||
|
val onSuccess: () -> Unit
|
||||||
|
) : IdziennikWeb(data, null) {
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "IdziennikWebSwitchRegister"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val hiddenFields = data.loginStore.getLoginData("hiddenFields", JsonObject())
|
||||||
|
// TODO error checking
|
||||||
|
|
||||||
|
webGet(TAG, IDZIENNIK_WEB_HOME, mapOf(
|
||||||
|
"__VIEWSTATE" to hiddenFields.getString("__VIEWSTATE", ""),
|
||||||
|
"__VIEWSTATEGENERATOR" to hiddenFields.getString("__VIEWSTATEGENERATOR", ""),
|
||||||
|
"__EVENTVALIDATION" to hiddenFields.getString("__EVENTVALIDATION", ""),
|
||||||
|
"ctl00\$dxComboUczniowie" to registerId
|
||||||
|
)) { text ->
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,15 +8,12 @@ import im.wangchao.mhttp.Request
|
|||||||
import im.wangchao.mhttp.Response
|
import im.wangchao.mhttp.Response
|
||||||
import im.wangchao.mhttp.callback.TextCallbackHandler
|
import im.wangchao.mhttp.callback.TextCallbackHandler
|
||||||
import okhttp3.Cookie
|
import okhttp3.Cookie
|
||||||
import pl.szczodrzynski.edziennik.HOUR
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MINUTE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.idziennik.DataIdziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.getUnixDate
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
@ -73,6 +70,17 @@ class IdziennikLoginWeb(val data: DataIdziennik, val onSuccess: () -> Unit) {
|
|||||||
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
data.loginExpiryTime = response.getUnixDate() + 30 * MINUTE /* after about 40 minutes the login didn't work already */
|
||||||
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
data.apiExpiryTime = response.getUnixDate() + 12 * HOUR /* actually it expires after 24 hours but I'm not sure when does the token refresh. */
|
||||||
|
|
||||||
|
val hiddenFields = JsonObject()
|
||||||
|
Regexes.IDZIENNIK_LOGIN_HIDDEN_FIELDS.findAll(text).forEach {
|
||||||
|
hiddenFields[it[1]] = it[2]
|
||||||
|
}
|
||||||
|
data.loginStore.putLoginData("hiddenFields", hiddenFields)
|
||||||
|
|
||||||
|
Regexes.IDZIENNIK_WEB_SELECTED_REGISTER.find(text)?.let {
|
||||||
|
val registerId = it[1].toIntOrNull() ?: return@let
|
||||||
|
data.webSelectedRegister = registerId
|
||||||
|
}
|
||||||
|
|
||||||
data.profile?.let { profile ->
|
data.profile?.let { profile ->
|
||||||
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
|
Regexes.IDZIENNIK_WEB_LUCKY_NUMBER.find(text)?.also {
|
||||||
val number = it[1].toIntOrNull() ?: return@also
|
val number = it[1].toIntOrNull() ?: return@also
|
||||||
|
@ -43,10 +43,12 @@ class LoginStore(
|
|||||||
fun getLoginData(key: String, defaultValue: Long) = data.getLong(key) ?: defaultValue
|
fun getLoginData(key: String, defaultValue: Long) = data.getLong(key) ?: defaultValue
|
||||||
fun getLoginData(key: String, defaultValue: Float) = data.getFloat(key) ?: defaultValue
|
fun getLoginData(key: String, defaultValue: Float) = data.getFloat(key) ?: defaultValue
|
||||||
fun getLoginData(key: String, defaultValue: Char) = data.getChar(key) ?: defaultValue
|
fun getLoginData(key: String, defaultValue: Char) = data.getChar(key) ?: defaultValue
|
||||||
|
fun getLoginData(key: String, defaultValue: JsonObject) = data.getJsonObject(key) ?: defaultValue
|
||||||
fun putLoginData(key: String, value: Boolean) { data[key] = value }
|
fun putLoginData(key: String, value: Boolean) { data[key] = value }
|
||||||
fun putLoginData(key: String, value: String?) { data[key] = value }
|
fun putLoginData(key: String, value: String?) { data[key] = value }
|
||||||
fun putLoginData(key: String, value: Number) { data[key] = value }
|
fun putLoginData(key: String, value: Number) { data[key] = value }
|
||||||
fun putLoginData(key: String, value: Char) { data[key] = value }
|
fun putLoginData(key: String, value: Char) { data[key] = value }
|
||||||
|
fun putLoginData(key: String, value: JsonObject) { data[key] = value }
|
||||||
fun removeLoginData(key: String) { data.remove(key) }
|
fun removeLoginData(key: String) { data.remove(key) }
|
||||||
|
|
||||||
fun copyFrom(args: Bundle) {
|
fun copyFrom(args: Bundle) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user