de.berstanio.ghgparser.JahresStundenPlan Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ghgsek2dsbparser Show documentation
Show all versions of ghgsek2dsbparser Show documentation
Fetching and parsing DSB plan for GHG
package de.berstanio.ghgparser;
import org.json.JSONArray;
import org.json.JSONObject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.stream.Collectors;
/**
* Representiert den "Standart-Stundenplan", wie er ohne Änderung wäre
*/
public class JahresStundenPlan extends Plan {
//Eine Liste von möglich wählbaren Kursen
private ArrayList coreCourses;
private static final long serialVersionUID = -2671162280384342988L;
public JahresStundenPlan(int year) throws DSBNotLoadableException {
super(year,0);
}
/**
* Lädt den Plan neu
* @return Ob es ein Update gab, als boolean
* @throws DSBNotLoadableException Wenn keine Verbindung zum DSB hergestellt werden kann
*/
@Override
public boolean refresh() throws DSBNotLoadableException {
boolean b = super.refresh();
if (b || getCoreCourses() == null){
//Wenn die DayListMap neu geladen wurde, auch die CoreCourses neu laden
setCoreCourses(loadCoreCourses());
}
return b;
}
/**
* Extrahiert alle wählbaren Kurse aus der dayListMap
* @return Liste der wählbaren Kurse
*/
public ArrayList loadCoreCourses(){
//Erstmal den Plan im Standardformat holen
HashMap> dayListMap = getDayListMap();
//Die Struktur des HTMLs mit den Stundenplan unterscheidet scih ein wenig. Bei dem einen kommt "Raum", "Fach","Lehrer"
//bei dem anderen lehrer, Fach, Raum. Deshalb müssen Lehrer und Raum hier getauscht werden
ArrayList alreadySwapped = new ArrayList<>();
dayListMap.values().forEach(blocks -> {
blocks.forEach(block -> {
block.getCourses().removeIf(course -> {
if (!alreadySwapped.contains(course)){
String room = course.getRoom();
course.setRoom(course.getTeacher());
course.setTeacher(room);
alreadySwapped.add(course);
}
return course.getTeacher().isEmpty() && course.getRoom().isEmpty();
});
});
});
//Kurse, die ich schon hinzugefügt habe(z.B. Kurse die über 2 Stunden gehen, sind 2x drin)
ArrayList alreadyAdd = new ArrayList<>();
//Die generierten Wählbaren Kurse
ArrayList finished = new ArrayList<>();
//Über alles rüberiterieren
for (DayOfWeek day : dayListMap.keySet().stream().sorted().collect(Collectors.toList())) {
LinkedList blocks = dayListMap.get(day);
for (Block block : blocks) {
for (Course course : block.getCourses()) {
//Die duplicates Liste besagt, welche Kurse zusammengehören
LinkedList duplicates = new LinkedList<>();
if (alreadyAdd.contains(course)) continue;
duplicates.add(course);
alreadyAdd.add(course);
//Geht nochmal über die gesammte Liste rüber und schaut, was für duplicate er findet(ziemlich Perfomancelastig glaube ich)
dayListMap.values().forEach(blocksDup -> {
blocksDup.forEach(blockDup -> {
blockDup.getCourses().forEach(courseDup -> {
if (!courseDup.equals(course)) {
if (courseDup.getCourseName().equalsIgnoreCase(course.getCourseName())) {
if (courseDup.getTeacher().equalsIgnoreCase(course.getTeacher())) {
duplicates.add(courseDup);
alreadyAdd.add(courseDup);
}
}
}
});
});
});
//Wir haben dämliche Einzelfälle, in denen Stunden nicht zu einem Kurs gehören... Die müssen dann getrennt werden.
if (course.getCourseName().contains("-vb") || course.getCourseName().contains("DELF")) {
duplicates.forEach(course1 -> {
CoreCourse coreCourse = new CoreCourse();
coreCourse.setCourseName(course.getCourseName());
coreCourse.setTeacher(course.getTeacher());
coreCourse.getCourses().add(course1);
finished.add(coreCourse);
});
continue;
}
if (!(duplicates.size() % 2 == 0 && duplicates.size() >= 4)) {
if (!course.getTeacher().isEmpty()) {
CoreCourse coreCourse = new CoreCourse();
coreCourse.setCourseName(course.getCourseName());
coreCourse.setTeacher(course.getTeacher());
coreCourse.getCourses().addAll(duplicates);
finished.add(coreCourse);
}
} else {
while (duplicates.size() != 0) {
CoreCourse coreCourse = new CoreCourse();
coreCourse.setCourseName(course.getCourseName());
coreCourse.setTeacher(course.getTeacher());
Course firstOrSecond;
Course base = duplicates.get(0);
Block baseBlock = dayListMap.get(base.getDay()).get(base.getLesson() - 1);
//Um die verschiedenen Kurse zu unterschieden muss man schauen, was für Kurse sonst noch gleichzeitig laufen
//Also der eine gkMa hat immer mit dem gleichen gkPhy Unterricht
//Deshalb schaue ich mir den 1. oder 2. gleichzeitig laufenden Kurs an und vergleiche das dann.
//(den 2. nehme ich, falls) der Kurs als erstes ist, zu dem ich gerade den Partner suche.
//Also der eine gkMa hat immer mit dem gleichen gkPhy Unterricht
//Deshalb schaue ich mir den 1. oder 2. gleichzeitig laufenden Kurs an und vergleiche das dann.
//(den 2. nehme ich, falls) der Kurs als erstes ist, zu dem ich gerade den Partner suche.
int i = 0;
if (baseBlock.getCourses().indexOf(base) == 0){
i = 1;
}
firstOrSecond = baseBlock.getCourses().get(i);
for (Course check : duplicates) {
if (check.equals(base)) continue;
Course tmp = dayListMap.get(check.getDay()).get(check.getLesson() - 1).getCourses().get(i);
if (tmp.getCourseName().equals(firstOrSecond.getCourseName())) {
if (tmp.getTeacher().equals(firstOrSecond.getTeacher())) {
coreCourse.getCourses().add(base);
coreCourse.getCourses().add(check);
finished.add(coreCourse);
break;
}
}
}
duplicates.removeAll(coreCourse.getCourses());
}
}
}
}
}
return finished;
}
/**
* Extrahiert aus einem JSON-Array das Datum des letzten Plan-Updates
* @param array Das JSON-Array
* @return Das Datum des letzten Plan-Updates als java.util.Date
*/
@Override
public Date getUpdateDate(JSONArray array) throws ParseException {
JSONObject object = (JSONObject) array.get(1);
String date = (String) object.get("Date");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy kk:mm");
return simpleDateFormat.parse(date);
}
/**
* Extrahiert aus einem JSON-Array den Token des Plans
* @param array Das JSON-Array
* @return Der Token als String
*/
@Override
public String loadToken(JSONArray array) throws DSBNotLoadableException {
// We need this for loop because android replaces the json api with a already provided one where JSONArray doesn't implement Iterable
// https://stackoverflow.com/questions/57274183/android-issue-using-json-library-in-pure-java-package
for (int i = 0; i < array.length(); i++) {
Object object = array.get(i);
if (object instanceof JSONObject) {
JSONObject jsonObject = (JSONObject) object;
if (jsonObject.get("Title").toString().contains("Jahresstundenplan")) {
return (String) jsonObject.get("Id");
}
}
}
throw new DSBNotLoadableException("Can't load token for JSP from string: " + array);
}
/**
* Gibt die Kalenderwoche zurück, in der sich der allgemeine Plan befindet
* @return Die Kalenderwoche als int, in der sich der allgemeine Plan befindet
*/
@Override
public int getWeek(){
try {
JSONObject s = getDataJSAsJSONObject();
JSONObject weeks = s.getJSONObject("weeks");
int week = Integer.parseInt(weeks.keys().next());
return week;
}catch (DSBNotLoadableException e){
e.printStackTrace();
return 0;
}
}
/**
* Gibt die Liste aller wählbaren Kurse zurück
* @return Die Liste aller wählbaren Kurse
*/
public ArrayList getCoreCourses() {
return coreCourses;
}
/**
* Setzt die Liste aller wählbaren Kurse
* @param coreCourses Die Liste aller wählbaren Kurse
*/
public void setCoreCourses(ArrayList coreCourses) {
this.coreCourses = coreCourses;
}
}