summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/romjaki/dsbclient/DSBClient.java144
-rw-r--r--src/main/java/de/romjaki/dsbclient/TimetableEntry.java95
-rw-r--r--src/main/java/de/romjaki/dsbclient/UnUtil.java75
-rw-r--r--src/test/java/Testing.java14
4 files changed, 328 insertions, 0 deletions
diff --git a/src/main/java/de/romjaki/dsbclient/DSBClient.java b/src/main/java/de/romjaki/dsbclient/DSBClient.java
new file mode 100644
index 0000000..01927cd
--- /dev/null
+++ b/src/main/java/de/romjaki/dsbclient/DSBClient.java
@@ -0,0 +1,144 @@
+package de.romjaki.dsbclient;
+
+import com.google.common.collect.Iterables;
+import org.apache.http.HttpException;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+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.net.URISyntaxException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+public class DSBClient {
+ private static final String BASE_URL = "https://iphone.dsbcontrol.de/iPhoneService.svc/DSB/";
+ private static final String AUTH_URL = BASE_URL + "AuthID/";
+ private static final String DATA_URL = BASE_URL + "timetables/";
+ private static final DateFormat dateformat = new SimpleDateFormat("d.M.Y H:m");
+ private final String user;
+ private final String pass;
+ private String authid;
+ private DefaultHttpClient client = new DefaultHttpClient();
+ private Map<Long, List<TimetableEntry>> cache;
+
+ private DSBClient(String user, String pass) {
+ this.user = user;
+ this.pass = pass;
+ }
+
+ public static DSBClient buildBlocking(String user, String pass) throws HttpException, IOException, URISyntaxException, JSONException, ParseException {
+ DSBClient client = new DSBClient(user, pass);
+ client.login();
+ client.receiveData();
+ return client;
+ }
+
+ public static DSBClient buildAsync(String user, String pass, Consumer<Exception> exceptionCallback) {
+ DSBClient client = new DSBClient(user, pass);
+ Thread t = new Thread(() -> {
+ try {
+ client.login();
+ client.receiveData();
+ } catch (Exception e) {
+ exceptionCallback.accept(e);
+ }
+ });
+ return client;
+ }
+
+ private void login() throws IOException, HttpException, URISyntaxException {
+ HttpGet get = new HttpGet(AUTH_URL + user + "/" + pass);
+
+ HttpResponse response = client.execute(get);
+
+ authid = EntityUtils.toString(response.getEntity()).replace("\"", "");
+ }
+
+ private void receiveData() throws URISyntaxException, IOException, HttpException, JSONException, ParseException {
+ HttpGet get = new HttpGet(DATA_URL + authid);
+
+ HttpResponse response = client.execute(get);
+
+ String str = EntityUtils.toString(response.getEntity());
+ JSONArray data = new JSONArray(str);
+ cache = new HashMap<>();
+ for (int i = 0; i < data.length(); i++) {
+ JSONObject o = data.getJSONObject(i);
+ boolean isHtml = o.getBoolean("ishtml");
+ Date timetabledate = dateformat.parse(o.getString("timetabledate"));
+ String timetableurl = o.getString("timetableurl");
+ long millis = UnUtil.sanitizeDate(UnUtil.calendarByDate(timetabledate, Locale.GERMANY)).getTimeInMillis();
+ List<TimetableEntry> arrL = cache.computeIfAbsent(millis, ignored -> new ArrayList<>());
+ arrL.addAll(parseEntry(isHtml, timetableurl));
+ }
+ }
+
+
+ private List<TimetableEntry> parseEntry(boolean isHtml, String timetableurl) throws URISyntaxException, IOException, HttpException {
+ if (!isHtml) return Collections.emptyList();
+ HttpGet get = new HttpGet(timetableurl);
+ HttpResponse response = client.execute(get);
+ Document document = Jsoup.parse(EntityUtils.toString(response.getEntity()));
+ Elements rows = document.getElementsByTag("tr").not(":not(:has(th))");
+ List<TimetableEntry> entries = new ArrayList<>(rows.size());
+ for (Element row : rows) {
+ entries.add(parseElement(row));
+ }
+ return entries;
+ }
+
+ private TimetableEntry parseElement(Element row) {
+ TimetableEntry entry = new TimetableEntry();
+ entry.setKlasse(row.child(1).text());
+ entry.setStunde(row.child(3).text());
+ entry.setVertreter(row.child(4).text());
+ entry.setFach(row.child(5).text());
+ entry.setRaum(row.child(8).text());
+ entry.setArt(row.child(9).text());
+ entry.setText(row.child(11).text());
+ if (entry.getFach() == null) {
+ entry.setFach(row.child(6).text());
+ }
+ if (entry.getRaum() == null) {
+ entry.setRaum(row.child(7).text());
+ }
+ if (entry.getKlasse() == null) {
+ entry.setKlasse(row.child(10).text());
+ }
+ return entry;
+ }
+
+ public List<TimetableEntry> byTeacher(String teacher) {
+ return filter(timetableEntry -> timetableEntry.getVertreter().equalsIgnoreCase(teacher));
+ }
+
+ public List<TimetableEntry> byDate(Date date) {
+ return cache.get(UnUtil.sanitizeDate(UnUtil.calendarByDate(date, Locale.GERMANY)).getTimeInMillis());
+ }
+
+ public List<TimetableEntry> byClass(String klasse) {
+ return filter(timetableEntry -> timetableEntry.getKlasse().contains(klasse) || klasse.contains(timetableEntry.getKlasse()));
+ }
+
+
+ public List<TimetableEntry> filter(Predicate<TimetableEntry> predicate) {
+ return StreamSupport.stream(Iterables.concat(cache.values()).spliterator(), false)
+ .filter(predicate)
+ .collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/de/romjaki/dsbclient/TimetableEntry.java b/src/main/java/de/romjaki/dsbclient/TimetableEntry.java
new file mode 100644
index 0000000..a888cfc
--- /dev/null
+++ b/src/main/java/de/romjaki/dsbclient/TimetableEntry.java
@@ -0,0 +1,95 @@
+package de.romjaki.dsbclient;
+
+public class TimetableEntry {
+ private String klasse;
+ private String stunde;
+ private String vertreter;
+ private String fach;
+ private String raum;
+ private String art;
+ private String text;
+
+ public String getKlasse() {
+ return klasse;
+ }
+
+ public void setKlasse(String klasse) {
+ klasse = klasse.trim();
+ if (klasse.isEmpty()) {
+ klasse = null;
+ }
+ this.klasse = klasse;
+ }
+
+ public String getStunde() {
+ return stunde;
+ }
+
+ public void setStunde(String stunde) {
+ stunde = stunde.trim();
+ if (stunde.isEmpty()) {
+ stunde = null;
+ }
+ this.stunde = stunde;
+ }
+
+ public String getVertreter() {
+ return vertreter;
+ }
+
+ public void setVertreter(String vertreter) {
+ vertreter = vertreter.trim();
+ if (vertreter.isEmpty()) {
+ vertreter = null;
+ }
+ this.vertreter = vertreter;
+ }
+
+ public String getFach() {
+ return fach;
+ }
+
+ public void setFach(String fach) {
+ fach = fach.trim();
+ if (fach.isEmpty()) {
+ fach = null;
+ }
+ this.fach = fach;
+ }
+
+ public String getRaum() {
+ return raum;
+ }
+
+ public void setRaum(String raum) {
+ raum = raum.trim();
+ if (raum.isEmpty()) {
+ raum = null;
+ }
+ this.raum = raum;
+ }
+
+ public String getArt() {
+ return art;
+ }
+
+ public void setArt(String art) {
+ art = art.trim();
+ if (art.isEmpty()) {
+ art = null;
+ }
+ this.art = art;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public void setText(String text) {
+ text = text.trim();
+ if (text.isEmpty()) {
+ text = null;
+ }
+ this.text = text;
+ }
+}
diff --git a/src/main/java/de/romjaki/dsbclient/UnUtil.java b/src/main/java/de/romjaki/dsbclient/UnUtil.java
new file mode 100644
index 0000000..2c3af02
--- /dev/null
+++ b/src/main/java/de/romjaki/dsbclient/UnUtil.java
@@ -0,0 +1,75 @@
+package de.romjaki.dsbclient;
+
+
+import org.apache.http.NameValuePair;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+
+import static java.util.Calendar.*;
+
+public class UnUtil {
+
+ private UnUtil() {
+ UnUtil.singleton(UnUtil.class);
+ }
+
+ public static Calendar calendarByDate(Date date, Locale germany) {
+ Calendar calendar = Calendar.getInstance(Locale.GERMANY);
+ calendar.setTime(date);
+ return calendar;
+ }
+
+ public static Calendar sanitizeDate(Calendar temp) {
+ Calendar calendar = Calendar.getInstance(temp.getTimeZone());
+
+ calendar.set(
+ temp.get(YEAR),
+ temp.get(MONTH),
+ temp.get(DAY_OF_MONTH),
+ 0, 0, 0);
+ return calendar;
+ }
+
+ public static void singleton(Class<UnUtil> utilClass) throws IllegalStateException {
+ throw new IllegalStateException("No " + utilClass.getCanonicalName() + " class instances for you :P");
+ }
+
+ public static String httpGet(String urlString, Map<String, List<String>> headers) throws IOException {
+ return performGeneralHttpRequest("GET", urlString, headers);
+ }
+
+ public static String performGeneralHttpRequest(String method, String urlString, Map<String, List<String>> headers) throws IOException {
+ URL url = new URL(urlString);
+ HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod(method);
+ conn.getRequestProperties().putAll(headers);
+
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+ conn.setUseCaches(false);
+
+ InputStream stream = conn.getInputStream();
+ return readFully(stream);
+ }
+
+ public static UrlEncodedFormEntity createFormEntity(Map<String, String> params) {
+ List<NameValuePair> nameValuePairs = new ArrayList<>();
+ params.forEach((name, val) -> nameValuePairs.add(new BasicNameValuePair(name, val)));
+ try {
+ return new UrlEncodedFormEntity(nameValuePairs, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ return null;
+ }
+ }
+
+ public static String readFully(InputStream stream) {
+ return new Scanner(stream).useDelimiter("\\A").next();
+ }
+}
diff --git a/src/test/java/Testing.java b/src/test/java/Testing.java
new file mode 100644
index 0000000..b404e8d
--- /dev/null
+++ b/src/test/java/Testing.java
@@ -0,0 +1,14 @@
+import de.romjaki.dsbclient.DSBClient;
+import org.apache.http.HttpException;
+import org.json.JSONException;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.text.ParseException;
+
+public class Testing {
+ public static void main(String[] args) throws URISyntaxException, IOException, HttpException, JSONException, ParseException {
+ DSBClient client = DSBClient.buildBlocking("166162", "Riedberg2014");
+
+ }
+}