forked from github/szkolny
[API/Edudziennik] Add getting grades and add basic error handling.
This commit is contained in:
parent
844d5b33bc
commit
30ee71f4e3
@ -112,15 +112,13 @@ fun String.swapFirstLastName(): String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.getFirstLastName(): Pair<String, String>? {
|
fun String.splitName(): Pair<String, String>? {
|
||||||
return this.split(" ").let {
|
return this.split(" ").let {
|
||||||
if (it.size >= 2) Pair(it[0], it[1])
|
if (it.size >= 2) Pair(it[0], it[1])
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.getLastFirstName() = this.getFirstLastName()
|
|
||||||
|
|
||||||
fun changeStringCase(s: String): String {
|
fun changeStringCase(s: String): String {
|
||||||
val delimiters = " '-/"
|
val delimiters = " '-/"
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
@ -179,6 +177,20 @@ fun colorFromName(context: Context, name: String?): Int {
|
|||||||
return context.getColorFromRes(color)
|
return context.getColorFromRes(color)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun colorFromCssName(name: String): Int {
|
||||||
|
return when (name) {
|
||||||
|
"red" -> 0xffff0000
|
||||||
|
"green" -> 0xff008000
|
||||||
|
"blue" -> 0xff0000ff
|
||||||
|
"violet" -> 0xffee82ee
|
||||||
|
"brown" -> 0xffa52a2a
|
||||||
|
"orange" -> 0xffffa500
|
||||||
|
"black" -> 0xff000000
|
||||||
|
"white" -> 0xffffffff
|
||||||
|
else -> -1
|
||||||
|
}.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
fun MutableList<Profile>.filterOutArchived(): MutableList<Profile> {
|
fun MutableList<Profile>.filterOutArchived(): MutableList<Profile> {
|
||||||
this.removeAll { it.archived }
|
this.removeAll { it.archived }
|
||||||
return this
|
return this
|
||||||
|
@ -161,6 +161,7 @@ const val ERROR_IDZIENNIK_API_OTHER = 451
|
|||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_INVALID_LOGIN = 501
|
||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_OTHER = 510
|
||||||
const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511
|
const val ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID = 511
|
||||||
|
const val ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC = 520
|
||||||
|
|
||||||
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
const val ERROR_TEMPLATE_WEB_OTHER = 801
|
||||||
|
|
||||||
|
@ -5,6 +5,12 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api
|
package pl.szczodrzynski.edziennik.data.api
|
||||||
|
|
||||||
object Regexes {
|
object Regexes {
|
||||||
|
val STYLE_CSS_COLOR by lazy {
|
||||||
|
"""color: \w+?;?"?""".toRegex()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val MOBIDZIENNIK_GRADES_SUBJECT_NAME by lazy {
|
val MOBIDZIENNIK_GRADES_SUBJECT_NAME by lazy {
|
||||||
"""<div.*?>\n*\s*(.+?)\s*\n*(?:<.*?)??</div>""".toRegex(RegexOption.DOT_MATCHES_ALL)
|
"""<div.*?>\n*\s*(.+?)\s*\n*(?:<.*?)??</div>""".toRegex(RegexOption.DOT_MATCHES_ALL)
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
||||||
|
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.currentTimeUnix
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.Data
|
import pl.szczodrzynski.edziennik.data.api.models.Data
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile
|
||||||
import pl.szczodrzynski.edziennik.isNotNullNorEmpty
|
import pl.szczodrzynski.edziennik.data.db.modules.subjects.Subject
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
* Use http://patorjk.com/software/taag/#p=display&f=Big for the ascii art
|
||||||
@ -61,8 +61,8 @@ class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Dat
|
|||||||
\/ \/ \___|_._*/
|
\/ \/ \___|_._*/
|
||||||
private var mWebSessionId: String? = null
|
private var mWebSessionId: String? = null
|
||||||
var webSessionId: String?
|
var webSessionId: String?
|
||||||
get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("sessionId", null); return mWebSessionId }
|
get() { mWebSessionId = mWebSessionId ?: loginStore.getLoginData("webSessionId", null); return mWebSessionId }
|
||||||
set(value) { loginStore.putLoginData("sessionId", value); mWebSessionId = value }
|
set(value) { loginStore.putLoginData("webSessionId", value); mWebSessionId = value }
|
||||||
|
|
||||||
private var mWebSessionIdExpiryTime: Long? = null
|
private var mWebSessionIdExpiryTime: Long? = null
|
||||||
var webSessionIdExpiryTime: Long
|
var webSessionIdExpiryTime: Long
|
||||||
@ -86,4 +86,23 @@ class DataEdudziennik(app: App, profile: Profile?, loginStore: LoginStore) : Dat
|
|||||||
|
|
||||||
val timetableEndpoint: String
|
val timetableEndpoint: String
|
||||||
get() = "Plan/$studentId/"
|
get() = "Plan/$studentId/"
|
||||||
|
|
||||||
|
fun getSubject(longId: String, name: String): Subject {
|
||||||
|
val id = longId.crc32()
|
||||||
|
return subjectList.singleOrNull { it.id == id } ?: run {
|
||||||
|
val subject = Subject(profileId, id, name, name)
|
||||||
|
subjectList.put(id, subject)
|
||||||
|
subject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTeacher(firstName: String, lastName: String): Teacher {
|
||||||
|
val name = "$firstName $lastName".fixName()
|
||||||
|
val id = name.crc32()
|
||||||
|
return teacherList.singleOrNull { it.id == id } ?: run {
|
||||||
|
val teacher = Teacher(profileId, id, firstName, lastName)
|
||||||
|
teacherList.put(id, teacher)
|
||||||
|
teacher
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik
|
|||||||
|
|
||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID
|
||||||
import pl.szczodrzynski.edziennik.data.api.edudziennikLoginMethods
|
import pl.szczodrzynski.edziennik.data.api.edudziennikLoginMethods
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikData
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.firstlogin.EdudziennikFirstLogin
|
||||||
@ -62,6 +64,28 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun login() {
|
||||||
|
d(TAG, "Trying to login with ${data.targetLoginMethodIds}")
|
||||||
|
if (internalErrorList.isNotEmpty()) {
|
||||||
|
d(TAG, " - Internal errors:")
|
||||||
|
internalErrorList.forEach { d(TAG, " - code $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") }
|
||||||
|
}
|
||||||
|
EdudziennikData(data) {
|
||||||
|
completed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getMessage(message: MessageFull) {
|
override fun getMessage(message: MessageFull) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -100,10 +124,19 @@ class Edudziennik(val app: App, val profile: Profile?, val loginStore: LoginStor
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(apiError: ApiError) {
|
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) {
|
when (apiError.errorCode) {
|
||||||
in internalErrorList -> {
|
ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID -> {
|
||||||
// finish immediately if the same error occurs twice during the same sync
|
login()
|
||||||
callback.onError(apiError)
|
}
|
||||||
|
ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC -> {
|
||||||
|
loginStore.putLoginData("timetableNotPublic", true)
|
||||||
|
data()
|
||||||
}
|
}
|
||||||
else -> callback.onError(apiError)
|
else -> callback.onError(apiError)
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,10 @@ val EdudziennikFeatures = listOf(
|
|||||||
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_EDUDZIENNIK_WEB
|
ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE to LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
||||||
|
|
||||||
|
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_GRADES, listOf(
|
||||||
|
ENDPOINT_EDUDZIENNIK_WEB_START to LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
|
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB)),
|
||||||
|
|
||||||
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
|
Feature(LOGIN_TYPE_EDUDZIENNIK, FEATURE_LUCKY_NUMBER, listOf(
|
||||||
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER to LOGIN_METHOD_EDUDZIENNIK_WEB
|
ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER to LOGIN_METHOD_EDUDZIENNIK_WEB
|
||||||
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB))
|
), listOf(LOGIN_METHOD_EDUDZIENNIK_WEB))
|
||||||
|
@ -37,7 +37,7 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
val callback = object : TextCallbackHandler() {
|
val callback = object : TextCallbackHandler() {
|
||||||
override fun onSuccess(text: String?, response: Response?) {
|
override fun onSuccess(text: String?, response: Response?) {
|
||||||
if (text == null || response == null) {
|
if (text == null || response == null) {
|
||||||
data.error(ApiError(TAG, ERROR_RESPONSE_EMPTY)
|
data.error(ApiError(tag, ERROR_RESPONSE_EMPTY)
|
||||||
.withResponse(response))
|
.withResponse(response))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ open class EdudziennikWeb(open val data: DataEdudziennik) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(response: Response?, throwable: Throwable?) {
|
override fun onFailure(response: Response?, throwable: Throwable?) {
|
||||||
data.error(ApiError(TAG, ERROR_REQUEST_FAILURE)
|
data.error(ApiError(tag, ERROR_REQUEST_FAILURE)
|
||||||
.withResponse(response)
|
.withResponse(response)
|
||||||
.withThrowable(throwable))
|
.withThrowable(throwable))
|
||||||
}
|
}
|
||||||
|
@ -20,23 +20,23 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
init { data.profile?.also { profile ->
|
init { data.profile?.also { profile ->
|
||||||
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
|
webGet(TAG, data.schoolEndpoint + "Lucky", xhr = true) { text ->
|
||||||
val luckyNumber = text.toInt()
|
text.toIntOrNull()?.let { luckyNumber ->
|
||||||
|
val luckyNumberObject = LuckyNumber(
|
||||||
|
profileId,
|
||||||
|
Date.getToday(),
|
||||||
|
luckyNumber
|
||||||
|
)
|
||||||
|
|
||||||
val luckyNumberObject = LuckyNumber(
|
data.luckyNumberList.add(luckyNumberObject)
|
||||||
profileId,
|
data.metadataList.add(Metadata(
|
||||||
Date.getToday(),
|
profileId,
|
||||||
luckyNumber
|
Metadata.TYPE_LUCKY_NUMBER,
|
||||||
)
|
luckyNumberObject.date.value.toLong(),
|
||||||
|
profile.empty,
|
||||||
data.luckyNumberList.add(luckyNumberObject)
|
profile.empty,
|
||||||
data.metadataList.add(Metadata(
|
System.currentTimeMillis()
|
||||||
profileId,
|
))
|
||||||
Metadata.TYPE_LUCKY_NUMBER,
|
}
|
||||||
luckyNumberObject.date.value.toLong(),
|
|
||||||
profile.empty,
|
|
||||||
profile.empty,
|
|
||||||
System.currentTimeMillis()
|
|
||||||
))
|
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess()
|
||||||
|
@ -4,13 +4,24 @@
|
|||||||
|
|
||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
|
import pl.szczodrzynski.edziennik.colorFromCssName
|
||||||
|
import pl.szczodrzynski.edziennik.crc32
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_CLASS_DETAIL_ID
|
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_CLASS_DETAIL_ID
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_GRADE_ID
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SCHOOL_DETAIL_ID
|
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SCHOOL_DETAIL_ID
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.Regexes.STYLE_CSS_COLOR
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.DataEdudziennik
|
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.ENDPOINT_EDUDZIENNIK_WEB_START
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.grades.Grade
|
||||||
|
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
||||||
import pl.szczodrzynski.edziennik.get
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.utils.Utils
|
||||||
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
class EdudziennikWebStart(override val data: DataEdudziennik,
|
class EdudziennikWebStart(override val data: DataEdudziennik,
|
||||||
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
val onSuccess: () -> Unit) : EdudziennikWeb(data) {
|
||||||
@ -18,16 +29,173 @@ class EdudziennikWebStart(override val data: DataEdudziennik,
|
|||||||
private const val TAG = "EdudziennikWebStart"
|
private const val TAG = "EdudziennikWebStart"
|
||||||
}
|
}
|
||||||
|
|
||||||
init { data.profile?.also { profile ->
|
init {
|
||||||
webGet(TAG, data.studentEndpoint + "start") { text ->
|
webGet(TAG, data.studentEndpoint + "start") { text ->
|
||||||
val schoolId = EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)
|
val doc = Jsoup.parse(text)
|
||||||
data.schoolId = schoolId
|
|
||||||
|
|
||||||
val classId = EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)
|
getInfo(text)
|
||||||
data.classId = classId
|
getGrades(doc)
|
||||||
|
|
||||||
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, SYNC_ALWAYS)
|
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, SYNC_ALWAYS)
|
||||||
onSuccess()
|
onSuccess()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInfo(text: String) {
|
||||||
|
val schoolId = EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)
|
||||||
|
data.schoolId = schoolId
|
||||||
|
|
||||||
|
val classId = EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)
|
||||||
|
data.classId = classId
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getGrades(doc: Document) { data.profile?.also { profile ->
|
||||||
|
val subjects = doc.select("#student_grades tbody").firstOrNull()?.children()
|
||||||
|
|
||||||
|
if (subjects.isNullOrEmpty()) return
|
||||||
|
|
||||||
|
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, subjectName)
|
||||||
|
|
||||||
|
val grades = subjectElement.select(".grade")
|
||||||
|
val gradesInfo = subjectElement.select(".grade-tip")
|
||||||
|
|
||||||
|
val gradeValues = subjects.select(".avg-$subjectId .grade-tip > p").first()
|
||||||
|
.text().split('+').map {
|
||||||
|
val split = it.split('*')
|
||||||
|
val weight = split[0].trim().toFloat()
|
||||||
|
val value = split[1].trim().toFloat()
|
||||||
|
|
||||||
|
Pair(value, weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
grades.forEachIndexed { index, gradeElement ->
|
||||||
|
val id = 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 category = info.child(4).text().trim()
|
||||||
|
|
||||||
|
val (teacherLastName, teacherFirstName) = info.child(1).text().split(' ')
|
||||||
|
val teacher = data.getTeacher(teacherFirstName, teacherLastName)
|
||||||
|
|
||||||
|
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 = STYLE_CSS_COLOR.find(gradeElement.attr("style"))?.get(1)?.let {
|
||||||
|
if (it.startsWith('#')) Color.parseColor(it)
|
||||||
|
else colorFromCssName(it)
|
||||||
|
} ?: -1
|
||||||
|
|
||||||
|
val gradeObject = Grade(
|
||||||
|
profileId,
|
||||||
|
id,
|
||||||
|
category,
|
||||||
|
color,
|
||||||
|
"",
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
weight,
|
||||||
|
profile.currentSemester,
|
||||||
|
teacher.id,
|
||||||
|
subject.id
|
||||||
|
)
|
||||||
|
|
||||||
|
data.gradeList.add(gradeObject)
|
||||||
|
data.metadataList.add(Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_GRADE,
|
||||||
|
id,
|
||||||
|
profile.empty,
|
||||||
|
profile.empty,
|
||||||
|
addedDate
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
val proposed = subjectElement.select(".proposal").firstOrNull()?.text()?.trim()
|
||||||
|
|
||||||
|
if (proposed != null && proposed.isNotBlank()) {
|
||||||
|
val proposedGradeObject = Grade(
|
||||||
|
profileId,
|
||||||
|
(-1 * subject.id) - 1,
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
proposed,
|
||||||
|
proposed.toFloatOrNull() ?: 0f,
|
||||||
|
0f,
|
||||||
|
profile.currentSemester,
|
||||||
|
-1,
|
||||||
|
subject.id
|
||||||
|
).apply {
|
||||||
|
type = when (semester) {
|
||||||
|
1 -> Grade.TYPE_SEMESTER1_PROPOSED
|
||||||
|
else -> Grade.TYPE_SEMESTER2_PROPOSED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.gradeList.add(proposedGradeObject)
|
||||||
|
data.metadataList.add(Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_GRADE,
|
||||||
|
proposedGradeObject.id,
|
||||||
|
profile.empty,
|
||||||
|
profile.empty,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
val final = subjectElement.select(".final").firstOrNull()?.text()?.trim()
|
||||||
|
|
||||||
|
if (final != null && final.isNotBlank()) {
|
||||||
|
val finalGradeObject = Grade(
|
||||||
|
profileId,
|
||||||
|
(-1 * subject.id) - 2,
|
||||||
|
"",
|
||||||
|
-1,
|
||||||
|
"",
|
||||||
|
final,
|
||||||
|
final.toFloatOrNull() ?: 0f,
|
||||||
|
0f,
|
||||||
|
profile.currentSemester,
|
||||||
|
-1,
|
||||||
|
subject.id
|
||||||
|
).apply {
|
||||||
|
type = when (semester) {
|
||||||
|
1 -> Grade.TYPE_SEMESTER1_FINAL
|
||||||
|
else -> Grade.TYPE_SEMESTER2_FINAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.gradeList.add(finalGradeObject)
|
||||||
|
data.metadataList.add(Metadata(
|
||||||
|
profileId,
|
||||||
|
Metadata.TYPE_GRADE,
|
||||||
|
finalGradeObject.id,
|
||||||
|
profile.empty,
|
||||||
|
profile.empty,
|
||||||
|
System.currentTimeMillis()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
} ?: onSuccess() }
|
} ?: onSuccess() }
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,19 @@
|
|||||||
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
package pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.data.web
|
||||||
|
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.data.api.ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes.EDUDZIENNIK_SUBJECT_ID
|
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.DataEdudziennik
|
||||||
import pl.szczodrzynski.edziennik.data.api.edziennik.edudziennik.ENDPOINT_EDUDZIENNIK_WEB_TIMETABLE
|
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.edziennik.edudziennik.data.EdudziennikWeb
|
||||||
|
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||||
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
import pl.szczodrzynski.edziennik.data.api.models.DataRemoveModel
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.subjects.Subject
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.teachers.Teacher
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
|
import pl.szczodrzynski.edziennik.get
|
||||||
|
import pl.szczodrzynski.edziennik.getString
|
||||||
|
import pl.szczodrzynski.edziennik.splitName
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||||
@ -51,7 +52,16 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|||||||
dataStart.stepForward(0, 0, 1)
|
dataStart.stepForward(0, 0, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
doc.select("#Schedule tbody").first().children().forEach { row ->
|
val table = doc.select("#Schedule tbody").first()
|
||||||
|
|
||||||
|
if (table.text().trim() == "Brak planu lekcji.") {
|
||||||
|
data.error(ApiError(TAG, ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC)
|
||||||
|
.withApiResponse(text))
|
||||||
|
onSuccess()
|
||||||
|
return@webGet
|
||||||
|
}
|
||||||
|
|
||||||
|
table.children().forEach { row ->
|
||||||
val rowElements = row.children()
|
val rowElements = row.children()
|
||||||
|
|
||||||
val lessonNumber = rowElements[0].text().toInt()
|
val lessonNumber = rowElements[0].text().toInt()
|
||||||
@ -75,30 +85,16 @@ class EdudziennikWebTimetable(override val data: DataEdudziennik,
|
|||||||
|
|
||||||
val subjectElement = info[0].child(0)
|
val subjectElement = info[0].child(0)
|
||||||
val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
|
val subjectId = EDUDZIENNIK_SUBJECT_ID.find(subjectElement.attr("href"))?.get(1)
|
||||||
?.crc32() ?: return@forEachIndexed
|
?: return@forEachIndexed
|
||||||
|
val subjectName = subjectElement.text().trim()
|
||||||
val subject = data.subjectList.singleOrNull { it.id == subjectId } ?: run {
|
val subject = data.getSubject(subjectId, subjectName)
|
||||||
val subjectName = subjectElement.text().trim()
|
|
||||||
val subjectObject = Subject(profileId, subjectId, subjectName, subjectName)
|
|
||||||
|
|
||||||
data.subjectList.put(subjectId, subjectObject)
|
|
||||||
subjectObject
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Getting teacher */
|
/* Getting teacher */
|
||||||
|
|
||||||
val teacherElement = info[1].child(0)
|
val teacherElement = info[1].child(0)
|
||||||
val teacherId = EDUDZIENNIK_TEACHER_ID.find(teacherElement.attr("href"))?.get(1)
|
val teacherName = teacherElement.text().trim()
|
||||||
?.crc32() ?: return@forEachIndexed
|
val teacher = teacherName.splitName()?.let { (teacherLastName, teacherFirstName) ->
|
||||||
|
data.getTeacher(teacherFirstName, teacherLastName)
|
||||||
val teacher = data.teacherList.singleOrNull { it.id == teacherId } ?: run {
|
|
||||||
val teacherName = teacherElement.text().trim()
|
|
||||||
val teacherObject = teacherName.getLastFirstName()?.let { (teacherLastName, teacherFirstName) ->
|
|
||||||
Teacher(profileId, teacherId, teacherFirstName, teacherLastName)
|
|
||||||
}
|
|
||||||
|
|
||||||
data.teacherList.put(teacherId, teacherObject)
|
|
||||||
teacherObject
|
|
||||||
} ?: return@forEachIndexed
|
} ?: return@forEachIndexed
|
||||||
|
|
||||||
val lessonObject = Lesson(profileId, -1).also {
|
val lessonObject = Lesson(profileId, -1).also {
|
||||||
|
@ -49,7 +49,7 @@ class VulcanApiMessagesInbox(override val data: DataVulcan, val onSuccess: () ->
|
|||||||
|
|
||||||
val senderName = message.getString("Nadawca") ?: ""
|
val senderName = message.getString("Nadawca") ?: ""
|
||||||
|
|
||||||
senderName.getLastFirstName()?.let { (senderLastName, senderFirstName) ->
|
senderName.splitName()?.let { (senderLastName, senderFirstName) ->
|
||||||
val teacherObject = Teacher(
|
val teacherObject = Teacher(
|
||||||
profileId,
|
profileId,
|
||||||
-1 * Utils.crc16(senderName.toByteArray()).toLong(),
|
-1 * Utils.crc16(senderName.toByteArray()).toLong(),
|
||||||
|
@ -54,7 +54,7 @@ class VulcanApiMessagesSent(override val data: DataVulcan, val onSuccess: () ->
|
|||||||
?: {
|
?: {
|
||||||
val receiverName = receiver.getString("Nazwa") ?: ""
|
val receiverName = receiver.getString("Nazwa") ?: ""
|
||||||
|
|
||||||
receiverName.getLastFirstName()?.let { (receiverLastName, receiverFirstName) ->
|
receiverName.splitName()?.let { (receiverLastName, receiverFirstName) ->
|
||||||
val teacherObject = Teacher(
|
val teacherObject = Teacher(
|
||||||
profileId,
|
profileId,
|
||||||
-1 * Utils.crc16(receiverName.toByteArray()).toLong(),
|
-1 * Utils.crc16(receiverName.toByteArray()).toLong(),
|
||||||
|
@ -22,7 +22,6 @@ import org.greenrobot.eventbus.EventBus
|
|||||||
import org.greenrobot.eventbus.Subscribe
|
import org.greenrobot.eventbus.Subscribe
|
||||||
import org.greenrobot.eventbus.ThreadMode
|
import org.greenrobot.eventbus.ThreadMode
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
|
import pl.szczodrzynski.edziennik.data.api.events.ApiTaskAllFinishedEvent
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
|
||||||
@ -116,7 +115,7 @@ class HomeTimetableCard(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getLoginData("timetableNotPublic", false)) {
|
if (app.profile.getLoginData("timetableNotPublic", false)) {
|
||||||
b.timetableLayout.visibility = View.GONE
|
b.timetableLayout.visibility = View.GONE
|
||||||
b.notPublicLayout.visibility = View.VISIBLE
|
b.notPublicLayout.visibility = View.VISIBLE
|
||||||
return
|
return
|
||||||
|
@ -20,7 +20,6 @@ import kotlinx.coroutines.*
|
|||||||
import pl.szczodrzynski.edziennik.App
|
import pl.szczodrzynski.edziennik.App
|
||||||
import pl.szczodrzynski.edziennik.MainActivity
|
import pl.szczodrzynski.edziennik.MainActivity
|
||||||
import pl.szczodrzynski.edziennik.R
|
import pl.szczodrzynski.edziennik.R
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
|
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
|
||||||
@ -88,7 +87,7 @@ class TimetableFragment : Fragment(), CoroutineScope {
|
|||||||
if (app.profile == null || !isAdded)
|
if (app.profile == null || !isAdded)
|
||||||
return@launch
|
return@launch
|
||||||
|
|
||||||
if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getLoginData("timetableNotPublic", false)) {
|
if (app.profile.getLoginData("timetableNotPublic", false)) {
|
||||||
b.timetableLayout.visibility = View.GONE
|
b.timetableLayout.visibility = View.GONE
|
||||||
b.timetableNotPublicLayout.visibility = View.VISIBLE
|
b.timetableNotPublicLayout.visibility = View.VISIBLE
|
||||||
return@launch
|
return@launch
|
||||||
|
@ -18,7 +18,6 @@ import com.linkedin.android.tachyon.DayViewConfig
|
|||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import pl.szczodrzynski.edziennik.*
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
import pl.szczodrzynski.edziennik.MainActivity.Companion.DRAWER_ITEM_TIMETABLE
|
||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_LIBRUS
|
|
||||||
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
import pl.szczodrzynski.edziennik.data.api.task.EdziennikTask
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
|
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
|
||||||
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
|
||||||
@ -151,7 +150,7 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// reload the fragment when: no lessons, user wants to sync the week, the timetable is not public, pager gets removed
|
// reload the fragment when: no lessons, user wants to sync the week, the timetable is not public, pager gets removed
|
||||||
if (app.profile.loginStoreType == LOGIN_TYPE_LIBRUS && app.profile.getLoginData("timetableNotPublic", false)) {
|
if (app.profile.getLoginData("timetableNotPublic", false)) {
|
||||||
activity.reloadTarget()
|
activity.reloadTarget()
|
||||||
// TODO fix for (not really)possible infinite loops
|
// TODO fix for (not really)possible infinite loops
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user