mirror of
https://gitlab.com/oeffi/public-transport-enabler.git
synced 2025-07-18 08:19:51 +00:00
parse SBB connection overview
git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@59 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
parent
5510ccbf6b
commit
6f1ecafcb2
8 changed files with 169 additions and 25 deletions
|
@ -265,7 +265,8 @@ public final class BahnProvider implements NetworkProvider
|
||||||
line = normalizeLine(line);
|
line = normalizeLine(line);
|
||||||
else
|
else
|
||||||
line = null;
|
line = null;
|
||||||
final Connection connection = new Connection(link, departureTime, arrivalTime, 0, from, 0, to, new ArrayList<Connection.Part>(1));
|
final Connection connection = new Connection(ParserUtils.extractId(link), link, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
|
new ArrayList<Connection.Part>(1));
|
||||||
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line.charAt(0)) : null));
|
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line.charAt(0)) : null));
|
||||||
connections.add(connection);
|
connections.add(connection);
|
||||||
}
|
}
|
||||||
|
@ -393,8 +394,8 @@ public final class BahnProvider implements NetworkProvider
|
||||||
if (firstDepartureTime == null || lastArrivalTime == null)
|
if (firstDepartureTime == null || lastArrivalTime == null)
|
||||||
throw new IllegalStateException("could not parse all parts of:\n" + page + "\n" + parts);
|
throw new IllegalStateException("could not parse all parts of:\n" + page + "\n" + parts);
|
||||||
|
|
||||||
return new GetConnectionDetailsResult(new Date(), new Connection(uri, firstDepartureTime, lastArrivalTime, 0, firstDeparture, 0,
|
return new GetConnectionDetailsResult(new Date(), new Connection(ParserUtils.extractId(uri), uri, firstDepartureTime, lastArrivalTime, 0,
|
||||||
lastArrival, parts));
|
firstDeparture, 0, lastArrival, parts));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,10 +36,10 @@ public final class Connection implements Serializable
|
||||||
final public String to;
|
final public String to;
|
||||||
final public List<Part> parts;
|
final public List<Part> parts;
|
||||||
|
|
||||||
public Connection(final String link, final Date departureTime, final Date arrivalTime, final int fromId, final String from, final int toId,
|
public Connection(final String id, final String link, final Date departureTime, final Date arrivalTime, final int fromId, final String from,
|
||||||
final String to, final List<Part> parts)
|
final int toId, final String to, final List<Part> parts)
|
||||||
{
|
{
|
||||||
this.id = extractId(link);
|
this.id = id;
|
||||||
this.link = link;
|
this.link = link;
|
||||||
this.departureTime = departureTime;
|
this.departureTime = departureTime;
|
||||||
this.fromId = fromId;
|
this.fromId = fromId;
|
||||||
|
@ -50,11 +50,6 @@ public final class Connection implements Serializable
|
||||||
this.parts = parts;
|
this.parts = parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String extractId(String link)
|
|
||||||
{
|
|
||||||
return link.substring(link.length() - 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
|
|
|
@ -299,7 +299,7 @@ public class MvvProvider implements NetworkProvider
|
||||||
Date arrivalTime = ParserUtils.joinDateTime(date, ParserUtils.parseTime(mConFine.group(5)));
|
Date arrivalTime = ParserUtils.joinDateTime(date, ParserUtils.parseTime(mConFine.group(5)));
|
||||||
if (departureTime.after(arrivalTime))
|
if (departureTime.after(arrivalTime))
|
||||||
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
|
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
|
||||||
final Connection connection = new Connection(link, departureTime, arrivalTime, 0, from, 0, to,
|
final Connection connection = new Connection(ParserUtils.extractId(link), link, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
new ArrayList<Connection.Part>(1));
|
new ArrayList<Connection.Part>(1));
|
||||||
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, null, null));
|
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, null, null));
|
||||||
connections.add(connection);
|
connections.add(connection);
|
||||||
|
@ -311,7 +311,7 @@ public class MvvProvider implements NetworkProvider
|
||||||
final Date departureTime = calendar.getTime();
|
final Date departureTime = calendar.getTime();
|
||||||
calendar.add(Calendar.MINUTE, min);
|
calendar.add(Calendar.MINUTE, min);
|
||||||
final Date arrivalTime = calendar.getTime();
|
final Date arrivalTime = calendar.getTime();
|
||||||
final Connection connection = new Connection(link, departureTime, arrivalTime, 0, from, 0, to,
|
final Connection connection = new Connection(ParserUtils.extractId(link), link, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
new ArrayList<Connection.Part>(1));
|
new ArrayList<Connection.Part>(1));
|
||||||
connection.parts.add(new Connection.Footway(min, from, to));
|
connection.parts.add(new Connection.Footway(min, from, to));
|
||||||
connections.add(connection);
|
connections.add(connection);
|
||||||
|
@ -448,8 +448,8 @@ public class MvvProvider implements NetworkProvider
|
||||||
lastArrivalTime = calendar.getTime();
|
lastArrivalTime = calendar.getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetConnectionDetailsResult(new Date(), new Connection(uri, firstDepartureTime, lastArrivalTime, 0, firstDeparture, 0,
|
return new GetConnectionDetailsResult(new Date(), new Connection(ParserUtils.extractId(uri), uri, firstDepartureTime, lastArrivalTime, 0,
|
||||||
lastArrival, parts));
|
firstDeparture, 0, lastArrival, parts));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -201,4 +201,9 @@ public final class ParserUtils
|
||||||
throw new RuntimeException(x);
|
throw new RuntimeException(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String extractId(final String link)
|
||||||
|
{
|
||||||
|
return link.substring(link.length() - 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -264,7 +264,8 @@ public class RmvProvider implements NetworkProvider
|
||||||
line = normalizeLine(line);
|
line = normalizeLine(line);
|
||||||
else
|
else
|
||||||
line = null;
|
line = null;
|
||||||
final Connection connection = new Connection(link, departureTime, arrivalTime, 0, from, 0, to, new ArrayList<Connection.Part>(1));
|
final Connection connection = new Connection(ParserUtils.extractId(link), link, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
|
new ArrayList<Connection.Part>(1));
|
||||||
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line.charAt(0)) : null));
|
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line.charAt(0)) : null));
|
||||||
connections.add(connection);
|
connections.add(connection);
|
||||||
}
|
}
|
||||||
|
@ -380,8 +381,8 @@ public class RmvProvider implements NetworkProvider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new GetConnectionDetailsResult(currentDate, new Connection(uri, firstDepartureTime, lastArrivalTime, 0, firstDeparture, 0,
|
return new GetConnectionDetailsResult(currentDate, new Connection(ParserUtils.extractId(uri), uri, firstDepartureTime, lastArrivalTime,
|
||||||
lastArrival, parts));
|
0, firstDeparture, 0, lastArrival, parts));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,20 +113,121 @@ public class SbbProvider implements NetworkProvider
|
||||||
return uri.toString();
|
return uri.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern P_PRE_ADDRESS = Pattern.compile(
|
||||||
|
"<select name=\"(REQ0JourneyStopsS0K|REQ0JourneyStopsZ0K|REQ0JourneyStops1\\.0K)\" accesskey=\"f\".*?>(.*?)</select>", Pattern.DOTALL);
|
||||||
|
private static final Pattern P_ADDRESSES = Pattern.compile("<option.*?>\\s*(.*?)\\s*</option>", Pattern.DOTALL);
|
||||||
|
|
||||||
public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep)
|
public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException();
|
final String uri = connectionsQueryUri(from, via, to, date, dep);
|
||||||
|
final CharSequence page = ParserUtils.scrape(uri);
|
||||||
|
|
||||||
|
// TODO errors
|
||||||
|
|
||||||
|
List<String> fromAddresses = null;
|
||||||
|
List<String> viaAddresses = null;
|
||||||
|
List<String> toAddresses = null;
|
||||||
|
|
||||||
|
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
|
||||||
|
while (mPreAddress.find())
|
||||||
|
{
|
||||||
|
final String type = mPreAddress.group(1);
|
||||||
|
final String options = mPreAddress.group(2);
|
||||||
|
|
||||||
|
final Matcher mAddresses = P_ADDRESSES.matcher(options);
|
||||||
|
final List<String> addresses = new ArrayList<String>();
|
||||||
|
while (mAddresses.find())
|
||||||
|
{
|
||||||
|
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
|
||||||
|
if (!addresses.contains(address))
|
||||||
|
addresses.add(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.equals("REQ0JourneyStopsS0K"))
|
||||||
|
fromAddresses = addresses;
|
||||||
|
else if (type.equals("REQ0JourneyStopsZ0K"))
|
||||||
|
toAddresses = addresses;
|
||||||
|
else if (type.equals("REQ0JourneyStops1.0K"))
|
||||||
|
viaAddresses = addresses;
|
||||||
|
else
|
||||||
|
throw new IOException(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
|
||||||
|
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
|
||||||
|
else
|
||||||
|
return queryConnections(uri, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public QueryConnectionsResult queryMoreConnections(String uri) throws IOException
|
public QueryConnectionsResult queryMoreConnections(final String uri) throws IOException
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException();
|
final CharSequence page = ParserUtils.scrape(uri);
|
||||||
|
|
||||||
|
return queryConnections(uri, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Pattern P_CONNECTIONS_HEAD = Pattern.compile(".*?" //
|
||||||
|
+ "Von:.*?<td .*?>(.*?)</td>.*?" // from
|
||||||
|
+ "Datum:.*?<td .*?>.., (\\d{2}\\.\\d{2}\\.\\d{2})</td>.*?" // date
|
||||||
|
+ "Nach:.*?<td .*?>(.*?)</td>.*?" // to
|
||||||
|
+ "(?:<a href=\"(http://fahrplan.sbb.ch/bin/query.exe/dn\\?seqnr=\\d+&ident=[\\w\\.]+&REQ0HafasScrollDir=2)\".*?>.*?)?" // linkEarlier
|
||||||
|
+ "(?:<a href=\"(http://fahrplan.sbb.ch/bin/query.exe/dn\\?seqnr=\\d+&ident=[\\w\\.]+&REQ0HafasScrollDir=1)\".*?>.*?)?" // linkLater
|
||||||
|
, Pattern.DOTALL);
|
||||||
|
private static final Pattern P_CONNECTIONS_COARSE = Pattern.compile("<tr class=\"(zebra-row-\\d)\">(.*?)</tr>\n?"//
|
||||||
|
+ "<tr class=\"\\1\">(.+?)</tr>", Pattern.DOTALL);
|
||||||
|
private static final Pattern P_CONNECTIONS_FINE = Pattern.compile(".*?" //
|
||||||
|
+ ".., (\\d{2}\\.\\d{2}\\.\\d{2}).*?" // departureDate
|
||||||
|
+ "ab.*?(\\d{2}:\\d{2}).*?" // departureTime
|
||||||
|
+ "duration.*?\\d{1,2}:\\d{2}.*?" //
|
||||||
|
+ "(?:.., (\\d{2}\\.\\d{2}\\.\\d{2}).*?)?" // arrivalDate
|
||||||
|
+ "an.*?(\\d{2}:\\d{2}).*?" // arrivalTime
|
||||||
|
, Pattern.DOTALL);
|
||||||
|
|
||||||
private QueryConnectionsResult queryConnections(final String uri, final CharSequence page) throws IOException
|
private QueryConnectionsResult queryConnections(final String uri, final CharSequence page) throws IOException
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException();
|
final Matcher mHead = P_CONNECTIONS_HEAD.matcher(page);
|
||||||
|
if (mHead.matches())
|
||||||
|
{
|
||||||
|
final String from = ParserUtils.resolveEntities(mHead.group(1));
|
||||||
|
final Date currentDate = ParserUtils.parseDate(mHead.group(2));
|
||||||
|
final String to = ParserUtils.resolveEntities(mHead.group(3));
|
||||||
|
final String linkEarlier = mHead.group(4) != null ? ParserUtils.resolveEntities(mHead.group(4)) : null;
|
||||||
|
final String linkLater = mHead.group(5) != null ? ParserUtils.resolveEntities(mHead.group(5)) : null;
|
||||||
|
final List<Connection> connections = new ArrayList<Connection>();
|
||||||
|
|
||||||
|
final Matcher mConCoarse = P_CONNECTIONS_COARSE.matcher(page);
|
||||||
|
int i = 1;
|
||||||
|
while (mConCoarse.find())
|
||||||
|
{
|
||||||
|
final String set = mConCoarse.group(2) + mConCoarse.group(3);
|
||||||
|
final Matcher mConFine = P_CONNECTIONS_FINE.matcher(set);
|
||||||
|
if (mConFine.matches())
|
||||||
|
{
|
||||||
|
final Date departureDate = ParserUtils.parseDate(mConFine.group(1));
|
||||||
|
final Date departureTime = ParserUtils.joinDateTime(departureDate, ParserUtils.parseTime(mConFine.group(2)));
|
||||||
|
final Date arrivalDate = mConFine.group(3) != null ? ParserUtils.parseDate(mConFine.group(3)) : null;
|
||||||
|
final Date arrivalTime = ParserUtils.joinDateTime(arrivalDate != null ? arrivalDate : departureDate, ParserUtils
|
||||||
|
.parseTime(mConFine.group(4)));
|
||||||
|
final String id = departureTime.toString() + arrivalTime.toString();
|
||||||
|
|
||||||
|
final Connection connection = new Connection(id, uri + "#" + i++, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
|
new ArrayList<Connection.Part>(1));
|
||||||
|
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, null, null));
|
||||||
|
connections.add(connection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("cannot parse '" + set + "' on " + uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new QueryConnectionsResult(uri, from, to, currentDate, linkEarlier, linkLater, connections);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IOException(page.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public GetConnectionDetailsResult getConnectionDetails(final String connectionUri) throws IOException
|
public GetConnectionDetailsResult getConnectionDetails(final String connectionUri) throws IOException
|
||||||
|
|
|
@ -271,7 +271,8 @@ public final class VbbProvider implements NetworkProvider
|
||||||
if (departureTime.after(arrivalTime))
|
if (departureTime.after(arrivalTime))
|
||||||
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
|
arrivalTime = ParserUtils.addDays(arrivalTime, 1);
|
||||||
final String line = normalizeLine(ParserUtils.resolveEntities(mConFine.group(4)));
|
final String line = normalizeLine(ParserUtils.resolveEntities(mConFine.group(4)));
|
||||||
final Connection connection = new Connection(link, departureTime, arrivalTime, 0, from, 0, to, new ArrayList<Connection.Part>(1));
|
final Connection connection = new Connection(ParserUtils.extractId(link), link, departureTime, arrivalTime, 0, from, 0, to,
|
||||||
|
new ArrayList<Connection.Part>(1));
|
||||||
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line) : null));
|
connection.parts.add(new Connection.Trip(departureTime, arrivalTime, line, line != null ? LINES.get(line) : null));
|
||||||
connections.add(connection);
|
connections.add(connection);
|
||||||
}
|
}
|
||||||
|
@ -410,8 +411,8 @@ public final class VbbProvider implements NetworkProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstDepartureTime != null && lastArrivalTime != null)
|
if (firstDepartureTime != null && lastArrivalTime != null)
|
||||||
return new GetConnectionDetailsResult(currentDate, new Connection(uri, firstDepartureTime, lastArrivalTime, firstDepartureId,
|
return new GetConnectionDetailsResult(currentDate, new Connection(ParserUtils.extractId(uri), uri, firstDepartureTime,
|
||||||
firstDeparture, lastArrivalId, lastArrival, parts));
|
lastArrivalTime, firstDepartureId, firstDeparture, lastArrivalId, lastArrival, parts));
|
||||||
else
|
else
|
||||||
return new GetConnectionDetailsResult(currentDate, null);
|
return new GetConnectionDetailsResult(currentDate, null);
|
||||||
}
|
}
|
||||||
|
|
40
test/de/schildbach/pte/live/SbbProviderLiveTest.java
Normal file
40
test/de/schildbach/pte/live/SbbProviderLiveTest.java
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 the original author or authors.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.schildbach.pte.live;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.schildbach.pte.QueryConnectionsResult;
|
||||||
|
import de.schildbach.pte.SbbProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andreas Schildbach
|
||||||
|
*/
|
||||||
|
public class SbbProviderLiveTest
|
||||||
|
{
|
||||||
|
private SbbProvider provider = new SbbProvider();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void connection() throws Exception
|
||||||
|
{
|
||||||
|
final QueryConnectionsResult result = provider.queryConnections("Zürich!", null, "Bern", new Date(), true);
|
||||||
|
System.out.println(result);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue