From ace2cb1e39efe6525db8e75fad0ffeb6b556c16d Mon Sep 17 00:00:00 2001 From: Seil0 Date: Mon, 11 Mar 2019 20:12:49 +0100 Subject: [PATCH] updated all parser & updated build.gradle this is the first work to get tcor fully workin --- build.gradle | 31 +++- gradle/wrapper/gradle-wrapper.properties | 3 +- settings.gradle | 3 +- src/main/kotlin/Main.kt | 11 -- src/main/kotlin/MensaParser.kt | 58 ------- src/main/kotlin/TimeTableParser.kt | 80 ---------- .../org/mosad/thecitadelofricks/DataTypes.kt | 36 +++++ .../org/mosad/thecitadelofricks/Main.kt | 40 +++++ .../hsoparser/CourseListParser.kt | 45 ++++++ .../hsoparser/MensaParser.kt | 86 +++++++++++ .../hsoparser/TimeTableParser.kt | 145 ++++++++++++++++++ 11 files changed, 381 insertions(+), 157 deletions(-) delete mode 100644 src/main/kotlin/Main.kt delete mode 100644 src/main/kotlin/MensaParser.kt delete mode 100644 src/main/kotlin/TimeTableParser.kt create mode 100644 src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt create mode 100644 src/main/kotlin/org/mosad/thecitadelofricks/Main.kt create mode 100644 src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt create mode 100644 src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/MensaParser.kt create mode 100644 src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimeTableParser.kt diff --git a/build.gradle b/build.gradle index b3cfbd2..2c6467e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,27 @@ -plugins { - id 'org.jetbrains.kotlin.jvm' version '1.3.0' + +buildscript { + ext.kotlin_version = '1.3.21' + + repositories { + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'org.jsoup:jsoup:1.11.3' + } } -group 'org.mosad.seil0' -version '1.0-SNAPSHOT' +plugins { + id 'org.jetbrains.kotlin.jvm' version '1.3.21' +} + +apply plugin: 'kotlin' +apply plugin: 'application' + +application { + mainClassName = "org.mosad.thecitadelofricks.MainKt" +} repositories { mavenCentral() @@ -19,4 +37,7 @@ compileKotlin { } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" -} \ No newline at end of file +} + +group 'org.mosad' +version '1.0-SNAPSHOT' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index d2c45a4..7e88b2b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Mon Mar 11 19:03:50 CET 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/settings.gradle b/settings.gradle index 55ac22f..e176a18 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -rootProject.name = 'TheCitadelofRicks' - +rootProject.name = 'thecitadelofricks' diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt deleted file mode 100644 index 3623514..0000000 --- a/src/main/kotlin/Main.kt +++ /dev/null @@ -1,11 +0,0 @@ - - -fun main() { - // TODO implement -} - -data class Lesson(val lessonSubject: String, val lessonTeacher: String, val lessonRoom:String, val lessonRemark: String) - -data class CourseTTLink(val courseTTLink: String, val course: String) - -data class Meal(val day: String, val heading: String, val parts: ArrayList, val additives: String) diff --git a/src/main/kotlin/MensaParser.kt b/src/main/kotlin/MensaParser.kt deleted file mode 100644 index 592e4f0..0000000 --- a/src/main/kotlin/MensaParser.kt +++ /dev/null @@ -1,58 +0,0 @@ - -import org.jsoup.Jsoup - -class MensaParser { - fun getMensaMenu() { - val menuHTML = Jsoup.connect("https://www.swfr.de/de/essen-trinken/speiseplaene/mensa-offenburg/").get() - - menuHTML.select("#speiseplan-tabs").select("div.tab-content").select("div.menu-tagesplan").forEachIndexed { index, element -> - var day = element.select("h3").text() - for (i in 0 .. (element.select("div.row h4").size - 1)) { - try { - var heading = element.select("div.row h4")[i].text() - var parts = ArrayList(element.select("div.row").select("div.menu-info")[i].html().substringBefore("", "|").split("|")) - var additives = element.select("div.row").select("div.menu-info")[i].select("span.show-with-allergenes").text() - - mealList.add(Meal(day, heading, parts, additives)) - } catch (e: Exception) { - // catch - } - } - } - } - - // TODO The following code can be removed - - fun printMensaMenu(mealList: ArrayList) { - for (meal in mealList) { - printMeal(meal) - } - println() - } - - fun printDayMenu(mealList: ArrayList, day: Int) { - var strDay: String = when(day) { - 0 -> "Mon" - 1 -> "Die" - 2 -> "Mit" - 3 -> "Don" - 4 -> "Fre" - 5 -> "Sam" - else -> "TODAY" //TODO - } - - for (meal in mealList) { - if (meal.day.contains(strDay)) printMeal(meal) - } - } - - fun printMeal(meal: Meal) { - println(meal.day) - println(meal.heading) - for (part in meal.parts) { - print(part) - } - println("\n" + meal.additives + "\n\n") - } - -} \ No newline at end of file diff --git a/src/main/kotlin/TimeTableParser.kt b/src/main/kotlin/TimeTableParser.kt deleted file mode 100644 index 90fbc76..0000000 --- a/src/main/kotlin/TimeTableParser.kt +++ /dev/null @@ -1,80 +0,0 @@ - -import org.jsoup.Jsoup - -class TimeTableParser { - - val days = arrayOf("Monday", "Tuesday" ,"Wednesday", "Thursday", "Friday", "Saturday") - var timeTableWeek = arrayOf>() - var courseTTLinkList = ArrayList() - - /** - * get the timetable from the given url - * 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 getTimeTable(courseTTURL: String) { - - // TODO do we even need this? - // create the timetable array -// for (i in 0..5) { -// var timeTableDay = arrayOf() -// for (j in 0..6) { -// timeTableDay += Lesson("", "","","") -// } -// timeTableWeek += timeTableDay -// } - - - val scheduleHTML = Jsoup.connect(courseTTURL).get() - - val week = scheduleHTML.select("h1.timetable-caption").text() - println("$week successful!\n") - - scheduleHTML.select("table.timetable").select("td.lastcol").forEachIndexed { index, element -> - timeTableWeek[index % 6][index / 6] = Lesson(element.select("div.lesson-subject").text(), element.select("div.lesson-teacher").text(), element.select("div.lesson-room").text(), element.select("div.lesson-remark").text()) - } - } - - /** - * parse all courses from the courses site at https://www.hs-offenburg.de/studium/vorlesungsplaene/ - */ - fun getCourseTTLinks() { - val courseHTML = Jsoup.connect("https://www.hs-offenburg.de/studium/vorlesungsplaene/").get() - - courseHTML.select("ul.index-group").select("li.Class").select("a[href]").forEachIndexed { _, element -> - courseTTLinkList.add(CourseTTLink(element.attr("href"),element.text())) - } - } - - fun printTimeTableWeek (timeTableWeek: Array>) { - - for (j in 0..5) print(days[j].padEnd(25 ,' ') + " | ") - println() - for (j in 0..5) print("-".padEnd(26 + (j.toFloat().div(j).toInt()), '-') + "+") - println() - - for (i in 0..6) { - for (j in 0..5) print(timeTableWeek[j][i].lessonSubject.padEnd(25 ,' ').substring(0,25) + " | ") - println() - for (j in 0..5) print(timeTableWeek[j][i].lessonTeacher.padEnd(25 ,' ').substring(0,25) + " | ") - println() - for (j in 0..5) print(timeTableWeek[j][i].lessonRoom.padEnd(25 ,' ').substring(0,25) + " | ") - println() - for (j in 0..5) print("-".padEnd(26 + (j.toFloat().div(j).toInt()), '-') + "+") - println() - } - println() - } - - fun printTimeTableDay(timeTableDay: Array, day: Int) { - println(days[day]) - for (i in 0..6) { - println("-".padEnd(22, '-')) - println(timeTableDay[i].lessonSubject) - println(timeTableDay[i].lessonTeacher) - println(timeTableDay[i].lessonRoom) - } - println("-".padEnd(22, '-')) - println() - } -} \ No newline at end of file diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt new file mode 100644 index 0000000..63d90f2 --- /dev/null +++ b/src/main/kotlin/org/mosad/thecitadelofricks/DataTypes.kt @@ -0,0 +1,36 @@ +/** + * TheCitadelofRicks + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.thecitadelofricks + + +data class Course(val courseLink: String, val courseName: String) + +data class Meal(val day: String, val heading: String, val parts: ArrayList, val additives: String) + +data class MealWeek(val day: Array> = Array(7) { ArrayList() }) + +data class Lesson(val lessonSubject: String, val lessonTeacher: String, val lessonRoom:String, val lessonRemark: String) + +data class TimeTableDay( val timeslots: Array> = Array(6) { ArrayList()}) + +data class TimeTable(val days: Array = Array(6) { TimeTableDay() }) \ No newline at end of file diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/Main.kt b/src/main/kotlin/org/mosad/thecitadelofricks/Main.kt new file mode 100644 index 0000000..4a6059d --- /dev/null +++ b/src/main/kotlin/org/mosad/thecitadelofricks/Main.kt @@ -0,0 +1,40 @@ +/** + * TheCitadelofRicks + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.thecitadelofricks + +import org.mosad.thecitadelofricks.hsoparser.CourseListParser +import org.mosad.thecitadelofricks.hsoparser.TimeTableParser + + fun main() { + + // TESTING AREA + val courseLinks = CourseListParser().getCourseLinks() + println(courseLinks) + + val timeTableWeek0 = TimeTableParser().getTimeTable("https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=5D255C23-BC03-4AA0-9F36-DC6767F3E05D&week=0") + + val timeTableWeek1 = TimeTableParser().getTimeTable("https://www.hs-offenburg.de/index.php?id=6627&class=class&iddV=5D255C23-BC03-4AA0-9F36-DC6767F3E05D&week=1") + } + + + diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt new file mode 100644 index 0000000..1bbd94b --- /dev/null +++ b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/CourseListParser.kt @@ -0,0 +1,45 @@ +/** + * TheCitadelofRicks + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + + +package org.mosad.thecitadelofricks.hsoparser + +import org.jsoup.Jsoup +import org.mosad.thecitadelofricks.Course + +class CourseListParser { + + fun getCourseLinks(): ArrayList { + val courseTTLinkList = ArrayList() // TODO val may cause bugs! + val courseHTML = Jsoup.connect("https://www.hs-offenburg.de/studium/vorlesungsplaene/").get() + + courseHTML.select("ul.index-group").select("li.Class").select("a[href]").forEachIndexed { _, element -> + courseTTLinkList.add( + Course( + element.attr("href").replace("http", "https"), + element.text() + ) + ) + } + return courseTTLinkList + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/MensaParser.kt b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/MensaParser.kt new file mode 100644 index 0000000..87b64b8 --- /dev/null +++ b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/MensaParser.kt @@ -0,0 +1,86 @@ +/** + * TheCitadelofRicks + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.thecitadelofricks.hsoparser + +import org.jsoup.Jsoup +import org.mosad.thecitadelofricks.Meal +import org.mosad.thecitadelofricks.MealWeek + +class MensaParser { + + /** + * returns the mensa menu for the a week + */ + fun getMensaMenu(menuLink: String): MealWeek { + val mealList = ArrayList() + val mealWeekList = MealWeek() + val menuHTML = Jsoup.connect(menuLink).get() + + menuHTML.select("#speiseplan-tabs").select("div.tab-content").select("div.menu-tagesplan") + .forEachIndexed { dayIndex, day -> + val strDay = day.select("h3").text() + + + day.select("div.menu-info").forEachIndexed { mealIndex, meal -> + val heading = day.select("h4")[mealIndex].text() + val parts = ArrayList(meal.html().substringBefore("
\n").replace("
", " ").split("\n")) + val additives = meal.select("span.show-with-allergenes").text() + + mealWeekList.day[dayIndex].add(Meal(strDay, heading, parts, additives)) + } + + for (i in 0..(day.select("div.row h4").size - 1)) { + try { + val heading = day.select("div.row h4")[i].text() + val parts = ArrayList( + day.select("div.row").select("div.menu-info")[i].html().substringBefore("", + " " + ).split("\n") + ) + val additives = + day.select("div.row").select("div.menu-info")[i].select("span.show-with-allergenes").text() + + mealList.add(Meal(strDay, heading, parts, additives)) + } catch (e: Exception) { + //println("Oooups! Something went wrong: ${e.printStackTrace()}") + } + } + } + + // Mon to Sat (0 - 5) + println(mealWeekList.day[4]) + + return mealWeekList + } + + /** + * return the link of the menus of the next week + */ + fun getMenuLinkNextWeek(menuLink: String): String { + val menuHTML = Jsoup.connect(menuLink).get() + + return "https://www.swfr.de" + menuHTML.select("#speiseplan-tabs").select("a.next-week").attr("href") + } + +} \ No newline at end of file diff --git a/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimeTableParser.kt b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimeTableParser.kt new file mode 100644 index 0000000..766c7cd --- /dev/null +++ b/src/main/kotlin/org/mosad/thecitadelofricks/hsoparser/TimeTableParser.kt @@ -0,0 +1,145 @@ +/** + * TheCitadelofRicks + * + * Copyright 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + * + */ + +package org.mosad.thecitadelofricks.hsoparser + +import org.jsoup.Jsoup +import org.mosad.thecitadelofricks.Lesson +import org.mosad.thecitadelofricks.TimeTable + +class TimeTableParser { + private val days = arrayOf("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") + + /** + * get the timetable from the given url + * 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 getTimeTable(courseTTURL: String): TimeTable { + val timeTableWeek = TimeTable() + val scheduleHTML = Jsoup.connect(courseTTURL).get() + + //val week = scheduleHTML.select("h1.timetable-caption").text() + //println("$week successful!\n") + + val rows = scheduleHTML.select("table.timetable").select("tr[scope=\"row\"]") + var sDay = -1 + var sRow = -1 + var sLesson = Lesson("", "", "", "") + + // get each row with index, reflects 1 timeslot per day + for ((rowIndex, row) in rows.withIndex()) { + var day = 0 + + // elements are now all lessons, including empty ones + row.select("td.lastcol, td[style]").forEach { element -> + + // if there is a lecture with rowspan="2", we need to shift everything by one to the left. This is stupid and ugly there needs to bee an API + if ((sDay > -1 && sRow > -1) && (sDay == day && ((sRow + 1) == rowIndex))) { + // we found a lecture that is longer than 1 lesson + timeTableWeek.days[day].timeslots[rowIndex].add(sLesson) // this just works if there is one lecture per slot + + // adjust the following slot + sDay++ + sLesson = Lesson( + element.select("div.lesson-subject").text(), + element.select("div.lesson-teacher").text(), + element.select("div.lesson-room").text(), + element.select("div.lesson-remark").text() + ) + + // adjust the slot directly as we don't get there anymore + if (sDay == 5) { + timeTableWeek.days[day + 1].timeslots[rowIndex].add(sLesson) + } + + } else { + timeTableWeek.days[day].timeslots[rowIndex].add( + Lesson( + element.select("div.lesson-subject").text(), + element.select("div.lesson-teacher").text(), + element.select("div.lesson-room").text(), + element.select("div.lesson-remark").text() + ) + ) + } + + // we found a lecture with rowspan="2", save day, row and lesson for later adjustment + if (element.toString().contains("rowspan=\"2\"")) { + sDay = day + sRow = rowIndex + sLesson = timeTableWeek.days[day].timeslots[rowIndex].get(index = 0) + } + + if (element.hasClass("lastcol")) day++ + } + + } + + printTimeTableWeek(timeTableWeek) + + return timeTableWeek + } + + fun printTimeTableWeek(timetable: TimeTable) { + for (j in 0..5) print(days[j].padEnd(75, ' ') + " | ") + println() + for (j in 0..5) print("-".padEnd(76 + (j.toFloat().div(j).toInt()), '-') + "+") + println() + + // the timeslot + for (i in 0..5) { + + for (j in 0..5) { + val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size + + for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonSubject.padEnd(75 / ldiff, ' ')) + if (ldiff == 2) print(" ") + print(" | ") + } + println() + + for (j in 0..5) { + val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size + + for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonTeacher.padEnd(75 / ldiff, ' ')) + if (ldiff == 2) print(" ") + print(" | ") + } + println() + + for (j in 0..5) { + val ldiff = if (timetable.days[j].timeslots[i].size == 0) 1 else timetable.days[j].timeslots[i].size + + for (lesson in timetable.days[j].timeslots[i]) print(lesson.lessonRoom.padEnd(75 / ldiff, ' ')) + if (ldiff == 2) print(" ") + print(" | ") + } + println() + + for (j in 0..5) print("-".padEnd(76 + (j.toFloat().div(j).toInt()), '-') + "+") + println() + } + + println(" \n") + } +} \ No newline at end of file