[API/Edudziennik] Add getting grades and add basic error handling.

This commit is contained in:
Kacper Ziubryniewicz 2019-12-23 22:56:23 +01:00
parent 844d5b33bc
commit 30ee71f4e3
15 changed files with 303 additions and 67 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
} }

View File

@ -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
}
}
} }

View File

@ -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) {
when (apiError.errorCode) { if (apiError.errorCode in internalErrorList) {
in internalErrorList -> {
// finish immediately if the same error occurs twice during the same sync // finish immediately if the same error occurs twice during the same sync
callback.onError(apiError) callback.onError(apiError)
return
}
internalErrorList.add(apiError.errorCode)
when (apiError.errorCode) {
ERROR_LOGIN_EDUDZIENNIK_WEB_NO_SESSION_ID -> {
login()
}
ERROR_EDUDZIENNIK_WEB_TIMETABLE_NOT_PUBLIC -> {
loginStore.putLoginData("timetableNotPublic", true)
data()
} }
else -> callback.onError(apiError) else -> callback.onError(apiError)
} }

View File

@ -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))

View File

@ -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))
} }

View File

@ -20,8 +20,7 @@ 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( val luckyNumberObject = LuckyNumber(
profileId, profileId,
Date.getToday(), Date.getToday(),
@ -37,6 +36,7 @@ class EdudziennikWebLuckyNumber(override val data: DataEdudziennik,
profile.empty, profile.empty,
System.currentTimeMillis() System.currentTimeMillis()
)) ))
}
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_LUCKY_NUMBER, SYNC_ALWAYS)
onSuccess() onSuccess()

View File

@ -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 doc = Jsoup.parse(text)
getInfo(text)
getGrades(doc)
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, SYNC_ALWAYS)
onSuccess()
}
}
private fun getInfo(text: String) {
val schoolId = EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1) val schoolId = EDUDZIENNIK_SCHOOL_DETAIL_ID.find(text)?.get(1)
data.schoolId = schoolId data.schoolId = schoolId
val classId = EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1) val classId = EDUDZIENNIK_CLASS_DETAIL_ID.find(text)?.get(1)
data.classId = classId data.classId = classId
}
data.setSyncNext(ENDPOINT_EDUDZIENNIK_WEB_START, SYNC_ALWAYS) private fun getGrades(doc: Document) { data.profile?.also { profile ->
onSuccess() 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() }
} }

View File

@ -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 subject = data.subjectList.singleOrNull { it.id == subjectId } ?: run {
val subjectName = subjectElement.text().trim() val subjectName = subjectElement.text().trim()
val subjectObject = Subject(profileId, subjectId, subjectName, subjectName) val subject = data.getSubject(subjectId, 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)
?.crc32() ?: return@forEachIndexed
val teacher = data.teacherList.singleOrNull { it.id == teacherId } ?: run {
val teacherName = teacherElement.text().trim() val teacherName = teacherElement.text().trim()
val teacherObject = teacherName.getLastFirstName()?.let { (teacherLastName, teacherFirstName) -> val teacher = teacherName.splitName()?.let { (teacherLastName, teacherFirstName) ->
Teacher(profileId, teacherId, teacherFirstName, teacherLastName) data.getTeacher(teacherFirstName, teacherLastName)
}
data.teacherList.put(teacherId, teacherObject)
teacherObject
} ?: return@forEachIndexed } ?: return@forEachIndexed
val lessonObject = Lesson(profileId, -1).also { val lessonObject = Lesson(profileId, -1).also {

View File

@ -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(),

View File

@ -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(),

View File

@ -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

View File

@ -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

View File

@ -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