From f9029bf1c328d2a48dd172ebbbf5eadc2a319ee6 Mon Sep 17 00:00:00 2001 From: Seil0 Date: Sat, 6 Jun 2020 23:07:23 +0200 Subject: [PATCH] use HashMap insted of ArrayList to store the timetables --- .../org/mosad/thecitadelofricks/DataTypes.kt | 4 +- .../controller/CacheController.kt | 50 ++++++++----------- .../controller/StartupController.kt | 3 +- .../hsoparser/CourseListParser.kt | 12 ++--- 4 files changed, 29 insertions(+), 40 deletions(-) diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt index 505775a..8ef387f 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt @@ -29,9 +29,9 @@ import kotlin.collections.HashMap // data classes for the course part data class Course(val courseName: String, val courseLink: String) -data class CoursesMeta(val updateTime: Long, val totalCourses: Int) +data class CoursesMeta(val updateTime: Long = 0, val totalCourses: Int = 0) -data class CoursesList(val meta: CoursesMeta, val courses: ArrayList) +data class CoursesList(val meta: CoursesMeta = CoursesMeta(), val courses: HashMap = HashMap()) // data classes for the Mensa part data class Meal(val day: String, val heading: String, val parts: ArrayList, val additives: String) diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt index af94cbe..3bdfb0d 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/controller/CacheController.kt @@ -23,10 +23,7 @@ package org.mosad.thecitadelofricks.controller import com.google.gson.Gson -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.async -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.* import org.mosad.thecitadelofricks.* import org.mosad.thecitadelofricks.hsoparser.CourseListParser import org.mosad.thecitadelofricks.hsoparser.MensaParser @@ -39,6 +36,7 @@ import java.io.FileWriter import java.util.* import java.util.concurrent.Executors import kotlin.collections.ArrayList +import kotlin.collections.HashMap import kotlin.collections.HashSet import kotlin.concurrent.scheduleAtFixedRate @@ -52,9 +50,9 @@ class CacheController { companion object{ private val logger: Logger = LoggerFactory.getLogger(CacheController::class.java) - var courseList = CoursesList(CoursesMeta(0, 0), ArrayList()) + var courseList = CoursesList() var mensaMenu = MensaMenu(MensaMeta(0,""), MensaWeek(), MensaWeek()) - var timetableList = ArrayList() // this list contains all timetables + var timetableList = HashMap() // this list contains all timetables /** * get a timetable, since they may not be cached, we need to make sure it's cached, otherwise download @@ -63,30 +61,22 @@ class CacheController { * @return timetable of the course (Type: [TimetableCourseWeek]) */ fun getTimetable(courseName: String, weekIndex: Int): TimetableCourseWeek = runBlocking { - val currentTime = System.currentTimeMillis() / 1000 - var timetable = TimetableWeek() - var weekNumberYear = 0 + return@runBlocking timetableList.getOrPut("$courseName-$weekIndex") { + val timetableLink = courseList.courses[courseName] + ?.courseLink + ?.replace("week=0", "week=$weekIndex") ?: "" + val currentTime = System.currentTimeMillis() / 1000 + var timetable = TimetableWeek() + var weekNumberYear = 0 - // check if the timetable already exists and is up to date - when (timetableList.stream().filter { x -> x.meta.courseName == courseName && x.meta.weekIndex == weekIndex }.findAny().orElse(null)) { - // there is no such course yet, create one - null -> { - val courseLink = courseList.courses.stream().filter { x -> x.courseName == courseName }.findFirst().orElse(null).courseLink - val timetableLink = courseLink.replace("week=0","week=$weekIndex") + val timetableJobs = listOf( + async { timetable = TimetableParser().getTimeTable(timetableLink) }, + async { weekNumberYear = TimetableParser().getWeekNumberYear(timetableLink) } + ) - val jobTimetable = async { - timetable = TimetableParser().getTimeTable(timetableLink) - weekNumberYear = TimetableParser().getWeekNumberYear(timetableLink) - } - - jobTimetable.await() - timetableList.add(TimetableCourseWeek(TimetableCourseMeta(currentTime, courseName, weekIndex, weekNumberYear, timetableLink), timetable)) - - logger.info("added new timetable for $courseName, week $weekIndex") - } + timetableJobs.awaitAll() + TimetableCourseWeek(TimetableCourseMeta(currentTime, courseName, weekIndex, weekNumberYear, timetableLink), timetable) } - - return@runBlocking timetableList.stream().filter { x -> x.meta.courseName == courseName && x.meta.weekIndex == weekIndex }.findAny().orElse(null) } /** @@ -170,10 +160,10 @@ class CacheController { try { timetableList.forEach { timetableCourse -> executor.execute { - timetableCourse.timetable = TimetableParser().getTimeTable(timetableCourse.meta.link) - timetableCourse.meta.updateTime = System.currentTimeMillis() / 1000 + timetableCourse.value.timetable = TimetableParser().getTimeTable(timetableCourse.value.meta.link) + timetableCourse.value.meta.updateTime = System.currentTimeMillis() / 1000 - saveTimetableToCache(timetableCourse) // save the updated timetable to the cache directory + saveTimetableToCache(timetableCourse.value) // save the updated timetable to the cache directory } } diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/controller/StartupController.kt b/src/main/kotlin/org/mosad/thecitadelofricks/controller/StartupController.kt index 346d76e..05446ac 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/controller/StartupController.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/controller/StartupController.kt @@ -134,7 +134,8 @@ class StartupController { try { val timetableObject = JsonParser.parseString(bufferedReader.readLine()).asJsonObject - CacheController.timetableList.add(Gson().fromJson(timetableObject, TimetableCourseWeek().javaClass)) + val timetable = Gson().fromJson(timetableObject, TimetableCourseWeek().javaClass) + CacheController.timetableList.put("${timetable.meta.courseName}-${timetable.meta.weekIndex}", timetable) } catch (ex: Exception) { logger.error("error while reading cache", ex) } finally { diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt index fb940f0..0d192fb 100644 --- a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt +++ b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt @@ -36,17 +36,15 @@ class CourseListParser { * @param courseListURL the url to the course list page * @return a ArrayList with all courses or null if the request was not successful */ - fun getCourseLinks(courseListURL: String): ArrayList? { - val courseLinkList = ArrayList() + fun getCourseLinks(courseListURL: String): HashMap? { + val courseLinkList = HashMap() try { val courseHTML = Jsoup.connect(courseListURL).get() courseHTML.select("ul.index-group").select("li.Class").select("a[href]").forEachIndexed { _, element -> - courseLinkList.add( - Course( - element.text(), - element.attr("href").replace("http", "https") - ) + courseLinkList[element.text()] = Course( + element.text(), + element.attr("href").replace("http", "https") ) } } catch (ex: SocketTimeoutException) {