mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-01-18 12:56:45 -06:00
[API] Remove EduDziennik implementation [*]
This commit is contained in:
parent
9dbb5d70e9
commit
37c68443bd
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginApi
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginMessages
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.login.LibrusLoginPortal
|
||||||
@ -26,8 +25,9 @@ import pl.szczodrzynski.edziennik.data.api.models.LoginMethod
|
|||||||
|
|
||||||
const val SYNERGIA_API_ENABLED = false
|
const val SYNERGIA_API_ENABLED = false
|
||||||
|
|
||||||
|
// the graveyard
|
||||||
const val LOGIN_TYPE_IDZIENNIK = 3
|
const val LOGIN_TYPE_IDZIENNIK = 3
|
||||||
|
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
||||||
|
|
||||||
const val LOGIN_TYPE_TEMPLATE = 21
|
const val LOGIN_TYPE_TEMPLATE = 21
|
||||||
|
|
||||||
@ -118,15 +118,6 @@ val vulcanLoginMethods = listOf(
|
|||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
||||||
)
|
)
|
||||||
|
|
||||||
const val LOGIN_TYPE_EDUDZIENNIK = 5
|
|
||||||
const val LOGIN_MODE_EDUDZIENNIK_WEB = 0
|
|
||||||
const val LOGIN_METHOD_EDUDZIENNIK_WEB = 100
|
|
||||||
val edudziennikLoginMethods = listOf(
|
|
||||||
LoginMethod(LOGIN_TYPE_EDUDZIENNIK, LOGIN_METHOD_EDUDZIENNIK_WEB, EdudziennikLoginWeb::class.java)
|
|
||||||
.withIsPossible { _, _ -> true }
|
|
||||||
.withRequiredLoginMethod { _, _ -> LOGIN_METHOD_NOT_NEEDED }
|
|
||||||
)
|
|
||||||
|
|
||||||
const val LOGIN_TYPE_PODLASIE = 6
|
const val LOGIN_TYPE_PODLASIE = 6
|
||||||
const val LOGIN_MODE_PODLASIE_API = 0
|
const val LOGIN_MODE_PODLASIE_API = 0
|
||||||
const val LOGIN_METHOD_PODLASIE_API = 100
|
const val LOGIN_METHOD_PODLASIE_API = 100
|
||||||
|
@ -8,7 +8,6 @@ import com.google.gson.JsonObject
|
|||||||
import org.greenrobot.eventbus.EventBus
|
import org.greenrobot.eventbus.EventBus
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
import pl.szczodrzynski.edziennik.data.api.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.Edudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
import pl.szczodrzynski.edziennik.data.api.edziennik.librus.Librus
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
import pl.szczodrzynski.edziennik.data.api.edziennik.mobidziennik.Mobidziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
|
import pl.szczodrzynski.edziennik.data.api.edziennik.podlasie.Podlasie
|
||||||
@ -112,7 +111,6 @@ open class EdziennikTask(override val profileId: Int, val request: Any) : IApiTa
|
|||||||
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_LIBRUS -> Librus(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_MOBIDZIENNIK -> Mobidziennik(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_VULCAN -> Vulcan(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_EDUDZIENNIK -> Edudziennik(app, profile, loginStore, taskCallback)
|
|
||||||
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_PODLASIE -> Podlasie(app, profile, loginStore, taskCallback)
|
||||||
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
LOGIN_TYPE_TEMPLATE -> Template(app, profile, loginStore, taskCallback)
|
||||||
else -> null
|
else -> null
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.ext.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
|
||||||
*
|
|
||||||
* Use https://codepen.io/kubasz/pen/RwwwbGN to easily generate the student data getters/setters
|
|
||||||
*/
|
|
||||||
class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(app, profile, loginStore) {
|
|
||||||
|
|
||||||
fun isWebLoginValid() = webSessionIdExpiryTime-30 > currentTimeUnix() && webSessionId.isNotNullNorEmpty()
|
|
||||||
|
|
||||||
override fun satisfyLoginMethods() {
|
|
||||||
loginMethods.clear()
|
|
||||||
if (isWebLoginValid()) {
|
|
||||||
loginMethods += LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun generateUserCode() = "$schoolName:$loginEmail:${studentId?.crc32()}"
|
|
||||||
|
|
||||||
private var mLoginEmail: String? = null
|
|
||||||
var loginEmail: String?
|
|
||||||
get() { mLoginEmail = mLoginEmail ?: loginStore.getLoginData("email", null); return mLoginEmail }
|
|
||||||
set(value) { loginStore.putLoginData("email", value); mLoginEmail = 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 mStudentId: String? = null
|
|
||||||
var studentId: String?
|
|
||||||
get() { mStudentId = mStudentId ?: profile?.getStudentData("studentId", null); return mStudentId }
|
|
||||||
set(value) { profile?.putStudentData("studentId", value) ?: return; mStudentId = value }
|
|
||||||
|
|
||||||
private var mSchoolId: String? = null
|
|
||||||
var schoolId: String?
|
|
||||||
get() { mSchoolId = mSchoolId ?: profile?.getStudentData("schoolId", null); return mSchoolId }
|
|
||||||
set(value) { profile?.putStudentData("schoolId", value) ?: return; mSchoolId = value }
|
|
||||||
|
|
||||||
private var mClassId: String? = null
|
|
||||||
var classId: String?
|
|
||||||
get() { mClassId = mClassId ?: profile?.getStudentData("classId", null); return mClassId }
|
|
||||||
set(value) { profile?.putStudentData("classId", value) ?: return; mClassId = value }
|
|
||||||
|
|
||||||
/* __ __ _
|
|
||||||
\ \ / / | |
|
|
||||||
\ \ /\ / /__| |__
|
|
||||||
\ \/ \/ / _ \ '_ \
|
|
||||||
\ /\ / __/ |_) |
|
|
||||||
\/ \/ \___|_._*/
|
|
||||||
private var mWebSessionId: String? = null
|
|
||||||
var webSessionId: String?
|
|
||||||
get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("webSessionId", null); return mWebSessionId }
|
|
||||||
set(value) { loginStore.putLoginData("webSessionId", value); mWebSessionId = value }
|
|
||||||
|
|
||||||
private var mWebSessionIdExpiryTime: Long? = null
|
|
||||||
var webSessionIdExpiryTime: Long
|
|
||||||
get() { mWebSessionIdExpiryTime = mWebSessionIdExpiryTime ?: loginStore.getLoginData("webSessionIdExpiryTime", 0L); return mWebSessionIdExpiryTime ?: 0L }
|
|
||||||
set(value) { loginStore.putLoginData("webSessionIdExpiryTime", value); mWebSessionIdExpiryTime = value }
|
|
||||||
|
|
||||||
/* ____ _ _
|
|
||||||
/ __ \| | | |
|
|
||||||
| | | | |_| |__ ___ _ __
|
|
||||||
| | | | __| '_ \ / _ \ '__|
|
|
||||||
| |__| | |_| | | | __/ |
|
|
||||||
\____/ \__|_| |_|\___|*/
|
|
||||||
private var mCurrentSemester: Int? = null
|
|
||||||
var currentSemester: Int
|
|
||||||
get() { mCurrentSemester = mCurrentSemester ?: profile?.getStudentData("currentSemester", 1); return mCurrentSemester ?: 1 }
|
|
||||||
set(value) { profile?.putStudentData("currentSemester", value) ?: return; mCurrentSemester = value }
|
|
||||||
|
|
||||||
private var mSchoolName: String? = null
|
|
||||||
var schoolName: String?
|
|
||||||
get() { mSchoolName = mSchoolName ?: profile?.getStudentData("schoolName", null); return mSchoolName }
|
|
||||||
set(value) { profile?.putStudentData("schoolName", value) ?: return; mSchoolName = value }
|
|
||||||
|
|
||||||
val studentEndpoint: String
|
|
||||||
get() = "Students/$studentId/"
|
|
||||||
|
|
||||||
val schoolEndpoint: String
|
|
||||||
get() = "Schools/$schoolId/"
|
|
||||||
|
|
||||||
val classStudentEndpoint: String
|
|
||||||
get() = "Class/$studentId/"
|
|
||||||
|
|
||||||
val schoolClassEndpoint: String
|
|
||||||
get() = "Schools/$classId/"
|
|
||||||
|
|
||||||
val studentAndClassEndpoint: String
|
|
||||||
get() = "Students/$studentId/Klass/$classId/"
|
|
||||||
|
|
||||||
val studentAndClassesEndpoint: String
|
|
||||||
get() = "Students/$studentId/Classes/$classId/"
|
|
||||||
|
|
||||||
val timetableEndpoint: String
|
|
||||||
get() = "Plan/$studentId/"
|
|
||||||
|
|
||||||
val studentAndTeacherClassEndpoint: String
|
|
||||||
get() = "Students/$studentId/Teachers/$classId/"
|
|
||||||
|
|
||||||
val courseStudentEndpoint: String
|
|
||||||
get() = "Course/$studentId/"
|
|
||||||
|
|
||||||
fun getEventType(longId: String, name: String): EventType {
|
|
||||||
val id = longId.crc16().toLong()
|
|
||||||
return eventTypes.singleOrNull { it.id == id } ?: run {
|
|
||||||
val eventType = EventType(profileId, id, name, colorFromName(name))
|
|
||||||
eventTypes.put(id, eventType)
|
|
||||||
eventType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,142 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|
||||||
|
|
||||||
import com.google.gson.JsonObject
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetAnnouncement
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.EdudziennikWebGetHomework
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLogin
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
|
||||||
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.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.d
|
|
||||||
|
|
||||||
class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStore, val callback: EdziennikCallback) : EdziennikInterface {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "Edudziennik"
|
|
||||||
}
|
|
||||||
|
|
||||||
val internalErrorList = mutableListOf<Int>()
|
|
||||||
val data: DataEdudziennik
|
|
||||||
private var afterLogin: (() -> Unit)? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
data = DataEdudziennik(app, profile, loginStore).apply {
|
|
||||||
callback = wrapCallback(this@Edudziennik.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(edudziennikLoginMethods, EdudziennikFeatures, featureIds, viewId, onlyEndpoints)
|
|
||||||
login()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun login(loginMethodId: Int? = null, afterLogin: (() -> Unit)? = null) {
|
|
||||||
d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
|
|
||||||
if (internalErrorList.isNotEmpty()) {
|
|
||||||
d(TAG, " - Internal errors:")
|
|
||||||
internalErrorList.forEach { d(TAG, " - code $it") }
|
|
||||||
}
|
|
||||||
loginMethodId?.let { data.prepareFor(edudziennikLoginMethods, it) }
|
|
||||||
afterLogin?.let { this.afterLogin = it }
|
|
||||||
EdudziennikLogin(data) {
|
|
||||||
data()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun data() {
|
|
||||||
d(TAG, "Endpoint IDs: ${data.targetEndpointIds}")
|
|
||||||
if (internalErrorList.isNotEmpty()) {
|
|
||||||
d(TAG, " - Internal errors:")
|
|
||||||
internalErrorList.forEach { d(TAG, " - code $it") }
|
|
||||||
}
|
|
||||||
afterLogin?.invoke() ?: EdudziennikData(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) {
|
|
||||||
EdudziennikLoginWeb(data) {
|
|
||||||
EdudziennikWebGetAnnouncement(data, announcement) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getAttachment(owner: Any, attachmentId: Long, attachmentName: String) {}
|
|
||||||
override fun getRecipientList() {}
|
|
||||||
|
|
||||||
override fun getEvent(eventFull: EventFull) {
|
|
||||||
EdudziennikLoginWeb(data) {
|
|
||||||
EdudziennikWebGetHomework(data, eventFull) {
|
|
||||||
completed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun firstLogin() { EdudziennikFirstLogin(data) { completed() } }
|
|
||||||
override fun cancel() {
|
|
||||||
d(TAG, "Cancelled")
|
|
||||||
data.cancel()
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
if (apiError.errorCode in internalErrorList) {
|
|
||||||
// finish immediately if the same error occurs twice during the same sync
|
|
||||||
callback.onError(apiError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
internalErrorList.add(apiError.errorCode)
|
|
||||||
when (apiError.errorCode) {
|
|
||||||
ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED -> {
|
|
||||||
login()
|
|
||||||
}
|
|
||||||
ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID -> {
|
|
||||||
login()
|
|
||||||
}
|
|
||||||
ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS -> {
|
|
||||||
data()
|
|
||||||
}
|
|
||||||
else -> callback.onError(apiError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-23
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Feature
|
|
||||||
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_START = 1000
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_TEACHERS = 1001
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_GRADES = 1011
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE = 1012
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_EXAMS = 1013
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE = 1014
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS = 1015
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK = 1016
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_EVENTS = 1017
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_NOTES = 1018
|
|
||||||
const val ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER = 1030
|
|
||||||
|
|
||||||
val EdudziennikFeatures = listOf(
|
|
||||||
/* School and team info and subjects */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_STUDENT_INFO, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_START to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Teachers */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TEACHERS, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Timetable */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_TIMETABLE, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Grades */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_GRADES, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_GRADES to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Agenda */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_AGENDA, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EXAMS to LOGIN_METHOD_EDUDZIENNIK_WEB,
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB,
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EVENTS to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Homework */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_HOMEWORK, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Behaviour */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_BEHAVIOUR, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_NOTES to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Attendance */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ATTENDANCE, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Announcements */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_ANNOUNCEMENTS, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
|
||||||
|
|
||||||
/* Lucky number */
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER to LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB))
|
|
||||||
)
|
|
@ -1,88 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.*
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web.*
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
|
|
||||||
class EdudziennikData(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikData"
|
|
||||||
}
|
|
||||||
|
|
||||||
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) { endpointId ->
|
|
||||||
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) {
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_START -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_data)
|
|
||||||
EdudziennikWebStart(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TEACHERS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_teachers)
|
|
||||||
EdudziennikWebTeachers(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_GRADES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_grades)
|
|
||||||
EdudziennikWebGrades(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_timetable)
|
|
||||||
EdudziennikWebTimetable(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EXAMS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_exams)
|
|
||||||
EdudziennikWebExams(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_attendance)
|
|
||||||
EdudziennikWebAttendance(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_announcements)
|
|
||||||
EdudziennikWebAnnouncements(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_homework)
|
|
||||||
EdudziennikWebHomework(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_EVENTS -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_events)
|
|
||||||
EdudziennikWebEvents(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_NOTES -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_notices)
|
|
||||||
EdudziennikWebNotes(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_endpoint_lucky_number)
|
|
||||||
EdudziennikWebLuckyNumber(data, lastSync, onSuccess)
|
|
||||||
}
|
|
||||||
else -> onSuccess(endpointId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.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.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
open class EdudziennikWeb(open val data: DataEdudziennik, open val lastSync: Long?) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWeb"
|
|
||||||
}
|
|
||||||
|
|
||||||
val profileId
|
|
||||||
get() = data.profile?.id ?: -1
|
|
||||||
|
|
||||||
val profile
|
|
||||||
get() = data.profile
|
|
||||||
|
|
||||||
fun webGet(tag: String, endpoint: String, xhr: Boolean = false, semester: Int? = null, onSuccess: (text: String) -> Unit) {
|
|
||||||
val url = "https://dziennikel.appspot.com/" + when (endpoint.endsWith('/') || endpoint.contains('?') || endpoint.isEmpty()) {
|
|
||||||
true -> endpoint
|
|
||||||
else -> "$endpoint/"
|
|
||||||
} + (semester?.let { "?semester=" + if(it == -1) "all" else it } ?: "")
|
|
||||||
|
|
||||||
d(tag, "Request: Edudziennik/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))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (semester == null && url.contains("start")) {
|
|
||||||
profile?.also { profile ->
|
|
||||||
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
|
||||||
val semesterCookie = cookies["semester"]?.toIntOrNull()
|
|
||||||
|
|
||||||
semesterCookie?.let { data.currentSemester = it }
|
|
||||||
|
|
||||||
if (semesterCookie == 2 && profile.dateSemester2Start > Date.getToday())
|
|
||||||
profile.dateSemester2Start = Date.getToday().stepForward(0, 0, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
onSuccess(text)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
data.error(ApiError(tag, EXCEPTION_EDUDZIENNIK_WEB_REQUEST)
|
|
||||||
.withThrowable(e)
|
|
||||||
.withResponse(response)
|
|
||||||
.withApiResponse(text))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
val error = when (response?.code()) {
|
|
||||||
402 -> ERROR_EDUDZIENNIK_WEB_LIMITED_ACCESS
|
|
||||||
403 -> ERROR_EDUDZIENNIK_WEB_SESSION_EXPIRED
|
|
||||||
else -> ERROR_REQUEST_FAILURE
|
|
||||||
}
|
|
||||||
data.error(ApiError(tag, error)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.app.cookieJar.set("dziennikel.appspot.com", "sessionid", data.webSessionId)
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url(url)
|
|
||||||
.userAgent(EDUDZIENNIK_USER_AGENT)
|
|
||||||
.apply {
|
|
||||||
if (xhr) header("X-Requested-With", "XMLHttpRequest")
|
|
||||||
}
|
|
||||||
.get()
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ANNOUNCEMENT_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Announcement
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebAnnouncements(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebAnnouncements"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.schoolClassEndpoint + "Announcements") { text ->
|
|
||||||
val doc = Jsoup.parse(text)
|
|
||||||
|
|
||||||
if (doc.getElementsByClass("message").text().trim() != "Brak ogłoszeń.") {
|
|
||||||
doc.select("table.list tbody tr").forEach { announcementElement ->
|
|
||||||
val titleElement = announcementElement.child(0).child(0)
|
|
||||||
|
|
||||||
val longId = EDUDZIENNIK_ANNOUNCEMENT_ID.find(titleElement.attr("href"))?.get(1)
|
|
||||||
?: return@forEach
|
|
||||||
val id = longId.crc32()
|
|
||||||
val subject = titleElement.text()
|
|
||||||
|
|
||||||
val teacherName = announcementElement.child(1).text()
|
|
||||||
val teacher = data.getTeacherByFirstLast(teacherName)
|
|
||||||
|
|
||||||
val dateString = announcementElement.getElementsByClass("datetime").first()?.text()
|
|
||||||
val startDate = Date.fromY_m_d(dateString)
|
|
||||||
val addedDate = Date.fromIsoHm(dateString)
|
|
||||||
|
|
||||||
val announcementObject = Announcement(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
subject = subject,
|
|
||||||
text = null,
|
|
||||||
startDate = startDate,
|
|
||||||
endDate = null,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
).also {
|
|
||||||
it.idString = longId
|
|
||||||
}
|
|
||||||
|
|
||||||
data.announcementList.add(announcementObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_ANNOUNCEMENT,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ANNOUNCEMENTS) }
|
|
||||||
}
|
|
@ -1,114 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-24
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_ENTRIES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ATTENDANCE_TYPES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.ext.singleOrNull
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class EdudziennikWebAttendance(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebAttendance"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var requestSemester: Int? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
|
|
||||||
getAttendances()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAttendances() { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.studentEndpoint + "Presence", semester = requestSemester) { text ->
|
|
||||||
|
|
||||||
val attendanceTypes = EDUDZIENNIK_ATTENDANCE_TYPES.find(text)?.get(1)?.split(',')?.map {
|
|
||||||
val type = EDUDZIENNIK_ATTENDANCE_TYPE.find(it.trim())
|
|
||||||
val symbol = type?.get(1)?.trim() ?: "?"
|
|
||||||
val name = type?.get(2)?.trim() ?: "nieznany rodzaj"
|
|
||||||
return@map Triple(
|
|
||||||
symbol,
|
|
||||||
name,
|
|
||||||
when (name.lowercase()) {
|
|
||||||
"obecność" -> Attendance.TYPE_PRESENT
|
|
||||||
"nieobecność" -> Attendance.TYPE_ABSENT
|
|
||||||
"spóźnienie" -> Attendance.TYPE_BELATED
|
|
||||||
"nieobecność usprawiedliwiona" -> Attendance.TYPE_ABSENT_EXCUSED
|
|
||||||
"dzień wolny" -> Attendance.TYPE_DAY_FREE
|
|
||||||
"brak zajęć" -> Attendance.TYPE_DAY_FREE
|
|
||||||
"oddelegowany" -> Attendance.TYPE_RELEASED
|
|
||||||
else -> Attendance.TYPE_UNKNOWN
|
|
||||||
}
|
|
||||||
)
|
|
||||||
} ?: emptyList()
|
|
||||||
|
|
||||||
EDUDZIENNIK_ATTENDANCE_ENTRIES.findAll(text).forEach { attendanceElement ->
|
|
||||||
val date = Date.fromY_m_d(attendanceElement[1])
|
|
||||||
val lessonNumber = attendanceElement[2].toInt()
|
|
||||||
val attendanceSymbol = attendanceElement[3]
|
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
|
||||||
val lesson = lessons.firstOrNull { it.lessonNumber == lessonNumber }
|
|
||||||
|
|
||||||
val id = "${date.stringY_m_d}:$lessonNumber:$attendanceSymbol".crc32()
|
|
||||||
|
|
||||||
val (typeSymbol, typeName, baseType) = attendanceTypes.firstOrNull { (symbol, _, _) -> symbol == attendanceSymbol }
|
|
||||||
?: return@forEach
|
|
||||||
|
|
||||||
val startTime = data.lessonRanges.singleOrNull { it.lessonNumber == lessonNumber }?.startTime
|
|
||||||
?: return@forEach
|
|
||||||
|
|
||||||
val attendanceObject = Attendance(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
baseType = baseType,
|
|
||||||
typeName = typeName,
|
|
||||||
typeShort = data.app.attendanceManager.getTypeShort(baseType),
|
|
||||||
typeSymbol = typeSymbol,
|
|
||||||
typeColor = null,
|
|
||||||
date = date,
|
|
||||||
startTime = lesson?.displayStartTime ?: startTime,
|
|
||||||
semester = profile.currentSemester,
|
|
||||||
teacherId = lesson?.displayTeacherId ?: -1,
|
|
||||||
subjectId = lesson?.displaySubjectId ?: -1
|
|
||||||
).also {
|
|
||||||
it.lessonNumber = lessonNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
data.attendanceList.add(attendanceObject)
|
|
||||||
if (baseType != Attendance.TYPE_PRESENT) {
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_ATTENDANCE,
|
|
||||||
id,
|
|
||||||
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN,
|
|
||||||
profile.empty || baseType == Attendance.TYPE_PRESENT_CUSTOM || baseType == Attendance.TYPE_UNKNOWN
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
|
||||||
requestSemester = null
|
|
||||||
getAttendances()
|
|
||||||
} else {
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_ATTENDANCE) }
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EVENTS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebEvents(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebEvents"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.studentAndClassesEndpoint + "KlassEvent", xhr = true) { text ->
|
|
||||||
val doc = Jsoup.parseBodyFragment("<table>" + text.trim() + "</table>")
|
|
||||||
|
|
||||||
doc.getElementsByTag("tr").forEach { eventElement ->
|
|
||||||
val date = Date.fromY_m_d(eventElement.child(1).text())
|
|
||||||
|
|
||||||
val titleElement = eventElement.child(2).child(0)
|
|
||||||
val title = titleElement.text().trim()
|
|
||||||
|
|
||||||
val id = EDUDZIENNIK_EVENT_ID.find(titleElement.attr("href"))?.get(1)?.crc32()
|
|
||||||
?: return@forEach
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = date,
|
|
||||||
time = null,
|
|
||||||
topic = title,
|
|
||||||
color = null,
|
|
||||||
type = Event.TYPE_CLASS_EVENT,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = -1,
|
|
||||||
teamId = data.teamClass?.id ?: -1
|
|
||||||
)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_EVENT,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_CLASS_EVENT))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EVENTS, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EVENTS) }
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-24
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EVENT_TYPE_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_EXAM_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_EXAMS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebExams(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebExams"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { profile?.also { profile ->
|
|
||||||
webGet(TAG, data.studentAndClassEndpoint + "Evaluations", xhr = true) { text ->
|
|
||||||
val doc = Jsoup.parseBodyFragment("<table>" + text.trim() + "</table>")
|
|
||||||
|
|
||||||
doc.select("tr").forEach { examElement ->
|
|
||||||
val id = EDUDZIENNIK_EXAM_ID.find(examElement.child(0).child(0).attr("href"))
|
|
||||||
?.get(1)?.crc32() ?: return@forEach
|
|
||||||
val topic = examElement.child(0).text().trim()
|
|
||||||
|
|
||||||
val subjectElement = examElement.child(1).child(0)
|
|
||||||
val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
|
|
||||||
?: return@forEach
|
|
||||||
val subjectName = subjectElement.text().trim()
|
|
||||||
val subject = data.getSubject(subjectId.crc32(), subjectName)
|
|
||||||
|
|
||||||
val dateString = examElement.child(2).text().trim()
|
|
||||||
if (dateString.isBlank()) return@forEach
|
|
||||||
val date = Date.fromY_m_d(dateString)
|
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
|
||||||
val startTime = lessons.firstOrNull { it.displaySubjectId == subject.id }?.displayStartTime
|
|
||||||
|
|
||||||
val eventTypeElement = examElement.child(3).child(0)
|
|
||||||
val eventTypeId = EDUDZIENNIK_EVENT_TYPE_ID.find(eventTypeElement.attr("href"))?.get(1)
|
|
||||||
?: return@forEach
|
|
||||||
val eventTypeName = eventTypeElement.text()
|
|
||||||
val eventType = data.getEventType(eventTypeId, eventTypeName)
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = date,
|
|
||||||
time = startTime,
|
|
||||||
topic = topic,
|
|
||||||
color = null,
|
|
||||||
type = eventType.id,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subject.id,
|
|
||||||
teamId = data.teamClass?.id ?: -1
|
|
||||||
)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_EVENT,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureExceptTypes(listOf(
|
|
||||||
Event.TYPE_HOMEWORK,
|
|
||||||
Event.TYPE_CLASS_EVENT
|
|
||||||
)))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_EXAMS, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_EXAMS)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-26
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.AnnouncementGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.AnnouncementFull
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
|
|
||||||
class EdudziennikWebGetAnnouncement(override val data: DataEdudziennik,
|
|
||||||
private val announcement: AnnouncementFull,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : EdudziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebGetAnnouncement"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webGet(TAG, "Announcement/${announcement.idString}") { text ->
|
|
||||||
val description = Regexes.EDUDZIENNIK_ANNOUNCEMENT_DESCRIPTION.find(text)?.get(1)?.trim() ?: ""
|
|
||||||
|
|
||||||
announcement.text = description
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(AnnouncementGetEvent(announcement))
|
|
||||||
|
|
||||||
data.announcementList.add(announcement)
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.EventGetEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
|
||||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
|
||||||
|
|
||||||
class EdudziennikWebGetHomework(
|
|
||||||
override val data: DataEdudziennik,
|
|
||||||
val event: EventFull,
|
|
||||||
val onSuccess: () -> Unit
|
|
||||||
) : EdudziennikWeb(data, null) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebGetHomework"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (event.attachmentNames.isNotNullNorEmpty()) {
|
|
||||||
val id = event.attachmentNames!![0]
|
|
||||||
|
|
||||||
webGet(TAG, "Homework/$id") { text ->
|
|
||||||
val description = Regexes.EDUDZIENNIK_HOMEWORK_DESCRIPTION.find(text)?.get(1)?.trim()
|
|
||||||
|
|
||||||
if (description != null)
|
|
||||||
event.topic = BetterHtml.fromHtml(context = null, description).toString()
|
|
||||||
|
|
||||||
event.homeworkBody = ""
|
|
||||||
event.isDownloaded = true
|
|
||||||
event.attachmentNames = null
|
|
||||||
|
|
||||||
data.eventList += event
|
|
||||||
data.eventListReplace = true
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(EventGetEvent(event))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
EventBus.getDefault().postSticky(EventGetEvent(event))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,230 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_GRADES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_NORMAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_POINT_SUM
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_FINAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER1_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_FINAL
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade.Companion.TYPE_SEMESTER2_PROPOSED
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.colorFromCssName
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebGrades(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebGrades"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var requestSemester: Int? = null
|
|
||||||
|
|
||||||
init {
|
|
||||||
if (profile?.empty == true && data.currentSemester == 2) requestSemester = 1
|
|
||||||
getGrades()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getGrades() { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.studentEndpoint + "start", semester = requestSemester) { text ->
|
|
||||||
val semester = requestSemester ?: data.currentSemester
|
|
||||||
|
|
||||||
val doc = Jsoup.parse(text)
|
|
||||||
val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
|
|
||||||
|
|
||||||
subjects?.forEach { subjectElement ->
|
|
||||||
if (subjectElement.id().isBlank()) return@forEach
|
|
||||||
|
|
||||||
val subjectId = subjectElement.id().trim()
|
|
||||||
val subjectName = subjectElement.child(0).text().trim()
|
|
||||||
val subject = data.getSubject(subjectId.crc32(), subjectName)
|
|
||||||
|
|
||||||
val gradeType = when {
|
|
||||||
subjectElement.select("#sum").text().isNotBlank() -> TYPE_POINT_SUM
|
|
||||||
else -> TYPE_NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
val gradeCountToAverage = subjectElement.select("#avg").text().isNotBlank()
|
|
||||||
|
|
||||||
val grades = subjectElement.select(".grade[data-edited]")
|
|
||||||
val gradesInfo = subjectElement.select(".grade-tip")
|
|
||||||
|
|
||||||
val gradeValues = if (grades.isNotEmpty()) {
|
|
||||||
subjects.select(".avg-$subjectId .grade-tip > p").first()
|
|
||||||
?.text()?.split('+')?.map {
|
|
||||||
val split = it.split('*')
|
|
||||||
val value = split[1].trim().toFloatOrNull()
|
|
||||||
val weight = value?.let { split[0].trim().toFloatOrNull() } ?: 0f
|
|
||||||
|
|
||||||
Pair(value ?: 0f, weight)
|
|
||||||
} ?: emptyList()
|
|
||||||
} else emptyList()
|
|
||||||
|
|
||||||
grades.forEachIndexed { index, gradeElement ->
|
|
||||||
val id = Regexes.EDUDZIENNIK_GRADE_ID.find(gradeElement.attr("href"))?.get(1)?.crc32()
|
|
||||||
?: return@forEachIndexed
|
|
||||||
val (value, weight) = gradeValues[index]
|
|
||||||
val name = gradeElement.text().trim().let {
|
|
||||||
if (it.contains(',') || it.contains('.')) {
|
|
||||||
val replaced = it.replace(',', '.')
|
|
||||||
val float = replaced.toFloatOrNull()
|
|
||||||
|
|
||||||
if (float != null && float % 1 == 0f) float.toInt().toString()
|
|
||||||
else it
|
|
||||||
} else it
|
|
||||||
}
|
|
||||||
|
|
||||||
val info = gradesInfo[index]
|
|
||||||
val fullName = info.child(0).text().trim()
|
|
||||||
val columnName = info.child(4).text().trim()
|
|
||||||
val comment = info.ownText()
|
|
||||||
|
|
||||||
val description = columnName + if (comment.isNotBlank()) " - $comment" else null
|
|
||||||
|
|
||||||
val teacherName = info.child(1).text()
|
|
||||||
val teacher = data.getTeacherByLastFirst(teacherName)
|
|
||||||
|
|
||||||
val addedDate = info.child(2).text().split(' ').let {
|
|
||||||
val day = it[0].toInt()
|
|
||||||
val month = Utils.monthFromName(it[1])
|
|
||||||
val year = it[2].toInt()
|
|
||||||
|
|
||||||
Date(year, month, day).inMillis
|
|
||||||
}
|
|
||||||
|
|
||||||
val color = Regexes.STYLE_CSS_COLOR.find(gradeElement.attr("style"))?.get(1)?.let {
|
|
||||||
if (it.startsWith('#')) Color.parseColor(it)
|
|
||||||
else colorFromCssName(it)
|
|
||||||
} ?: -1
|
|
||||||
|
|
||||||
val gradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
name = name,
|
|
||||||
type = gradeType,
|
|
||||||
value = value,
|
|
||||||
weight = if (gradeCountToAverage) weight else 0f,
|
|
||||||
color = color,
|
|
||||||
category = fullName,
|
|
||||||
description = description,
|
|
||||||
comment = null,
|
|
||||||
semester = semester,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
subjectId = subject.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(gradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
val proposed = subjectElement.select(".proposal").firstOrNull()?.text()?.trim()
|
|
||||||
|
|
||||||
if (proposed != null && proposed.isNotBlank()) {
|
|
||||||
val proposedGradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = (-1 * subject.id) - 1,
|
|
||||||
name = proposed,
|
|
||||||
type = when (semester) {
|
|
||||||
1 -> TYPE_SEMESTER1_PROPOSED
|
|
||||||
else -> TYPE_SEMESTER2_PROPOSED
|
|
||||||
},
|
|
||||||
value = proposed.toFloatOrNull() ?: 0f,
|
|
||||||
weight = 0f,
|
|
||||||
color = -1,
|
|
||||||
category = null,
|
|
||||||
description = null,
|
|
||||||
comment = null,
|
|
||||||
semester = semester,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subject.id
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(proposedGradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
proposedGradeObject.id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
val final = subjectElement.select(".final").firstOrNull()?.text()?.trim()
|
|
||||||
|
|
||||||
if (final != null && final.isNotBlank()) {
|
|
||||||
val finalGradeObject = Grade(
|
|
||||||
profileId = profileId,
|
|
||||||
id = (-1 * subject.id) - 2,
|
|
||||||
name = final,
|
|
||||||
type = when (semester) {
|
|
||||||
1 -> TYPE_SEMESTER1_FINAL
|
|
||||||
else -> TYPE_SEMESTER2_FINAL
|
|
||||||
},
|
|
||||||
value = final.toFloatOrNull() ?: 0f,
|
|
||||||
weight = 0f,
|
|
||||||
color = -1,
|
|
||||||
category = null,
|
|
||||||
description = null,
|
|
||||||
comment = null,
|
|
||||||
semester = semester,
|
|
||||||
teacherId = -1,
|
|
||||||
subjectId = subject.id
|
|
||||||
)
|
|
||||||
|
|
||||||
data.gradeList.add(finalGradeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
data.profileId,
|
|
||||||
Metadata.TYPE_GRADE,
|
|
||||||
finalGradeObject.id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!subjects.isNullOrEmpty()) {
|
|
||||||
data.toRemove.addAll(listOf(
|
|
||||||
TYPE_NORMAL,
|
|
||||||
TYPE_POINT_SUM,
|
|
||||||
TYPE_SEMESTER1_PROPOSED,
|
|
||||||
TYPE_SEMESTER2_PROPOSED,
|
|
||||||
TYPE_SEMESTER1_FINAL,
|
|
||||||
TYPE_SEMESTER2_FINAL
|
|
||||||
).map {
|
|
||||||
DataRemoveModel.Grades.semesterWithType(semester, it)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (profile.empty && requestSemester == 1 && data.currentSemester == 2) {
|
|
||||||
requestSemester = null
|
|
||||||
getGrades()
|
|
||||||
} else {
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_GRADES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_GRADES) }
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_HOMEWORK_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebHomework(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebHomework"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.courseStudentEndpoint + "Homework", xhr = true) { text ->
|
|
||||||
val doc = Jsoup.parseBodyFragment("<table>" + text.trim() + "</table>")
|
|
||||||
|
|
||||||
if (doc.getElementsByClass("message").text().trim() != "Brak prac domowych") {
|
|
||||||
doc.getElementsByTag("tr").forEach { homeworkElement ->
|
|
||||||
val dateElement = homeworkElement.getElementsByClass("date").first()?.child(0) ?: return@forEach
|
|
||||||
val idStr = EDUDZIENNIK_HOMEWORK_ID.find(dateElement.attr("href"))?.get(1) ?: return@forEach
|
|
||||||
val id = idStr.crc32()
|
|
||||||
val date = Date.fromY_m_d(dateElement.text())
|
|
||||||
|
|
||||||
val subjectElement = homeworkElement.child(1).child(0)
|
|
||||||
val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
|
|
||||||
?: return@forEach
|
|
||||||
val subjectName = subjectElement.text()
|
|
||||||
val subject = data.getSubject(subjectId.crc32(), subjectName)
|
|
||||||
|
|
||||||
val lessons = data.app.db.timetableDao().getAllForDateNow(profileId, date)
|
|
||||||
val startTime = lessons.firstOrNull { it.subjectId == subject.id }?.displayStartTime
|
|
||||||
|
|
||||||
val teacherName = homeworkElement.child(2).text()
|
|
||||||
val teacher = data.getTeacherByFirstLast(teacherName)
|
|
||||||
|
|
||||||
val topic = homeworkElement.child(4).text().trim()
|
|
||||||
|
|
||||||
val eventObject = Event(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
date = date,
|
|
||||||
time = startTime,
|
|
||||||
topic = topic ?: "",
|
|
||||||
color = null,
|
|
||||||
type = Event.TYPE_HOMEWORK,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
subjectId = subject.id,
|
|
||||||
teamId = data.teamClass?.id ?: -1
|
|
||||||
)
|
|
||||||
|
|
||||||
eventObject.attachmentNames = mutableListOf(idStr)
|
|
||||||
|
|
||||||
data.eventList.add(eventObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_HOMEWORK,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Events.futureWithType(Event.TYPE_HOMEWORK))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_HOMEWORK) }
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-23
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LuckyNumber
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebLuckyNumber"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
|
|
||||||
text.toIntOrNull()?.also { luckyNumber ->
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
|
||||||
profileId = profileId,
|
|
||||||
date = Date.getToday(),
|
|
||||||
number = luckyNumber
|
|
||||||
)
|
|
||||||
|
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_LUCKY_NUMBER,
|
|
||||||
luckyNumberObject.date.value.toLong(),
|
|
||||||
true,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER) }
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2020-1-1
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_NOTE_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_NOTES
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
|
|
||||||
class EdudziennikWebNotes(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
const val TAG = "EdudziennikWebNotes"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
webGet(TAG, data.classStudentEndpoint + "RegistryNotesStudent", xhr = true) { text ->
|
|
||||||
val doc = Jsoup.parseBodyFragment("<table>" + text.trim() + "</table>")
|
|
||||||
|
|
||||||
doc.getElementsByTag("tr").forEach { noteElement ->
|
|
||||||
val dateElement = noteElement.getElementsByClass("date").first()?.child(0) ?: return@forEach
|
|
||||||
val addedDate = Date.fromY_m_d(dateElement.text()).inMillis
|
|
||||||
|
|
||||||
val id = EDUDZIENNIK_NOTE_ID.find(dateElement.attr("href"))?.get(0)?.crc32()
|
|
||||||
?: return@forEach
|
|
||||||
|
|
||||||
val teacherName = noteElement.child(1).text()
|
|
||||||
val teacher = data.getTeacherByFirstLast(teacherName)
|
|
||||||
|
|
||||||
val description = noteElement.child(3).text()
|
|
||||||
|
|
||||||
val noticeObject = Notice(
|
|
||||||
profileId = profileId,
|
|
||||||
id = id,
|
|
||||||
type = Notice.TYPE_NEUTRAL,
|
|
||||||
semester = profile.currentSemester,
|
|
||||||
text = description,
|
|
||||||
category = null,
|
|
||||||
points = null,
|
|
||||||
teacherId = teacher.id,
|
|
||||||
addedDate = addedDate
|
|
||||||
)
|
|
||||||
|
|
||||||
data.noticeList.add(noticeObject)
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_NOTICE,
|
|
||||||
id,
|
|
||||||
profile.empty,
|
|
||||||
profile.empty
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_NOTES, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_NOTES) }
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-23
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.ERROR_EDUDZIENNIK_WEB_TEAM_MISSING
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECTS_START
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_START
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Team
|
|
||||||
import pl.szczodrzynski.edziennik.ext.MONTH
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.firstLettersName
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
|
|
||||||
class EdudziennikWebStart(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebStart"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webGet(TAG, data.studentEndpoint + "start") { text ->
|
|
||||||
getSchoolAndTeam(text)
|
|
||||||
getSubjects(text)
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, MONTH)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_START)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSchoolAndTeam(text: String) {
|
|
||||||
val schoolId = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)?.trim()
|
|
||||||
val schoolLongName = Regexes.EDUDZIENNIK_SCHOOL_DETAIL_NAME.find(text)?.get(1)?.trim()
|
|
||||||
data.schoolId = schoolId
|
|
||||||
|
|
||||||
val classId = Regexes.EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)?.trim()
|
|
||||||
val className = Regexes.EDUDZIENNIK_CLASS_DETAIL_NAME.find(text)?.get(1)?.trim()
|
|
||||||
data.classId = classId
|
|
||||||
|
|
||||||
if (classId == null || className == null || schoolId == null || schoolLongName == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_EDUDZIENNIK_WEB_TEAM_MISSING)
|
|
||||||
.withApiResponse(text))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val schoolName = schoolId.crc32().toString() + schoolLongName.firstLettersName + "_edu"
|
|
||||||
data.schoolName = schoolName
|
|
||||||
|
|
||||||
val teamId = classId.crc32()
|
|
||||||
val teamCode = "$schoolName:$className"
|
|
||||||
|
|
||||||
val teamObject = Team(
|
|
||||||
data.profileId,
|
|
||||||
teamId,
|
|
||||||
className,
|
|
||||||
Team.TYPE_CLASS,
|
|
||||||
teamCode,
|
|
||||||
-1
|
|
||||||
)
|
|
||||||
|
|
||||||
data.teamClass = teamObject
|
|
||||||
data.teamList.put(teamObject.id, teamObject)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getSubjects(text: String) {
|
|
||||||
EDUDZIENNIK_SUBJECTS_START.findAll(text).forEach {
|
|
||||||
val id = it[1].trim()
|
|
||||||
val name = it[2].trim()
|
|
||||||
data.getSubject(id.crc32(), name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-25
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHERS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TEACHERS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.ext.MONTH
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
|
|
||||||
class EdudziennikWebTeachers(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebTeachers"
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
webGet(TAG, data.studentAndTeacherClassEndpoint + "grid") { text ->
|
|
||||||
EDUDZIENNIK_TEACHERS.findAll(text).forEach {
|
|
||||||
val lastName = it[1].trim()
|
|
||||||
val firstName = it[2].trim()
|
|
||||||
data.getTeacher(firstName, lastName)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS, MONTH)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TEACHERS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,150 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-23
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_TEACHER_ID
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.LessonRange
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.SYNC_ALWAYS
|
|
||||||
import pl.szczodrzynski.edziennik.ext.crc32
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.ext.getString
|
|
||||||
import pl.szczodrzynski.edziennik.ext.singleOrNull
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
|
||||||
|
|
||||||
class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|
||||||
override val lastSync: Long?,
|
|
||||||
val onSuccess: (endpointId: Int) -> Unit
|
|
||||||
) : EdudziennikWeb(data, lastSync) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikWebTimetable"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
|
||||||
|
|
||||||
val currentWeekStart = Week.getWeekStart()
|
|
||||||
|
|
||||||
if (Date.getToday().weekDay > 4) {
|
|
||||||
currentWeekStart.stepForward(0, 0, 7)
|
|
||||||
}
|
|
||||||
|
|
||||||
val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
|
|
||||||
|
|
||||||
val weekStart = Date.fromY_m_d(getDate)
|
|
||||||
val weekEnd = weekStart.clone().stepForward(0, 0, 6)
|
|
||||||
|
|
||||||
webGet(TAG, data.timetableEndpoint + "print?date=$getDate") { text ->
|
|
||||||
val doc = Jsoup.parse(text)
|
|
||||||
|
|
||||||
val dataDays = mutableListOf<Int>()
|
|
||||||
val dataStart = weekStart.clone()
|
|
||||||
while (dataStart <= weekEnd) {
|
|
||||||
dataDays += dataStart.value
|
|
||||||
dataStart.stepForward(0, 0, 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
val table = doc.select("#Schedule tbody").first()
|
|
||||||
|
|
||||||
if (table?.text()?.contains("Brak planu lekcji.") == false) {
|
|
||||||
table.children().forEach { row ->
|
|
||||||
val rowElements = row.children()
|
|
||||||
|
|
||||||
val lessonNumber = rowElements[0].text().toInt()
|
|
||||||
|
|
||||||
val times = rowElements[1].text().split('-')
|
|
||||||
val startTime = Time.fromH_m(times[0].trim())
|
|
||||||
val endTime = Time.fromH_m(times[1].trim())
|
|
||||||
|
|
||||||
data.lessonRanges.singleOrNull {
|
|
||||||
it.lessonNumber == lessonNumber && it.startTime == startTime && it.endTime == endTime
|
|
||||||
} ?: run {
|
|
||||||
data.lessonRanges.put(lessonNumber, LessonRange(profileId, lessonNumber, startTime, endTime))
|
|
||||||
}
|
|
||||||
|
|
||||||
rowElements.subList(2, rowElements.size).forEachIndexed { index, lesson ->
|
|
||||||
val course = lesson.select(".course").firstOrNull() ?: return@forEachIndexed
|
|
||||||
val info = course.select("span > span")
|
|
||||||
|
|
||||||
if (info.isEmpty()) return@forEachIndexed
|
|
||||||
|
|
||||||
val type = when (course.hasClass("substitute")) {
|
|
||||||
true -> Lesson.TYPE_CHANGE
|
|
||||||
else -> Lesson.TYPE_NORMAL
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getting subject */
|
|
||||||
|
|
||||||
val subjectElement = info[0].child(0)
|
|
||||||
val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
|
|
||||||
?: return@forEachIndexed
|
|
||||||
val subjectName = subjectElement.text().trim()
|
|
||||||
val subject = data.getSubject(subjectId.crc32(), subjectName)
|
|
||||||
|
|
||||||
/* Getting teacher */
|
|
||||||
|
|
||||||
val teacherId = if (info.size >= 2) {
|
|
||||||
val teacherElement = info[1].child(0)
|
|
||||||
val teacherLongId = EDUDZIENNIK_TEACHER_ID.find(teacherElement.attr("href"))?.get(1)
|
|
||||||
val teacherName = teacherElement.text().trim()
|
|
||||||
data.getTeacherByLastFirst(teacherName, teacherLongId).id
|
|
||||||
} else null
|
|
||||||
|
|
||||||
val lessonObject = Lesson(profileId, -1).also {
|
|
||||||
it.type = type
|
|
||||||
it.date = weekStart.clone().stepForward(0, 0, index)
|
|
||||||
it.lessonNumber = lessonNumber
|
|
||||||
it.startTime = startTime
|
|
||||||
it.endTime = endTime
|
|
||||||
it.subjectId = subject.id
|
|
||||||
it.teacherId = teacherId
|
|
||||||
it.teamId = data.teamClass?.id
|
|
||||||
|
|
||||||
it.id = it.buildId()
|
|
||||||
}
|
|
||||||
|
|
||||||
data.lessonList.add(lessonObject)
|
|
||||||
dataDays.remove(lessonObject.date!!.value)
|
|
||||||
|
|
||||||
if (type != Lesson.TYPE_NORMAL) {
|
|
||||||
val seen = profile.empty || lessonObject.date!! < Date.getToday()
|
|
||||||
|
|
||||||
data.metadataList.add(Metadata(
|
|
||||||
profileId,
|
|
||||||
Metadata.TYPE_LESSON_CHANGE,
|
|
||||||
lessonObject.id,
|
|
||||||
seen,
|
|
||||||
seen
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (day in dataDays) {
|
|
||||||
val lessonDate = Date.fromValue(day)
|
|
||||||
data.lessonList += Lesson(profileId, lessonDate.value.toLong()).apply {
|
|
||||||
type = Lesson.TYPE_NO_LESSONS
|
|
||||||
date = lessonDate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate")
|
|
||||||
|
|
||||||
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
|
|
||||||
onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE)
|
|
||||||
}
|
|
||||||
} ?: onSuccess(ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE) }
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin
|
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_EDUDZIENNIK
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_ACCOUNT_NAME_START
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_STUDENTS_START
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login.EdudziennikLoginWeb
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.FirstLoginFinishedEvent
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
|
||||||
import pl.szczodrzynski.edziennik.ext.fixName
|
|
||||||
import pl.szczodrzynski.edziennik.ext.get
|
|
||||||
import pl.szczodrzynski.edziennik.ext.getShortName
|
|
||||||
import pl.szczodrzynski.edziennik.ext.set
|
|
||||||
|
|
||||||
class EdudziennikFirstLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikFirstLogin"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val web = EdudziennikWeb(data, null)
|
|
||||||
private val profileList = mutableListOf<Profile>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
val loginStoreId = data.loginStore.id
|
|
||||||
val loginStoreType = LOGIN_TYPE_EDUDZIENNIK
|
|
||||||
var firstProfileId = loginStoreId
|
|
||||||
|
|
||||||
EdudziennikLoginWeb(data) {
|
|
||||||
web.webGet(TAG, "") { text ->
|
|
||||||
val accountNameLong = EDUDZIENNIK_ACCOUNT_NAME_START.find(text)?.get(1)?.fixName()
|
|
||||||
|
|
||||||
EDUDZIENNIK_STUDENTS_START.findAll(text).forEach {
|
|
||||||
val studentId = it[1]
|
|
||||||
val studentNameLong = it[2].fixName()
|
|
||||||
|
|
||||||
if (studentId.isBlank() || studentNameLong.isBlank()) return@forEach
|
|
||||||
|
|
||||||
val studentNameShort = studentNameLong.getShortName()
|
|
||||||
val accountName = if (accountNameLong == studentNameLong) null else accountNameLong
|
|
||||||
|
|
||||||
val profile = Profile(
|
|
||||||
firstProfileId++,
|
|
||||||
loginStoreId,
|
|
||||||
loginStoreType,
|
|
||||||
studentNameLong,
|
|
||||||
data.loginEmail,
|
|
||||||
studentNameLong,
|
|
||||||
studentNameShort,
|
|
||||||
accountName
|
|
||||||
).apply {
|
|
||||||
studentData["studentId"] = studentId
|
|
||||||
}
|
|
||||||
profileList.add(profile)
|
|
||||||
}
|
|
||||||
|
|
||||||
EventBus.getDefault().postSticky(FirstLoginFinishedEvent(profileList, data.loginStore))
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.login
|
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.R
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils
|
|
||||||
|
|
||||||
class EdudziennikLogin(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikLogin"
|
|
||||||
}
|
|
||||||
|
|
||||||
private var cancelled = false
|
|
||||||
|
|
||||||
init {
|
|
||||||
nextLoginMethod(onSuccess)
|
|
||||||
}
|
|
||||||
|
|
||||||
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_EDUDZIENNIK_WEB -> {
|
|
||||||
data.startProgress(R.string.edziennik_progress_login_edudziennik_web)
|
|
||||||
EdudziennikLoginWeb(data) { onSuccess(loginMethodId) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Kacper Ziubryniewicz 2019-12-22
|
|
||||||
*/
|
|
||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.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.edudziennik.DataEdudziennik
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
|
||||||
import pl.szczodrzynski.edziennik.ext.getUnixDate
|
|
||||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
|
||||||
|
|
||||||
class EdudziennikLoginWeb(val data: DataEdudziennik, val onSuccess: () -> Unit) {
|
|
||||||
companion object {
|
|
||||||
private const val TAG = "EdudziennikLoginWeb"
|
|
||||||
}
|
|
||||||
|
|
||||||
init { run {
|
|
||||||
if (data.isWebLoginValid()) {
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data.app.cookieJar.clear("dziennikel.appspot.com")
|
|
||||||
if (data.loginEmail.isNotNullNorEmpty() && data.loginPassword.isNotNullNorEmpty()) {
|
|
||||||
loginWithCredentials()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_DATA_MISSING))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
|
|
||||||
private fun loginWithCredentials() {
|
|
||||||
d(TAG, "Request: Edudziennik/Login/Web - https://dziennikel.appspot.com/login/?next=/")
|
|
||||||
|
|
||||||
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 url = response.raw().request().url().toString()
|
|
||||||
|
|
||||||
if (!url.contains("Student")) {
|
|
||||||
when {
|
|
||||||
text.contains("Wprowadzono nieprawidłową nazwę użytkownika lub hasło.") -> ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN
|
|
||||||
else -> ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER
|
|
||||||
}.let { errorCode ->
|
|
||||||
data.error(ApiError(TAG, errorCode)
|
|
||||||
.withApiResponse(text)
|
|
||||||
.withResponse(response))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val cookies = data.app.cookieJar.getAll("dziennikel.appspot.com")
|
|
||||||
val sessionId = cookies["sessionid"]
|
|
||||||
|
|
||||||
if (sessionId == null) {
|
|
||||||
data.error(ApiError(TAG, ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID)
|
|
||||||
.withResponse(response)
|
|
||||||
.withApiResponse(text))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data.webSessionId = sessionId
|
|
||||||
data.webSessionIdExpiryTime = response.getUnixDate() + 45 * 60 /* 45 min */
|
|
||||||
onSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
|
||||||
.withResponse(response)
|
|
||||||
.withThrowable(throwable))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Request.builder()
|
|
||||||
.url("https://dziennikel.appspot.com/login/?next=/")
|
|
||||||
.userAgent(EDUDZIENNIK_USER_AGENT)
|
|
||||||
.contentType("application/x-www-form-urlencoded")
|
|
||||||
.addParameter("email", data.loginEmail)
|
|
||||||
.addParameter("password", data.loginPassword)
|
|
||||||
.addParameter("auth_method", "password")
|
|
||||||
.addParameter("next", "/")
|
|
||||||
.post()
|
|
||||||
.callback(callback)
|
|
||||||
.build()
|
|
||||||
.enqueue()
|
|
||||||
}
|
|
||||||
}
|
|
@ -278,28 +278,6 @@ object LoginInfo {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
Register(
|
|
||||||
loginType = LOGIN_TYPE_EDUDZIENNIK,
|
|
||||||
internalName = "edudziennik",
|
|
||||||
registerName = R.string.login_type_edudziennik,
|
|
||||||
registerLogo = R.drawable.login_logo_edudziennik,
|
|
||||||
loginModes = listOf(
|
|
||||||
Mode(
|
|
||||||
loginMode = LOGIN_MODE_EDUDZIENNIK_WEB,
|
|
||||||
name = R.string.login_mode_edudziennik_web,
|
|
||||||
icon = R.drawable.login_mode_edudziennik_web,
|
|
||||||
hintText = R.string.login_mode_edudziennik_web_hint,
|
|
||||||
guideText = R.string.login_mode_edudziennik_web_guide,
|
|
||||||
credentials = listOf(
|
|
||||||
getEmailCredential("email"),
|
|
||||||
getPasswordCredential("password")
|
|
||||||
),
|
|
||||||
errorCodes = mapOf(
|
|
||||||
ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN to R.string.login_error_incorrect_login_or_password
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
Register(
|
Register(
|
||||||
loginType = LOGIN_TYPE_PODLASIE,
|
loginType = LOGIN_TYPE_PODLASIE,
|
||||||
internalName = "podlasie",
|
internalName = "podlasie",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user