From fdb5f7ec0240a4b8671ff45eba44fd2f27f25045 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Szczodrzy=C5=84ski?= Date: Mon, 18 Nov 2019 22:57:23 +0100 Subject: [PATCH] [APIv2/Mobidziennik] Implement getting message details. --- .../szczodrzynski/edziennik/api/v2/Regexes.kt | 12 ++ .../api/v2/mobidziennik/Mobidziennik.kt | 8 +- .../data/web/MobidziennikWebGetMessage.kt | 157 ++++++++++++++++++ 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/web/MobidziennikWebGetMessage.kt diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Regexes.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Regexes.kt index e6025f9d..3bc7f005 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Regexes.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/Regexes.kt @@ -37,6 +37,16 @@ object Regexes { """events: (.+),$""".toRegex(RegexOption.MULTILINE) } + val MOBIDZIENNIK_MESSAGE_READ_DATE by lazy { + """czas przeczytania:.+?,\s([0-9]+)\s(.+?)\s([0-9]{4}),\sgodzina\s([0-9:]+)""".toRegex(RegexOption.DOT_MATCHES_ALL) + } + val MOBIDZIENNIK_MESSAGE_SENT_READ_DATE by lazy { + """.+?,\s([0-9]+)\s(.+?)\s([0-9]{4}),\sgodzina\s([0-9:]+)""".toRegex(RegexOption.DOT_MATCHES_ALL) + } + val MOBIDZIENNIK_MESSAGE_ATTACHMENT by lazy { + """href="https://.+?\.mobidziennik.pl/.+?&(?:amp;)?zalacznik=([0-9]+)"(?:.+?(.+?)\s(.+?)\s*\((.+?),\s*(.+?)\)""".toRegex(RegexOption.DOT_MATCHES_ALL) } + + val VULCAN_SHITFT_ANNOTATION by lazy { """\(przeniesiona (z|na) lekcj[ię] ([0-9]+), (.+)\)""".toRegex() } diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/Mobidziennik.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/Mobidziennik.kt index b4c825f1..21a136a8 100644 --- a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/Mobidziennik.kt +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/Mobidziennik.kt @@ -10,8 +10,10 @@ import pl.szczodrzynski.edziennik.api.v2.CODE_INTERNAL_LIBRUS_ACCOUNT_410 import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikCallback import pl.szczodrzynski.edziennik.api.v2.interfaces.EdziennikInterface import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikData +import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.web.MobidziennikWebGetMessage import pl.szczodrzynski.edziennik.api.v2.mobidziennik.firstlogin.MobidziennikFirstLogin import pl.szczodrzynski.edziennik.api.v2.mobidziennik.login.MobidziennikLogin +import pl.szczodrzynski.edziennik.api.v2.mobidziennik.login.MobidziennikLoginWeb import pl.szczodrzynski.edziennik.api.v2.mobidziennikLoginMethods import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.prepare @@ -63,7 +65,11 @@ class Mobidziennik(val app: App, val profile: Profile?, val loginStore: LoginSto } override fun getMessage(message: MessageFull) { - + MobidziennikLoginWeb(data) { + MobidziennikWebGetMessage(data, message) { + completed() + } + } } override fun markAllAnnouncementsAsRead() { diff --git a/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/web/MobidziennikWebGetMessage.kt b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/web/MobidziennikWebGetMessage.kt new file mode 100644 index 00000000..3307ee7c --- /dev/null +++ b/app/src/main/java/pl/szczodrzynski/edziennik/api/v2/mobidziennik/data/web/MobidziennikWebGetMessage.kt @@ -0,0 +1,157 @@ +/* + * Copyright (c) Kuba Szczodrzyński 2019-11-18. + */ + +package pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.web + +import org.greenrobot.eventbus.EventBus +import org.jsoup.Jsoup +import pl.szczodrzynski.edziennik.api.v2.Regexes +import pl.szczodrzynski.edziennik.api.v2.events.MessageGetEvent +import pl.szczodrzynski.edziennik.api.v2.mobidziennik.DataMobidziennik +import pl.szczodrzynski.edziennik.api.v2.mobidziennik.data.MobidziennikWeb +import pl.szczodrzynski.edziennik.data.db.modules.messages.Message +import pl.szczodrzynski.edziennik.data.db.modules.messages.Message.TYPE_RECEIVED +import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageFull +import pl.szczodrzynski.edziennik.data.db.modules.messages.MessageRecipientFull +import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata +import pl.szczodrzynski.edziennik.get +import pl.szczodrzynski.edziennik.singleOrNull +import pl.szczodrzynski.edziennik.utils.Utils.monthFromName +import pl.szczodrzynski.edziennik.utils.models.Date +import pl.szczodrzynski.edziennik.utils.models.Time + +class MobidziennikWebGetMessage( + override val data: DataMobidziennik, + private val message: MessageFull, + val onSuccess: () -> Unit) : MobidziennikWeb(data) { + companion object { + private const val TAG = "MobidziennikWebGetMessage" + } + + init { + val typeUrl = if (message.type == Message.TYPE_SENT) + "wiadwyslana" + else + "wiadodebrana" + webGet(TAG, "/dziennik/$typeUrl/?id=${message.id}") { text -> + MobidziennikLuckyNumberExtractor(data, text) + + val messageRecipientList = mutableListOf() + + val doc = Jsoup.parse(text) + + val content = doc.select("#content").first() + + val body = content.select(".wiadomosc_tresc").first() + + if (message.type == TYPE_RECEIVED) { + var readDate = System.currentTimeMillis() + Regexes.MOBIDZIENNIK_MESSAGE_READ_DATE.find(body.html())?.let { + val date = Date( + it[3].toIntOrNull() ?: 2019, + monthFromName(it[2]), + it[1].toIntOrNull() ?: 1 + ) + val time = Time.fromH_m_s( + it[4] // TODO blank string safety + ) + readDate = date.combineWith(time) + } + + val recipient = MessageRecipientFull( + profileId, + -1, + -1, + readDate, + message.id + ) + + recipient.fullName = profile?.accountNameLong ?: profile?.studentNameLong + + messageRecipientList.add(recipient) + } else { + message.senderId = -1 + message.senderReplyId = -1 + + content.select("table.spis tr:has(td)")?.forEach { recipientEl -> + val senderEl = recipientEl.select("td:eq(0)").first() + val senderName = senderEl.text() + + val teacher = data.teacherList.singleOrNull { it.fullNameLastFirst == senderName } + val receiverId = teacher?.id ?: -1 + + var readDate = 0L + val isReadEl = recipientEl.select("td:eq(2)").first() + if (isReadEl.ownText() != "NIE") { + val readDateEl = recipientEl.select("td:eq(3) small").first() + Regexes.MOBIDZIENNIK_MESSAGE_SENT_READ_DATE.find(readDateEl.ownText())?.let { + val date = Date( + it[3].toIntOrNull() ?: 2019, + monthFromName(it[2]), + it[1].toIntOrNull() ?: 1 + ) + val time = Time.fromH_m_s( + it[4] // TODO blank string safety + ) + readDate = date.combineWith(time) + } + } + + val recipient = MessageRecipientFull( + profileId, + receiverId, + -1, + readDate, + message.id + ) + + recipient.fullName = teacher?.fullName ?: "?" + + messageRecipientList.add(recipient) + } + } + + // this line removes the sender and read date details + body.select("div").remove() + + // this needs to be at the end + message.apply { + this.body = body.html() + + clearAttachments() + content.select("ul li").map { it.select("a").first() }.forEach { + val attachmentName = it.ownText() + Regexes.MOBIDZIENNIK_MESSAGE_ATTACHMENT.find(it.outerHtml())?.let { match -> + val attachmentId = match[1].toLong() + var size = match[2].toFloatOrNull() ?: 0f + when (match[3]) { + "K" -> size *= 1024f + "M" -> size *= 1024f * 1024f + "G" -> size *= 1024f * 1024f * 1024f + } + message.addAttachment(attachmentId, attachmentName, size.toLong()) + } + } + } + + if (!message.seen) { // TODO discover why this monstrosity instead of MetadataDao.setSeen + data.messageMetadataList.add(Metadata( + message.profileId, + Metadata.TYPE_MESSAGE, + message.id, + true, + true, + message.addedDate + )) + } + + message.recipients = messageRecipientList + data.messageRecipientList.addAll(messageRecipientList) + data.messageList.add(message) + + EventBus.getDefault().postSticky(MessageGetEvent(message)) + onSuccess() + } + } +} \ No newline at end of file