diff --git a/src/de/schildbach/pte/NasaProvider.java b/src/de/schildbach/pte/NasaProvider.java index 131eb1ec..cb96dc0e 100644 --- a/src/de/schildbach/pte/NasaProvider.java +++ b/src/de/schildbach/pte/NasaProvider.java @@ -18,23 +18,12 @@ package de.schildbach.pte; import java.io.IOException; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Collections; -import java.util.GregorianCalendar; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import de.schildbach.pte.dto.Departure; -import de.schildbach.pte.dto.Line; import de.schildbach.pte.dto.Location; import de.schildbach.pte.dto.LocationType; import de.schildbach.pte.dto.NearbyStationsResult; import de.schildbach.pte.dto.QueryDeparturesResult; -import de.schildbach.pte.dto.QueryDeparturesResult.Status; -import de.schildbach.pte.dto.StationDepartures; -import de.schildbach.pte.util.ParserUtils; /** * @author Andreas Schildbach @@ -45,8 +34,6 @@ public class NasaProvider extends AbstractHafasProvider public static final String OLD_NETWORK_ID = "www.nasa.de"; private static final String API_BASE = "http://reiseauskunft.insa.de/bin/"; - private static final long PARSER_DAY_ROLLOVER_THRESHOLD_MS = 12 * 60 * 60 * 1000; - public NasaProvider() { super(API_BASE + "query.exe/dn", 8, null); @@ -119,158 +106,19 @@ public class NasaProvider extends AbstractHafasProvider } } - private String departuresQueryUri(final int stationId, final int maxDepartures) - { - final StringBuilder uri = new StringBuilder(); - - uri.append(API_BASE).append("stboard.exe/dn"); - uri.append("?input=").append(stationId); - uri.append("&boardType=dep"); - uri.append("&productsFilter=").append(allProductsString()); - if (maxDepartures != 0) - uri.append("&maxJourneys=").append(maxDepartures); - uri.append("&disableEquivs=yes"); // don't use nearby stations - uri.append("&start=yes"); - - return uri.toString(); - } - - private static final Pattern P_DEPARTURES_HEAD_COARSE = Pattern - .compile( - ".*?" // - + "(?:" // - + "]*>(.+?)
.*?" // - + "(?:]*>(.+?)
|(verkehren an dieser Haltestelle keine))"// - + "|(Eingabe kann nicht interpretiert)|(Verbindung zum Server konnte leider nicht hergestellt werden|kann vom Server derzeit leider nicht bearbeitet werden))" // - + ".*?" // - , Pattern.DOTALL); - private static final Pattern P_DEPARTURES_HEAD_FINE = Pattern.compile(".*?" // - + "\\s*(.*?)\\s*<.*?" // location - + "(\\d{2}\\.\\d{2}\\.\\d{2}).*?" // date - + "Abfahrt (\\d{1,2}:\\d{2}).*?" // time - , Pattern.DOTALL); - private static final Pattern P_DEPARTURES_COARSE = Pattern.compile("(.*?)", Pattern.DOTALL); - private static final Pattern P_DEPARTURES_FINE = Pattern.compile(".*?" // - + "(\\d{1,2}:\\d{2})\n" // plannedTime - + "(?:\n" // - + "(?: |(pünktlich|\\d{1,2}:\\d{2}))\n\n" // predictedTime - + ")?.*?" // - + "]*>\\s*(.*?)\\s*\n" // - + "]*>" // destinationId - + "\\s*(.*?)\\s*\n" // destination - + ".*?" // - + "(?:\n(" + ParserUtils.P_PLATFORM + ").*?)?" // position - , Pattern.DOTALL); - public QueryDeparturesResult queryDepartures(final int stationId, final int maxDepartures, final boolean equivs) throws IOException { - final QueryDeparturesResult result = new QueryDeparturesResult(); + final StringBuilder uri = new StringBuilder(); + uri.append(API_BASE).append("stboard.exe/dn"); + uri.append("?productsFilter=").append(allProductsString()); + uri.append("&boardType=dep"); + uri.append("&disableEquivs=yes"); // don't use nearby stations + uri.append("&maxJourneys=50"); // ignore maxDepartures because result contains other stations + uri.append("&start=yes"); + uri.append("&L=vs_java3"); + uri.append("&input=").append(stationId); - // scrape page - final String uri = departuresQueryUri(stationId, maxDepartures); - final CharSequence page = ParserUtils.scrape(uri); - - // parse page - final Matcher mHeadCoarse = P_DEPARTURES_HEAD_COARSE.matcher(page); - if (mHeadCoarse.matches()) - { - // messages - if (mHeadCoarse.group(3) != null) - { - result.stationDepartures.add(new StationDepartures(new Location(LocationType.STATION, stationId), - Collections. emptyList(), null)); - return result; - } - else if (mHeadCoarse.group(4) != null) - return new QueryDeparturesResult(Status.INVALID_STATION); - else if (mHeadCoarse.group(5) != null) - return new QueryDeparturesResult(Status.SERVICE_DOWN); - - final Matcher mHeadFine = P_DEPARTURES_HEAD_FINE.matcher(mHeadCoarse.group(1)); - if (mHeadFine.matches()) - { - final String location = ParserUtils.resolveEntities(mHeadFine.group(1)); - final Calendar currentTime = new GregorianCalendar(timeZone()); - currentTime.clear(); - ParserUtils.parseGermanDate(currentTime, mHeadFine.group(2)); - ParserUtils.parseEuropeanTime(currentTime, mHeadFine.group(3)); - final List departures = new ArrayList(8); - String oldZebra = null; - - final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(2)); - while (mDepCoarse.find()) - { - final String zebra = mDepCoarse.group(1); - if (oldZebra != null && zebra.equals(oldZebra)) - throw new IllegalArgumentException("missed row? last:" + zebra); - else - oldZebra = zebra; - - final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(2)); - if (mDepFine.matches()) - { - final Calendar plannedTime = new GregorianCalendar(timeZone()); - plannedTime.setTimeInMillis(currentTime.getTimeInMillis()); - ParserUtils.parseEuropeanTime(plannedTime, mDepFine.group(1)); - - if (plannedTime.getTimeInMillis() - currentTime.getTimeInMillis() < -PARSER_DAY_ROLLOVER_THRESHOLD_MS) - plannedTime.add(Calendar.DAY_OF_MONTH, 1); - - final Calendar predictedTime; - final String prognosis = ParserUtils.resolveEntities(mDepFine.group(2)); - if (prognosis != null) - { - predictedTime = new GregorianCalendar(timeZone()); - if (prognosis.equals("pünktlich")) - { - predictedTime.setTimeInMillis(plannedTime.getTimeInMillis()); - } - else - { - predictedTime.setTimeInMillis(currentTime.getTimeInMillis()); - ParserUtils.parseEuropeanTime(predictedTime, prognosis); - } - } - else - { - predictedTime = null; - } - - final String lineType = mDepFine.group(3); - - final String line = normalizeLine(lineType, ParserUtils.resolveEntities(mDepFine.group(4))); - - final int destinationId = mDepFine.group(5) != null ? Integer.parseInt(mDepFine.group(5)) : 0; - - final String destination = ParserUtils.resolveEntities(mDepFine.group(6)); - - final String position = mDepFine.group(7) != null ? "Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)) : null; - - final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, new Line( - null, line, line != null ? lineColors(line) : null), position, destinationId, destination, null, null); - - if (!departures.contains(dep)) - departures.add(dep); - } - else - { - throw new IllegalArgumentException("cannot parse '" + mDepCoarse.group(2) + "' on " + stationId); - } - } - - result.stationDepartures.add(new StationDepartures(new Location(LocationType.STATION, stationId, null, location), departures, null)); - return result; - } - else - { - throw new IllegalArgumentException("cannot parse '" + mHeadCoarse.group(1) + "' on " + stationId); - } - } - else - { - throw new IllegalArgumentException("cannot parse '" + page + "' on " + stationId); - } + return xmlQueryDepartures(uri.toString(), stationId); } public List autocompleteStations(final CharSequence constraint) throws IOException