All Downloads are FREE. Search and download functionalities are using the official Maven repository.

me.vertretungsplan.parser.IndiwareMobileParser Maven / Gradle / Ivy

Go to download

Java library for parsing schools' substitution schedules. Supports multiple different systems mainly used in the German-speaking countries.

There is a newer version: 1.0.0-beta356
Show newest version
/*
 * substitution-schedule-parser - Java library for parsing schools' substitution schedules
 * Copyright (c) 2017 Johan v. Forstner
 *
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

package me.vertretungsplan.parser;

import me.vertretungsplan.exception.CredentialInvalidException;
import me.vertretungsplan.objects.Substitution;
import me.vertretungsplan.objects.SubstitutionSchedule;
import me.vertretungsplan.objects.SubstitutionScheduleData;
import me.vertretungsplan.objects.SubstitutionScheduleDay;
import org.apache.http.client.HttpResponseException;
import org.jetbrains.annotations.NotNull;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

/**
 * Parser for the mobile version of substitution schedules created with the Indiware
 * software.
 * 

* This parser can be accessed using "indiware-mobile" for {@link SubstitutionScheduleData#setApi(String)}. * *

Configuration parameters

* These parameters can be supplied in {@link SubstitutionScheduleData#setData(JSONObject)} to configure the parser: * *
*
baseurl (Array of Strings, required)
*
Base URL of the Indiware mobile schedule.
* *
* * Additionally, this parser supports the parameters specified in {@link LoginHandler} for login-protected schedules. */ public class IndiwareMobileParser extends BaseParser { private static final String PARAM_BASEURL = "baseurl"; private static final int MAX_DAYS = 7; private JSONObject data; public IndiwareMobileParser(SubstitutionScheduleData scheduleData, CookieProvider cookieProvider) { super(scheduleData, cookieProvider); data = scheduleData.getData(); } @Override public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONException, CredentialInvalidException { new LoginHandler(scheduleData, credential, cookieProvider).handleLogin(executor, cookieStore); String baseurl = data.getString(PARAM_BASEURL) + "/"; List docs = new ArrayList<>(); HttpResponseException lastException = null; for (int i = 0; i < MAX_DAYS; i++) { LocalDate date = LocalDate.now().plusDays(i); String dateStr = DateTimeFormat.forPattern("yyyyMMdd").print(date); String filePrefix = scheduleData.getType() == SubstitutionSchedule.Type.TEACHER ? "PlanLe" : "PlanKl"; String url = baseurl + "mobdaten/" + filePrefix + dateStr + "" + ".xml?_=" + System.currentTimeMillis(); try { String xml = httpGet(url, "UTF-8"); Document doc = Jsoup.parse(xml, url, Parser.xmlParser()); if (doc.select("kopf datei").text().equals(filePrefix + dateStr + ".xml")) { docs.add(doc); } } catch (HttpResponseException e) { lastException = e; } } if (docs.size() == 0 && lastException != null) { throw lastException; } SubstitutionSchedule v = SubstitutionSchedule.fromData(scheduleData); for (Document doc:docs) { v.addDay(parseDay(doc, colorProvider, scheduleData)); } v.setClasses(getAllClasses()); v.setTeachers(getAllTeachers()); v.setWebsite(baseurl + "plankl.html"); return v; } static SubstitutionScheduleDay parseDay(Document doc, ColorProvider colorProvider, SubstitutionScheduleData scheduleData) { SubstitutionScheduleDay day = new SubstitutionScheduleDay(); day.setDate(ParserUtils.parseDate(doc.select("Kopf > DatumPlan").text())); day.setLastChange(ParserUtils.parseDateTime(doc.select("Kopf > Zeitstempel").text())); for (Element klasse:doc.select("Klassen > Kl")) { String className = klasse.select("Kurz").first().text(); HashSet classes = new HashSet<>(); classes.add(className); for (Element lesson:klasse.select("Pl > Std")) { if (lesson.select("If:not(:empty), Le[LeAe], Ra[RaAe], Fa[FaAe]").size() == 0) { continue; } Substitution subst = new Substitution(); subst.setLesson(text(lesson.select("St"))); if (scheduleData.getType() == SubstitutionSchedule.Type.STUDENT) { subst.setTeachers(split(text(lesson.select("Le")))); subst.setClasses(classes); } else { subst.setClasses(split(text(lesson.select("Le")))); subst.setTeachers(classes); } subst.setSubject(text(lesson.select("Fa"))); subst.setRoom(text(lesson.select("Ra"))); IndiwareParser.handleDescription(subst, text(lesson.select("If")), scheduleData.getType() == SubstitutionSchedule.Type.TEACHER); if (subst.getType() == null) subst.setType("Vertretung"); subst.setColor(colorProvider.getColor(subst.getType())); day.addSubstitution(subst); } } for (Element info:doc.select("ZusatzInfo > ZiZeile")) { day.getMessages().add(info.text()); } return day; } @NotNull private static HashSet split(String text) { if (text != null) { return new HashSet<>(Arrays.asList(text.split(","))); } else { return new HashSet<>(); } } private static String text(Elements elem) { String text = elem.text().replace(" ", "").trim(); if (!text.isEmpty()) { return text; } else { return null; } } @Override public List getAllClasses() throws IOException, JSONException, CredentialInvalidException { if (scheduleData.getType() == SubstitutionSchedule.Type.STUDENT) { return parseClasses("PlanKl"); } else { return new ArrayList<>(); } } @NotNull private List parseClasses(String filePrefix) throws JSONException, IOException, CredentialInvalidException { String baseurl = data.getString(PARAM_BASEURL) + "/"; HttpResponseException lastException = null; for (int i = -4; i < MAX_DAYS; i++) { LocalDate date = LocalDate.now().plusDays(i); String dateStr = DateTimeFormat.forPattern("yyyyMMdd").print(date); String url = baseurl + "mobdaten/" + filePrefix + dateStr + ".xml?_=" + System.currentTimeMillis(); try { String xml = httpGet(url, "UTF-8"); Document doc = Jsoup.parse(xml, url, Parser.xmlParser()); List classes = new ArrayList<>(); for (Element klasse:doc.select("Klassen > Kl")) { classes.add(klasse.select("Kurz").first().text()); } return classes; } catch (HttpResponseException e) { lastException = e; } } if (lastException != null) { throw lastException; } else { return new ArrayList<>(); } } @Override public List getAllTeachers() throws IOException, JSONException, CredentialInvalidException { if (scheduleData.getType() == SubstitutionSchedule.Type.TEACHER) { return parseClasses("PlanLe"); } else { return null; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy