use of me.vertretungsplan.objects.Substitution in project substitution-schedule-parser by vertretungsplanme.
the class IndiwareParser method parseIndiwareDay.
SubstitutionScheduleDay parseIndiwareDay(Element doc, boolean html) throws IOException, JSONException {
SubstitutionScheduleDay day = new SubstitutionScheduleDay();
DataSource ds;
if (html) {
ds = new HTMLDataSource(doc);
} else {
ds = new XMLDataSource(doc);
}
Matcher matcher = datePattern.matcher(ds.titel().text());
if (!matcher.find())
throw new IOException("malformed date: " + ds.titel().text());
String date = matcher.group();
day.setDate(DateTimeFormat.forPattern("EEEE, dd. MMMM yyyy").withLocale(Locale.GERMAN).parseLocalDate(date));
matcher = lastChangePattern.matcher(ds.datum().text());
if (!matcher.find())
throw new IOException("malformed date: " + ds.datum().text());
String lastChange = matcher.group();
day.setLastChange(DateTimeFormat.forPattern("dd.MM.yyyy, HH:mm").withLocale(Locale.GERMAN).parseLocalDateTime(lastChange));
if (ds.kopfinfos().size() > 0) {
for (Element kopfinfo : ds.kopfinfos()) {
String title = html ? kopfinfo.select("th").text() : kopfinfoTitle(kopfinfo.tagName()) + ":";
StringBuilder message = new StringBuilder();
if (title != null && !title.isEmpty()) {
message.append("<b>").append(title).append("</b>").append(" ");
}
message.append(html ? kopfinfo.select("td").text() : kopfinfo.text());
day.addMessage(message.toString());
}
}
if (ds.fuss() != null) {
StringBuilder message = new StringBuilder();
boolean first = true;
for (Element fusszeile : ds.fusszeilen()) {
if (first) {
first = false;
} else {
message.append("<br>\n");
}
message.append(fusszeile.text());
}
day.addMessage(message.toString());
}
if (ds.aufsichten() != null) {
StringBuilder message = new StringBuilder();
message.append("<b>").append("GeƤnderte Aufsichten:").append("</b>");
for (Element aufsicht : ds.aufsichtzeilen()) {
message.append("<br>\n");
message.append(aufsicht.text());
}
day.addMessage(message.toString());
}
List<String> columnTypes = null;
if (html) {
columnTypes = new ArrayList<>();
for (Element th : ((HTMLDataSource) ds).headers()) {
Set<String> classNames = th.classNames();
for (String className : classNames) {
if (className.contains("thplan") || className.contains("thlplan")) {
columnTypes.add(className.replace("thplan", "").replace("thlplan", "").replace("_scheuler", // sic! -> http://www.hildebrand-gymnasium.de/index.php/klasse-5.html
""));
break;
}
}
}
}
for (Element aktion : ds.aktionen()) {
Substitution substitution = new Substitution();
String course = null;
int i = 0;
for (Element info : aktion.children()) {
String value = info.text().replace("\u00a0", "");
if (value.equals("---")) {
i++;
continue;
}
final String columnType = html ? columnTypes.get(i) : info.tagName();
switch(columnType) {
case "klasse":
ClassAndCourse cac = new ClassAndCourse(value, data);
course = cac.course;
substitution.setClasses(cac.classes);
break;
case "stunde":
substitution.setLesson(value);
break;
case "fach":
String subject = subjectAndCourse(course, value);
if (columnTypes != null && columnTypes.contains("vfach")) {
substitution.setPreviousSubject(subject);
} else {
substitution.setSubject(subject);
}
break;
case "vfach":
substitution.setSubject(subjectAndCourse(course, value));
case "lehrer":
Matcher bracesMatcher = bracesPattern.matcher(value);
if (bracesMatcher.matches()) {
value = bracesMatcher.group(1);
substitution.setPreviousTeachers(new HashSet<>(Arrays.asList(value.split(", "))));
} else {
substitution.setTeachers(new HashSet<>(Arrays.asList(value.split(", "))));
}
break;
case "raum":
if (columnTypes != null && columnTypes.contains("vraum")) {
substitution.setPreviousRoom(value);
} else {
substitution.setRoom(value);
}
break;
case "vraum":
substitution.setRoom(value);
case "info":
handleDescription(substitution, value);
break;
}
i++;
}
if (substitution.getType() == null)
substitution.setType("Vertretung");
substitution.setColor(colorProvider.getColor(substitution.getType()));
if (course != null && substitution.getSubject() == null) {
substitution.setSubject(course);
}
day.addSubstitution(substitution);
}
return day;
}
use of me.vertretungsplan.objects.Substitution in project substitution-schedule-parser by vertretungsplanme.
the class LegionBoardParser method parseLegionBoard.
void parseLegionBoard(SubstitutionSchedule substitutionSchedule, JSONArray changes, JSONArray courses, JSONArray teachers) throws IOException, JSONException {
if (changes == null) {
return;
}
// Link course IDs to their names
HashMap<String, String> coursesHashMap = null;
if (courses != null) {
coursesHashMap = new HashMap<>();
for (int i = 0; i < courses.length(); i++) {
JSONObject course = courses.getJSONObject(i);
coursesHashMap.put(course.getString("id"), course.getString("name"));
}
}
// Link teacher IDs to their names
HashMap<String, String> teachersHashMap = null;
if (teachers != null) {
teachersHashMap = new HashMap<>();
for (int i = 0; i < teachers.length(); i++) {
JSONObject teacher = teachers.getJSONObject(i);
teachersHashMap.put(teacher.getString("id"), teacher.getString("name"));
}
}
// Add changes to SubstitutionSchedule
LocalDate currentDate = LocalDate.now();
SubstitutionScheduleDay substitutionScheduleDay = new SubstitutionScheduleDay();
substitutionScheduleDay.setDate(currentDate);
for (int i = 0; i < changes.length(); i++) {
final JSONObject change = changes.getJSONObject(i);
final Substitution substitution = getSubstitution(change, coursesHashMap, teachersHashMap);
final LocalDate startingDate = new LocalDate(change.getString("startingDate"));
final LocalDate endingDate = new LocalDate(change.getString("endingDate"));
// Handle multi-day changes
if (!startingDate.isEqual(endingDate)) {
if (!substitutionScheduleDay.getSubstitutions().isEmpty()) {
substitutionSchedule.addDay(substitutionScheduleDay);
}
for (int k = 0; k < 8; k++) {
final LocalDate date = LocalDate.now().plusDays(k);
if ((date.isAfter(startingDate) || date.isEqual(startingDate)) && (date.isBefore(endingDate) || date.isEqual(endingDate))) {
substitutionScheduleDay = new SubstitutionScheduleDay();
substitutionScheduleDay.setDate(date);
substitutionScheduleDay.addSubstitution(substitution);
substitutionSchedule.addDay(substitutionScheduleDay);
currentDate = date;
}
}
continue;
}
// If starting date of change does not equal date of SubstitutionScheduleDay
if (!startingDate.isEqual(currentDate)) {
if (!substitutionScheduleDay.getSubstitutions().isEmpty()) {
substitutionSchedule.addDay(substitutionScheduleDay);
}
substitutionScheduleDay = new SubstitutionScheduleDay();
substitutionScheduleDay.setDate(startingDate);
currentDate = startingDate;
}
substitutionScheduleDay.addSubstitution(substitution);
}
substitutionSchedule.addDay(substitutionScheduleDay);
}
use of me.vertretungsplan.objects.Substitution in project substitution-schedule-parser by vertretungsplanme.
the class LegionBoardParser method getSubstitution.
private Substitution getSubstitution(JSONObject change, HashMap<String, String> coursesHashMap, HashMap<String, String> teachersHashMap) throws IOException, JSONException {
final Substitution substitution = new Substitution();
// Set class
final String classId = change.getString("course");
if (!classId.equals("0")) {
if (coursesHashMap == null) {
throw new IOException("Change references a course but courses are empty.");
}
final String singleClass = coursesHashMap.get(classId);
final HashSet<String> classes = new HashSet<>();
classes.add(singleClass);
substitution.setClasses(classes);
}
// Set type
String type = "Unknown";
switch(change.getString("type")) {
case "0":
type = "Entfall";
break;
case "1":
type = "Vertretung";
break;
case "2":
type = "Information";
break;
}
substitution.setType(type);
// Set color
substitution.setColor(colorProvider.getColor(type));
// Set covering teacher
final String coveringTeacherId = change.getString("coveringTeacher");
if (!coveringTeacherId.equals("0")) {
if (teachersHashMap == null) {
throw new IOException("Change references a covering teacher but teachers are empty.");
}
if (!teachersHashMap.get(coveringTeacherId).equals("-")) {
substitution.setTeacher(teachersHashMap.get(coveringTeacherId));
}
}
// Set teacher
final String teacherId = change.getString("teacher");
if (!teacherId.equals("0")) {
if (teachersHashMap == null) {
throw new IOException("Change references a teacher but teachers are empty.");
}
if (!teachersHashMap.get(teacherId).equals("-")) {
if (type.equals("Vertretung") || substitution.getTeacher() != null) {
substitution.setPreviousTeacher(teachersHashMap.get(teacherId));
} else {
substitution.setTeacher(teachersHashMap.get(teacherId));
}
}
}
// Set description
substitution.setDesc(change.getString("text"));
// Set lesson
final String startingHour = change.getString("startingHour").replaceFirst("^0+(?!$)", "");
final String endingHour = change.getString("endingHour").replaceFirst("^0+(?!$)", "");
if (!startingHour.equals("") || !endingHour.equals("")) {
String lesson = "";
if (!startingHour.equals("") && endingHour.equals("")) {
lesson = "Ab " + startingHour;
}
if (startingHour.equals("") && !endingHour.equals("")) {
lesson = "Bis " + endingHour;
}
if (!startingHour.equals("") && !endingHour.equals("")) {
if (startingHour.equals(endingHour)) {
lesson = startingHour;
} else {
lesson = startingHour + " - " + endingHour;
}
}
substitution.setLesson(lesson);
}
return substitution;
}
use of me.vertretungsplan.objects.Substitution in project substitution-schedule-parser by vertretungsplanme.
the class ESchoolParser method parseTable.
private void parseTable(Element table, SubstitutionScheduleDay day) {
for (Element th : table.select("th[colspan=10]")) {
String lesson;
Pattern pattern = Pattern.compile("(\\d+)\\. Stunde");
Matcher matcher = pattern.matcher(th.text());
if (matcher.find()) {
lesson = matcher.group(1);
} else {
lesson = th.text();
}
// skip over table headers
Element row = th.parent().nextElementSibling().nextElementSibling();
while (row != null && row.select("th").size() == 0) {
Substitution subst = new Substitution();
subst.setLesson(lesson);
Elements columns = row.select("td");
String[] classes = columns.get(0).text().split(", |\\+");
subst.setClasses(new HashSet<>(Arrays.asList(classes)));
subst.setPreviousTeacher(getPreviousValue(columns.get(1)));
subst.setTeacher(getNewValue(columns.get(1)));
subst.setPreviousSubject(getPreviousValue(columns.get(2)));
subst.setSubject(getNewValue(columns.get(2)));
subst.setPreviousRoom(getPreviousValue(columns.get(3)));
subst.setRoom(getNewValue(columns.get(3)));
if (columns.get(4).text().isEmpty()) {
subst.setType("Vertretung");
subst.setColor(colorProvider.getColor("Vertretung"));
} else {
String desc = columns.get(4).text();
subst.setDesc(desc);
String recognizedType = recognizeType(desc);
if (recognizedType == null)
recognizedType = "Vertretung";
subst.setType(recognizedType);
subst.setColor(colorProvider.getColor(recognizedType));
}
day.addSubstitution(subst);
row = row.nextElementSibling();
}
}
}
use of me.vertretungsplan.objects.Substitution in project substitution-schedule-parser by vertretungsplanme.
the class SubstitutionScheduleDayDiff method compare.
public static SubstitutionScheduleDayDiff compare(SubstitutionScheduleDay a, SubstitutionScheduleDay b) {
if (!a.equalsByDate(b)) {
throw new IllegalArgumentException("Days must have the same date");
}
SubstitutionScheduleDayDiff diff = new SubstitutionScheduleDayDiff();
diff.date = a.getDate();
diff.dateString = a.getDateString();
diff.newMessages = new ArrayList<>();
diff.removedMessages = new ArrayList<>();
diff.newSubstitutions = new HashSet<>();
diff.editedSubstitutions = new HashSet<>();
diff.removedSubstitutions = new HashSet<>();
for (String message : b.getMessages()) {
if (!a.getMessages().contains(message)) {
diff.newMessages.add(message);
}
}
for (String message : a.getMessages()) {
if (!b.getMessages().contains(message)) {
diff.removedMessages.add(message);
}
}
// save all old substitutions that were already handled here to speed up the second run
Set<Substitution> handledOldSubstitutions = new HashSet<>();
// first run: go through all new substitutions and search for matching old substitutions
for (Substitution newSubstitution : b.getSubstitutions()) {
if (a.getSubstitutions().contains(newSubstitution)) {
// this substitution has not changed in any way
handledOldSubstitutions.add(newSubstitution);
continue;
}
Substitution oldSubstitution = findEqualSubtitutionExcludingClasses(newSubstitution, a.getSubstitutions(), handledOldSubstitutions);
if (oldSubstitution != null) {
// The same substitution was already there, but the set of classes has changed
Set<String> newClasses = new HashSet<>();
for (String currentClass : newSubstitution.getClasses()) {
if (!oldSubstitution.getClasses().contains(currentClass)) {
newClasses.add(currentClass);
}
}
if (!newClasses.isEmpty()) {
diff.newSubstitutions.add(new Substitution(newSubstitution, newClasses));
}
Set<String> removedClasses = new HashSet<>();
for (String currentClass : oldSubstitution.getClasses()) {
if (!newSubstitution.getClasses().contains(currentClass)) {
removedClasses.add(currentClass);
}
}
if (!removedClasses.isEmpty()) {
diff.removedSubstitutions.add(new Substitution(newSubstitution, removedClasses));
}
handledOldSubstitutions.add(oldSubstitution);
continue;
}
oldSubstitution = findSimilarSubstitution(newSubstitution, a.getSubstitutions(), handledOldSubstitutions);
if (oldSubstitution != null) {
// there is a similar substitution, create a SubstitutionDiff
SubstitutionDiff substitutionDiff = SubstitutionDiff.compare(oldSubstitution, newSubstitution);
// Only use the diff if its complexity is low enough. Otherwise, regard this as a new substitution.
if (substitutionDiff.getComplexity() <= SubstitutionDiff.MAX_COMPLEXITY) {
diff.editedSubstitutions.add(substitutionDiff);
handledOldSubstitutions.add(oldSubstitution);
continue;
}
}
// There seems to be no matching substitution, so this is new
diff.newSubstitutions.add(newSubstitution);
}
// second run: go through all unhandled old substitutions -> they must have been removed
for (Substitution oldSubstitution : a.getSubstitutions()) {
if (!handledOldSubstitutions.contains(oldSubstitution)) {
diff.removedSubstitutions.add(oldSubstitution);
}
}
return diff;
}
Aggregations