Upgrade jsoup to 1.14.2

This commit is contained in:
Mikołaj Pich 2021-09-04 12:45:34 +02:00
parent 46ce30f2b8
commit 7c399ffaea
7 changed files with 21 additions and 20 deletions

View file

@ -10,6 +10,7 @@ ext {
GIT_URL = 'https://github.com/wulkanowy/sdk.git'
jspoon = "1.3.2"
jsoup = "1.14.2"
okhttp3 = "4.9.1"
retrofit = "2.9.0"
slf4j = "1.7.32"
@ -127,7 +128,6 @@ subprojects {
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp3"

View file

@ -6,6 +6,7 @@ plugins {
dependencies {
implementation "pl.droidsonroids:jspoon:$jspoon"
implementation "org.jsoup:jsoup:$jsoup"
testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp3"
implementation "com.squareup.retrofit2:retrofit:$retrofit"

View file

@ -43,8 +43,8 @@ class ErrorInterceptor : Interceptor {
}
doc.select("#MainPage_ErrorDiv div").let {
if (it?.text()?.contains("Trwa aktualizacja bazy danych") == true) throw ServiceUnavailableException(it.last().ownText())
if (it?.last()?.ownText()?.contains("czasowo wyłączona") == true) throw TemporarilyDisabledException(it.last().ownText())
if (it.text().contains("Trwa aktualizacja bazy danych")) throw ServiceUnavailableException(it.last()?.ownText().orEmpty())
if (it.last()?.ownText()?.contains("czasowo wyłączona") == true) throw TemporarilyDisabledException(it.last()?.ownText().orEmpty())
if (it.isNotEmpty()) throw VulcanException(it[0].ownText())
}
@ -52,7 +52,7 @@ class ErrorInterceptor : Interceptor {
if (it.isNotEmpty()) throw AccountPermissionException(it.text())
}
doc.select("form")?.attr("action")?.let {
doc.selectFirst("form")?.attr("action")?.let {
if ("SetNewPassword" in it) {
logger.debug("Set new password action url: $redirectUrl")
throw PasswordChangeRequiredException("Wymagana zmiana hasła użytkownika", redirectUrl)
@ -62,10 +62,10 @@ class ErrorInterceptor : Interceptor {
when (doc.title()) {
"Błąd" -> throw VulcanException(doc.body().text())
"Błąd strony" -> throw VulcanException(doc.select(".errorMessage").text())
"Logowanie" -> throw AccountPermissionException(doc.select("div").last().ownText().split(" Jeśli")[0])
"Logowanie" -> throw AccountPermissionException(doc.select("div").last()?.ownText().orEmpty().split(" Jeśli")[0])
"Przerwa techniczna" -> throw ServiceUnavailableException(doc.title())
"Strona nie została odnaleziona" -> throw ScrapperException(doc.title())
"Strona nie znaleziona" -> throw ScrapperException(doc.selectFirst("div div").text())
"Strona nie znaleziona" -> throw ScrapperException(doc.selectFirst("div div")?.text().orEmpty())
}
doc.select("h2").text().let {

View file

@ -41,9 +41,9 @@ class AccountRepository(private val account: AccountService) {
ADFSLight, ADFSLightScoped, ADFSLightCufs -> account.sendPasswordResetRequestADFSLight(url, email, captchaCode)
ADFS, ADFSCards -> {
val page = account.getPasswordResetPageADFS(url)
val formFields = page.html.select("[type=hidden]").map { input ->
val formFields = page.html.select("[type=hidden]").associate { input ->
input.attr("name") to input.attr("value")
}.toMap()
}
account.sendPasswordResetRequestADFS(
url = url,
username = email,
@ -55,10 +55,10 @@ class AccountRepository(private val account: AccountService) {
}
with(res.html) {
select(".ErrorMessage")?.text()?.let { // STANDARD
select(".ErrorMessage").text().let { // STANDARD
if (it.contains("Niepoprawny adres email")) throw InvalidEmailException(it)
}
select(".ErrorMessage, #ErrorTextLabel, #lblStatus")?.text()?.let { // STANDARD, ADFSLight, ADFSCards
select(".ErrorMessage, #ErrorTextLabel, #lblStatus").text()?.let { // STANDARD, ADFSLight, ADFSCards
if (it.contains("nie zostało odnalezione lub zostało zablokowane")) throw NoAccountFoundException(it)
if (it.contains("nie ma w systemie zarejestrowanych")) throw NoAccountFoundException(it) // 😀
if (it.contains("żądanie nie zostało poprawnie autoryzowane")) throw InvalidCaptchaException(it)
@ -101,7 +101,7 @@ class AccountRepository(private val account: AccountService) {
page.select(SELECTOR_STANDARD).isNotEmpty() -> STANDARD
page.select(SELECTOR_ADFS).isNotEmpty() -> ADFS
page.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> {
page.selectFirst("form").attr("action").run {
page.selectFirst("form")?.attr("action").orEmpty().run {
when {
contains("cufs.edu.lublin.eu") -> ADFSLightCufs
startsWith("/LoginPage.aspx") -> ADFSLight

View file

@ -85,7 +85,7 @@ class RegisterRepository(
page.select(SELECTOR_STANDARD).isNotEmpty() -> Scrapper.LoginType.STANDARD
page.select(SELECTOR_ADFS).isNotEmpty() || page.select(SELECTOR_ADFS_MS).isNotEmpty() -> Scrapper.LoginType.ADFS
page.select(SELECTOR_ADFS_LIGHT).isNotEmpty() -> {
page.selectFirst("form").attr("action").run {
page.selectFirst("form")?.attr("action").orEmpty().run {
when {
contains("cufs.edu.lublin.eu") -> Scrapper.LoginType.ADFSLightCufs
startsWith("/LoginPage.aspx") -> Scrapper.LoginType.ADFSLight

View file

@ -25,7 +25,7 @@ fun TimetableResponse.mapTimetableList(startDate: LocalDate, endDate: LocalDate?
)
}.mapNotNull { parser.getTimetable(it) }
}.asSequence().filter {
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= endDate ?: startDate.plusDays(4)
it.date.toLocalDate() >= startDate && it.date.toLocalDate() <= (endDate ?: startDate.plusDays(4))
}.sortedWith(compareBy({ it.date }, { it.number })).toList()
fun TimetableResponse.mapTimetableHeaders() = headers.drop(1).map {
@ -70,6 +70,6 @@ fun ApiResponse<*>.mapCompletedLessonsList(start: LocalDate, endDate: LocalDate?
teacher = teacher.substringBefore(" [")
}
}.sortedWith(compareBy({ it.date }, { it.number })).toList().filter {
it.date.toLocalDate() >= start && it.date.toLocalDate() <= endDate ?: start.plusDays(4)
it.date.toLocalDate() >= start && it.date.toLocalDate() <= (endDate ?: start.plusDays(4))
}
}

View file

@ -108,10 +108,10 @@ class TimetableParser {
when {
size == 2 -> getLessonLight(lesson, this, div.ownText())
size == 3 -> getSimpleLesson(lesson, this, changes = div.ownText())
size == 4 && last().hasClass(CLASS_REALIZED) -> getSimpleLesson(lesson, this, changes = div.ownText())
size == 4 && last()?.hasClass(CLASS_REALIZED) == true -> getSimpleLesson(lesson, this, changes = div.ownText())
size == 4 -> getGroupLesson(lesson, this)
size == 5 && first().hasClass(CLASS_CHANGES) && select(".$CLASS_REALIZED").size == 2 -> getSimpleLesson(lesson, this, 1, changes = div.ownText())
size == 5 && last().hasClass(CLASS_REALIZED) -> getGroupLesson(lesson, this)
size == 5 && first()?.hasClass(CLASS_CHANGES) == true && select(".$CLASS_REALIZED").size == 2 -> getSimpleLesson(lesson, this, 1, changes = div.ownText())
size == 5 && last()?.hasClass(CLASS_REALIZED) == true -> getGroupLesson(lesson, this)
size == 7 -> getSimpleLessonWithReplacement(lesson, this)
size == 9 -> getGroupLessonWithReplacement(lesson, this)
else -> lesson
@ -135,7 +135,7 @@ class TimetableParser {
}
private fun getLessonLight(lesson: Timetable, spans: Elements, info: String): Timetable {
val firstElementClasses = spans.first().classNames()
val firstElementClasses = spans.first()?.classNames().orEmpty()
val isCanceled = CLASS_MOVED_OR_CANCELED in firstElementClasses
return lesson.copy(
subject = getLessonAndGroupInfoFromSpan(spans[0])[0],
@ -148,7 +148,7 @@ class TimetableParser {
}
private fun getLesson(lesson: Timetable, spans: Elements, offset: Int = 0, infoExtraOffset: Int = 0, changes: String = ""): Timetable {
val firstElementClasses = spans.first().classNames()
val firstElementClasses = spans.first()?.classNames().orEmpty()
val isCanceled = CLASS_MOVED_OR_CANCELED in firstElementClasses
return lesson.copy(
subject = getLessonAndGroupInfoFromSpan(spans[0])[0],
@ -169,7 +169,7 @@ class TimetableParser {
teacherOld = spans[1 + o].text(),
room = spans[5 + o * 2].text(),
roomOld = spans[2 + o].text(),
info = "${getFormattedLessonInfo(spans.last().text())}, poprzednio: ${getLessonAndGroupInfoFromSpan(spans[0])[0]}",
info = "${getFormattedLessonInfo(spans.last()?.text())}, poprzednio: ${getLessonAndGroupInfoFromSpan(spans[0])[0]}",
changes = true
)