me.vertretungsplan.parser.UntisSubstitutionParser Maven / Gradle / Ivy
/*
* substitution-schedule-parser - Java library for parsing schools' substitution schedules
* Copyright (c) 2016 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.SubstitutionSchedule;
import me.vertretungsplan.objects.SubstitutionScheduleData;
import org.apache.http.client.HttpResponseException;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.json.JSONArray;
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.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Parser for substitution schedules in HTML format created by the Untis software
* using the "Vertretungsplanung" layout.
*
* Example: JKG Stuttgart
*
* This parser can be accessed using "untis-substitution"
for
* {@link SubstitutionScheduleData#setApi(String)}.
*
*
Configuration parameters
* These parameters can be supplied in {@link SubstitutionScheduleData#setData(JSONObject)} to configure the parser:
*
*
* baseurl
(String, required if urls
not specified)
* - The URL of the home page of the substitution schedule where the selection of classes is found. If the URL
* contains the date, you can use something like
{date(yyyy-MM-dd)}
in the URL. This placeholder will then
* be replaced with the dates of the next 7 days.
*
* urls
(Array of strings, required if baseurl
not specified)
* - The URLs of the home pages of the substitution schedule where the selection of classes is found. If the URL
* contains the date, you can use something like
{date(yyyy-MM-dd)}
in the URL. This placeholder will then
* be replaced with the dates of the next 7 days.
*
* encoding
(String, required)
* - The charset of the XML files. It's probably either UTF-8 or ISO-8859-1.
*
* columns
(Array of Strings, required)
* - As defined in {@link UntisCommonParser}, but additionally supports
"columns"
as a column type.
*
* classes
(Array of Strings, required)
* - The list of all classes, as they can appear in the schedule
*
* website
(String, recommended)
* - The URL of a website where the substitution schedule can be seen online
*
*
* Additionally, this parser supports the parameters specified in {@link LoginHandler} for login-protected schedules
* and those specified in {@link UntisCommonParser}.
*/
public class UntisSubstitutionParser extends UntisCommonParser {
private static final String PARAM_BASEURL = "baseurl";
private static final String PARAM_URLS = "urls";
private static final String PARAM_ENCODING = "encoding";
private static final String PARAM_WEBSITE = "website";
private List urls;
private JSONObject data;
public UntisSubstitutionParser(SubstitutionScheduleData scheduleData, CookieProvider cookieProvider) {
super(scheduleData, cookieProvider);
try {
data = scheduleData.getData();
urls = new ArrayList<>();
if (data.has(PARAM_BASEURL)) {
urls.add(data.getString(PARAM_BASEURL));
} else {
JSONArray urlsArray = data.getJSONArray(PARAM_URLS);
for (int i = 0; i < urlsArray.length(); i++) {
urls.add(urlsArray.getString(i));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public SubstitutionSchedule getSubstitutionSchedule() throws IOException,
JSONException, CredentialInvalidException {
new LoginHandler(scheduleData, credential, cookieProvider).handleLogin(executor, cookieStore);
String encoding = data.optString(PARAM_ENCODING, null);
SubstitutionSchedule v = SubstitutionSchedule.fromData(scheduleData);
int successfulSchedules = 0;
HttpResponseException lastExceptionSchedule = null;
for (String baseUrl:ParserUtils.handleUrlsWithDateFormat(urls)) {
try {
Document doc = Jsoup.parse(this.httpGet(baseUrl, encoding));
Elements classes = doc.select("td a");
String lastChange = doc.select("td[align=right]:not(:has(b))").text();
int successfulClasses = 0;
HttpResponseException lastExceptionClass = null;
for (Element klasse : classes) {
try {
Document classDoc = Jsoup.parse(httpGet(baseUrl.substring(0, baseUrl.lastIndexOf("/"))
+ "/" + klasse.attr("href"), encoding));
parseSubstitutionTable(v, lastChange, classDoc, klasse.text());
successfulClasses++;
} catch (HttpResponseException e) {
lastExceptionClass = e;
}
}
if (successfulClasses == 0 && lastExceptionClass != null) {
throw lastExceptionClass;
}
successfulSchedules ++;
} catch (HttpResponseException e) {
lastExceptionSchedule = e;
}
}
if (successfulSchedules == 0 && lastExceptionSchedule != null) {
throw lastExceptionSchedule;
}
if (data.has(PARAM_WEBSITE)) {
v.setWebsite(data.getString(PARAM_WEBSITE));
} else {
v.setWebsite(urls.get(0));
}
v.setClasses(getAllClasses());
v.setTeachers(getAllTeachers());
return v;
}
@Override
public List getAllTeachers() {
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy