forked from agzam/vyatsu-schedule
fix: wrong parsed teacher schedule
This commit is contained in:
@@ -23,9 +23,18 @@ object TeacherScheduleParser {
|
||||
|
||||
data class ParsedTeacherSchedule(val teachers: List<String>, val days: List<Day>)
|
||||
|
||||
/**
|
||||
* Столбец расписания преподавателя: имя и абсолютный индекс ячейки в шапке.
|
||||
* Индекс нужен для точного выравнивания с рядами данных — в шапке могут
|
||||
* присутствовать пустые колонки-разделители, которые не должны сдвигать
|
||||
* соответствие «преподаватель → столбец».
|
||||
*/
|
||||
private data class Column(val teacher: String, val headerIndex: Int)
|
||||
|
||||
fun parse(html: String): ParsedTeacherSchedule {
|
||||
val doc = Jsoup.parse(html)
|
||||
var headerFound = false
|
||||
var columns: List<Column> = emptyList()
|
||||
var teachers: List<String> = emptyList()
|
||||
val days = mutableListOf<Day>()
|
||||
var currentDate: LocalDate? = null
|
||||
@@ -43,10 +52,12 @@ object TeacherScheduleParser {
|
||||
val first = cellText(tds[0])
|
||||
val second = cellText(tds[1])
|
||||
if (!headerFound && first == "День" && second == "Интервал") {
|
||||
teachers = tds.drop(2)
|
||||
.map { cellText(it.selectFirst("span") ?: it) }
|
||||
.filter { it.isNotEmpty() }
|
||||
.distinct()
|
||||
columns = tds.mapIndexedNotNull { index, td ->
|
||||
if (index < 2) return@mapIndexedNotNull null
|
||||
val name = cellText(td.selectFirst("span") ?: td)
|
||||
if (name.isEmpty()) null else Column(name, index)
|
||||
}.distinctBy { it.teacher }
|
||||
teachers = columns.map { it.teacher }
|
||||
headerFound = true
|
||||
continue
|
||||
}
|
||||
@@ -58,7 +69,7 @@ object TeacherScheduleParser {
|
||||
currentIntervals = mutableListOf()
|
||||
}
|
||||
if (intervalMatch != null && currentIntervals != null) {
|
||||
parseIntervalRow(tds, intervalMatch, if (dayMatch != null) 2 else 1, teachers, currentIntervals!!)
|
||||
parseIntervalRow(tds, intervalMatch, dayMatch != null, columns, currentIntervals!!)
|
||||
}
|
||||
}
|
||||
flushDay()
|
||||
@@ -83,16 +94,20 @@ object TeacherScheduleParser {
|
||||
private fun parseIntervalRow(
|
||||
tds: List<Element>,
|
||||
intervalMatch: MatchResult,
|
||||
startCol: Int,
|
||||
teachers: List<String>,
|
||||
dayRow: Boolean,
|
||||
columns: List<Column>,
|
||||
intervals: MutableList<TimeSlot>
|
||||
) {
|
||||
val start = LocalTime.parse(intervalMatch.groupValues[1])
|
||||
val end = LocalTime.parse(intervalMatch.groupValues[2])
|
||||
val lessons = mutableListOf<Lesson>()
|
||||
for (i in teachers.indices) {
|
||||
val cell = tds.getOrNull(startCol + i) ?: continue
|
||||
lessons += parseCell(cell, teachers[i])
|
||||
for (column in columns) {
|
||||
// Ряд с днём содержит обе ведущие ячейки (День, Интервал) и совпадает
|
||||
// по индексам с шапкой; ряд только с интервалом пропускает ячейку дня
|
||||
// (rowspan) — его ячейки сдвинуты на одну позицию влево.
|
||||
val dataIndex = if (dayRow) column.headerIndex else column.headerIndex - 1
|
||||
val cell = tds.getOrNull(dataIndex) ?: continue
|
||||
lessons += parseCell(cell, column.teacher)
|
||||
}
|
||||
if (lessons.isNotEmpty()) intervals.add(TimeSlot(start, end, lessons))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user