diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt index 06031ad..9f6d6b7 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/APIController.kt @@ -102,7 +102,7 @@ class APIController { @RequestParam(value = "course", defaultValue = "AI4") courseName: String, @RequestParam(value = "subject", defaultValue = "Mathematik 4") lessonSubject: String, @RequestParam(value = "week", defaultValue = "0") week: Int - ): ArrayList { + ): ArrayList { logger.info("lesson request at ${LocalDateTime.now()}!") updateTimetableRequests(courseName) return getLesson(courseName, lessonSubject, week) diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt index 490f6f7..8cd20c8 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt @@ -49,7 +49,7 @@ data class MensaMenu(val meta: MensaMeta, val currentWeek: MensaWeek, val nextWe data class CalendarWeek(val week: Int, val year: Int) -data class Lesson( +data class LessonWithRoom( val lessonID: String, val lessonSubject: String, val lessonTeacher: String, @@ -57,13 +57,21 @@ data class Lesson( val lessonRemark: String ) -data class TimetableDay(val timeslots: Array> = Array(6) { ArrayList() }) +data class LessonWithCourse( + val lessonID: String, + val lessonSubject: String, + val lessonTeacher: String, + val lessonCourse: String, + val lessonRemark: String +) -data class TimetableWeek(val days: Array = Array(6) { TimetableDay() }) +data class TimetableDay(val timeslots: Array> = Array(6) { ArrayList() }) + +data class TimetableWeek(val days: Array> = Array(6) { TimetableDay() }) data class TimetableCourseMeta(var updateTime: Long = 0, val courseName: String = "", val weekIndex: Int = 0, var weekNumberYear: Int = 0, var year: Int = 0, val link: String = "") -data class TimetableCourseWeek(val meta: TimetableCourseMeta = TimetableCourseMeta(), var timetable: TimetableWeek = TimetableWeek()) +data class TimetableCourseWeek(val meta: TimetableCourseMeta = TimetableCourseMeta(), var timetable: TimetableWeek = TimetableWeek()) // data classes for the room occupancy part data class Room(val roomName: String, val roomLink: String) @@ -75,7 +83,7 @@ data class RoomsListRet(val meta: RoomsMeta = RoomsMeta(), val rooms: ArrayList< data class RoomScheduleMeta(var updateTime: Long = 0, val roomName: String = "", val weekIndex: Int = 0, var weekNumberYear: Int = 0, var year: Int = 0, val link: String = "") -data class RoomScheduleWeekRet(val meta: RoomScheduleMeta = RoomScheduleMeta(), var timetable: TimetableWeek = TimetableWeek()) +data class RoomScheduleWeekRet(val meta: RoomScheduleMeta = RoomScheduleMeta(), var timetable: TimetableWeek = TimetableWeek()) // data classes for the status part diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt index 5640a72..ae57c54 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt @@ -27,9 +27,10 @@ import kotlinx.coroutines.* import org.jsoup.Jsoup import org.mosad.thecitadelofricks.* import org.mosad.thecitadelofricks.hsoparser.CourseListParser +import org.mosad.thecitadelofricks.hsoparser.CourseTimetableParser import org.mosad.thecitadelofricks.hsoparser.MensaParser import org.mosad.thecitadelofricks.hsoparser.RoomListParser -import org.mosad.thecitadelofricks.hsoparser.TimetableParser +import org.mosad.thecitadelofricks.hsoparser.RoomTimetableParser import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.* @@ -41,7 +42,6 @@ import kotlin.collections.HashSet import kotlin.concurrent.scheduleAtFixedRate import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes -import kotlin.time.ExperimentalTime class CacheController { @@ -76,7 +76,7 @@ class CacheController { val instr = CacheController::class.java.getResourceAsStream("/html/Timetable_normal-week.html") val timetableParser = - TimetableParser(htmlDoc = Jsoup.parse(instr!!, "UTF-8", "https://www.hs-offenburg.de/")) + CourseTimetableParser(htmlDoc = Jsoup.parse(instr!!, "UTF-8", "https://www.hs-offenburg.de/")) val timetableTest = timetableParser.parseTimeTable() return TimetableCourseWeek( @@ -100,7 +100,7 @@ class CacheController { ?.replace("week=0", "week=$weekIndex") ?: "" val currentTime = System.currentTimeMillis() / 1000 - val timetableParser = TimetableParser(timetableLink) + val timetableParser = CourseTimetableParser(timetableLink) val calendarWeek = timetableParser.parseCalendarWeek() val timetable = timetableParser.parseTimeTable() @@ -142,8 +142,8 @@ class CacheController { * @param weekIndex request week number (current week = 0) * @return a ArrayList<[Lesson]> of every lesson with lessonSubject for one week */ - fun getLesson(courseName: String, lessonSubject: String, weekIndex: Int): ArrayList { - val lessonList = ArrayList() + fun getLesson(courseName: String, lessonSubject: String, weekIndex: Int): ArrayList { + val lessonList = ArrayList() // get all lessons from the weeks timetable val flatMap = getTimetable(courseName, weekIndex).timetable.days.flatMap { it.timeslots.asIterable() } @@ -171,7 +171,7 @@ class CacheController { ?.replace("week=0", "week=$weekIndex") ?: "" val currentTime = System.currentTimeMillis() / 1000 - val roomScheduleParser = TimetableParser(roomScheduleLink) + val roomScheduleParser = RoomTimetableParser(roomScheduleLink) val calendarWeek = roomScheduleParser.parseCalendarWeek() val roomSchedule = roomScheduleParser.parseTimeTable() @@ -248,7 +248,7 @@ class CacheController { try { timetableList.forEach { timetableCourse -> executor.execute { - val timetableParser = TimetableParser(timetableCourse.value.meta.link) + val timetableParser = CourseTimetableParser(timetableCourse.value.meta.link) timetableCourse.value.timetable = timetableParser.parseTimeTable() ?: return@execute timetableParser.parseCalendarWeek()?.also { timetableCourse.value.meta.weekNumberYear = it.week @@ -294,7 +294,7 @@ class CacheController { try { roomScheduleList.forEach { roomSchedule -> executor.execute { - val roomScheduleParser = TimetableParser(roomSchedule.value.meta.link) + val roomScheduleParser = RoomTimetableParser(roomSchedule.value.meta.link) roomSchedule.value.timetable = roomScheduleParser.parseTimeTable() ?: return@execute roomScheduleParser.parseCalendarWeek()?.also { roomSchedule.value.meta.weekNumberYear = it.week diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimetableParser.kt b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimetableParser.kt index 7e2c02f..141b436 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimetableParser.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimetableParser.kt @@ -27,7 +27,8 @@ import kotlinx.coroutines.sync.Semaphore import org.jsoup.Jsoup import org.jsoup.nodes.Document import org.mosad.thecitadelofricks.CalendarWeek -import org.mosad.thecitadelofricks.Lesson +import org.mosad.thecitadelofricks.LessonWithCourse +import org.mosad.thecitadelofricks.LessonWithRoom import org.mosad.thecitadelofricks.TimetableWeek import org.slf4j.LoggerFactory @@ -35,10 +36,13 @@ import org.slf4j.LoggerFactory * @param timetableURL the URL of the timetable you want to get * @param htmlDoc the html document to use (the timetableURL will be ignored if this value is present) */ -class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { +sealed class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { private var logger: org.slf4j.Logger = LoggerFactory.getLogger(TimetableParser::class.java) private val days = arrayOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") + abstract fun constructLesson(lessonID: String, lessonSubject: String, lessonTeacher: String, value4: String, lessonRemark: String): Lesson + abstract val value4Class: String + companion object { val semaphore = Semaphore(3, 0) } @@ -63,13 +67,13 @@ class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { * the timetable is organised per row not per column; * Mon 1, Tue 1, Wed 1, Thur 1, Fri 1, Sat 1, Mon 2 and so on */ - fun parseTimeTable(): TimetableWeek? = htmlDoc?.let { - val timetableWeek = TimetableWeek() + fun parseTimeTable(): TimetableWeek? = htmlDoc?.let { + val timetableWeek = TimetableWeek() val rows = it.select("table.timetable").select("tr[scope=\"row\"]") var sDay = -1 var sRow = -1 - var sLesson = Lesson("", "", "", "", "") + var sLesson = constructLesson("", "", "", "", "") // get each row with index, reflects 1 timeslot per day for ((rowIndex, row) in rows.withIndex()) { @@ -86,11 +90,11 @@ class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { // adjust the following slot sDay++ - sLesson = Lesson( + sLesson = constructLesson( "$day.$rowIndex.$lessonIndexDay", element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), - element.select("div.lesson-room").text(), + element.select("div.$value4Class").text(), element.select("div.lesson-remark").text() ) @@ -101,11 +105,11 @@ class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { } else { timetableWeek.days[day].timeslots[rowIndex].add( - Lesson( + constructLesson( "$day.$rowIndex.$lessonIndexDay", element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), - element.select("div.lesson-room").text(), + element.select("div.$value4Class").text(), element.select("div.lesson-remark").text() ) ) @@ -146,7 +150,7 @@ class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { * print a timetable * @param timetable the timetable to print */ - fun printTimetableWeek(timetable: TimetableWeek) { + fun printTimetableWeek(timetable: TimetableWeek) { for (j in 0..5) print(days[j].padEnd(75, ' ') + " | ") println() for (j in 0..5) print("-".padEnd(76 + (j.toFloat().div(j).toInt()), '-') + "+") @@ -189,4 +193,18 @@ class TimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) { println(" \n") } -} \ No newline at end of file +} + +class CourseTimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) : TimetableParser(timetableURL, htmlDoc) { + override fun constructLesson(lessonID: String, lessonSubject: String, lessonTeacher: String, value4: String, lessonRemark: String) + = LessonWithRoom(lessonID, lessonSubject, lessonTeacher, value4, lessonRemark) + + override val value4Class = "lesson-room" +} + +class RoomTimetableParser(timetableURL: String? = null, htmlDoc: Document? = null) : TimetableParser(timetableURL, htmlDoc) { + override fun constructLesson(lessonID: String, lessonSubject: String, lessonTeacher: String, value4: String, lessonRemark: String) + = LessonWithCourse(lessonID, lessonSubject, lessonTeacher, value4, lessonRemark) + + override val value4Class = "lesson-class" +}