Skip to content

Commit 63393ba

Browse files
committed
Added public transit. Fix #113
1 parent 93f9016 commit 63393ba

File tree

11 files changed

+263
-1
lines changed

11 files changed

+263
-1
lines changed

.classpath

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@
1313
<classpathentry kind="src" path="test"/>
1414
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
1515
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
16-
<classpathentry kind="output" path="build/classes"/>
16+
<classpathentry kind="output" path="bin"/>
1717
</classpath>

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "dependencies/public-transport-enabler"]
2+
path = dependencies/public-transport-enabler
3+
url = https://github.com/schildbach/public-transport-enabler.git

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ dependencies {
5555
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.+'
5656
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.+'
5757
compile group: 'jfree', name: 'jfreechart', version: '1.+'
58+
compile(project(':dependencies:public-transport-enabler:enabler')) { }
5859
}
5960

6061
tasks.withType(Javadoc) {

conf/susi/bahn.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{"rules":[
2+
{
3+
"example":"How to get from München HBF to Potsdam Griebnitzsee",
4+
"phrases":[ {"type":"pattern", "expression":"How to get from * to *"}
5+
],
6+
"process":[ {"type":"console", "expression":"SELECT description FROM bahn WHERE from='$1$' to='$2$';"}],
7+
"actions":[ {"type":"answer", "select":"random", "phrases":[
8+
"$description$",
9+
]}],
10+
},
11+
]}

settings.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
rootProject.name = 'susi_server'
2+
include ':dependencies:public-transport-enabler:enabler'

src/ai/susi/server/api/susi/ConsoleService.java

+21
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@
4343
import ai.susi.server.BaseUserRole;
4444
import ai.susi.server.ClientConnection;
4545
import ai.susi.server.Query;
46+
import api.external.transit.BahnService;
47+
import api.external.transit.BahnService.NoStationFoundException;
4648

4749
import javax.servlet.http.HttpServletResponse;
4850

@@ -176,6 +178,25 @@ public static byte[] loadData(String url) throws IOException {
176178
}
177179
return json;
178180
});
181+
dbAccess.put(Pattern.compile("SELECT +?(.*?) +?FROM +?bahn +?WHERE +?from ??= ??'(.*?)' +?to ??= ??'(.*?)' ??;"), (flow, matcher) -> {
182+
String query = matcher.group(1);
183+
String from = matcher.group(2);
184+
String to = matcher.group(3);
185+
SusiThought json = new SusiThought();
186+
try {
187+
json = (new BahnService()).getConnections(from, to);
188+
SusiTransfer transfer = new SusiTransfer(query);
189+
json.setData(transfer.conclude(json.getData()));
190+
return json;
191+
} catch (IOException e) {
192+
// TODO Auto-generated catch block
193+
e.printStackTrace();
194+
} catch (NoStationFoundException e) {
195+
// TODO Auto-generated catch block
196+
e.printStackTrace();
197+
}
198+
return json;
199+
});
179200
}
180201

181202
@Override
+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package api.external.transit;
2+
import java.io.IOException;
3+
import java.util.Calendar;
4+
import java.util.Date;
5+
import java.util.List;
6+
7+
import org.json.*;
8+
9+
import ai.susi.mind.SusiThought;
10+
import de.schildbach.pte.*;
11+
import de.schildbach.pte.dto.Location;
12+
import de.schildbach.pte.dto.QueryTripsResult;
13+
import de.schildbach.pte.dto.Trip;
14+
15+
public class BahnService {
16+
@SuppressWarnings("serial")
17+
public static class NoStationFoundException extends Exception {
18+
public NoStationFoundException(String stationName) {
19+
super("No station named '" + stationName + "' found.");
20+
}
21+
}
22+
private BahnProvider provider = new BahnProvider();
23+
24+
public SusiThought getConnections(String from, String to) throws IOException, NoStationFoundException {
25+
Calendar cal = Calendar.getInstance();
26+
return this.getConnections(from, to, cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
27+
}
28+
29+
@SuppressWarnings("deprecation")
30+
public SusiThought getConnections(String from, String to, int hoursDep, int minutesDep) throws IOException, NoStationFoundException {
31+
// Yes, Date is deprecated, but the referenced library needs it...
32+
Date date = new Date();
33+
date.setHours(hoursDep);
34+
date.setMinutes(minutesDep);
35+
SusiThought response = new SusiThought();
36+
JSONArray data = new JSONArray();
37+
38+
List<Location> fromLocations = provider.suggestLocations(from).getLocations();
39+
List<Location> toLocations = provider.suggestLocations(to).getLocations();
40+
if (fromLocations.size() == 0) {
41+
throw new NoStationFoundException(from);
42+
}
43+
if (toLocations.size() == 0) {
44+
throw new NoStationFoundException(to);
45+
}
46+
47+
QueryTripsResult tripsResult = provider.queryTrips(fromLocations.get(0), null, toLocations.get(0), date, true, null, null, null, null, null);
48+
response.setHits(tripsResult.trips.size());
49+
50+
for (Trip trip : tripsResult.trips) {
51+
data.put(JSONConverter.tripToJSON(trip));
52+
}
53+
response.setData(data);
54+
55+
return response;
56+
}
57+
}
+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
package api.external.transit;
2+
3+
import java.util.List;
4+
5+
import org.json.JSONArray;
6+
import org.json.JSONObject;
7+
8+
import de.schildbach.pte.dto.Fare;
9+
import de.schildbach.pte.dto.Location;
10+
import de.schildbach.pte.dto.Trip;
11+
import de.schildbach.pte.dto.Trip.Leg;
12+
import de.schildbach.pte.dto.Line;
13+
14+
public class JSONConverter {
15+
public static JSONObject tripToJSON(Trip trip) {
16+
JSONObject tripObj = new JSONObject();
17+
tripObj.put("durationMinutes", trip.getDuration() / 60000.0);
18+
tripObj.put("departureTime", trip.getFirstDepartureTime());
19+
JSONObject legs = new JSONObject();
20+
for (Integer i = 0; i < trip.legs.size(); i++) {
21+
legs.put(i.toString(), JSONConverter.legToJSON(trip.legs.get(i)));
22+
}
23+
tripObj.put("legs", legs);
24+
tripObj.put("numChanges", trip.numChanges);
25+
JSONArray fares = new JSONArray();
26+
if (trip.fares != null) {
27+
for (Fare fare : trip.fares) {
28+
fares.put(JSONConverter.fareToJson(fare));
29+
}
30+
tripObj.put("fares", fares);
31+
}
32+
tripObj.put("description", JSONConverter.getDescription(trip.legs));
33+
return tripObj;
34+
}
35+
36+
public static JSONObject fareToJson(Fare fare) {
37+
JSONObject fareObj = new JSONObject();
38+
if (fare == null) return fareObj;
39+
fareObj.put("currency", fare.currency.getCurrencyCode());
40+
fareObj.put("fare", fare.fare);
41+
fareObj.put("network", fare.network);
42+
fareObj.put("units", fare.units);
43+
fareObj.put("unitName", fare.unitName);
44+
fareObj.put("class", fare.getClass().getName());
45+
return fareObj;
46+
}
47+
48+
public static JSONObject legToJSON(Leg leg) {
49+
JSONObject legObj = new JSONObject();
50+
if (leg == null) return legObj;
51+
legObj.put("departure", JSONConverter.locationToJSON(leg.departure));
52+
legObj.put("arrival", JSONConverter.locationToJSON(leg.arrival));
53+
legObj.put("departureTime", leg.getDepartureTime());
54+
legObj.put("arrivalTime", leg.getArrivalTime());
55+
if (leg instanceof Trip.Public) {
56+
Trip.Public pub = (Trip.Public)leg;
57+
legObj.putOpt("departureDelay", pub.getDepartureDelay() / 60000.0);
58+
legObj.putOpt("arrivalDelay", pub.getArrivalDelay() / 60000.0);
59+
legObj.putOpt("line", JSONConverter.lineToJSON(pub.line));
60+
}
61+
return legObj;
62+
}
63+
64+
public static JSONObject lineToJSON(Line line) {
65+
JSONObject lineObj = new JSONObject();
66+
if (line == null) return lineObj;
67+
lineObj.put("id", line.id);
68+
lineObj.put("name", line.name);
69+
lineObj.put("label", line.label);
70+
lineObj.put("message", line.message);
71+
lineObj.put("network", line.network);
72+
lineObj.put("product", line.product.toString());
73+
return lineObj;
74+
}
75+
76+
public static JSONObject locationToJSON(Location location) {
77+
JSONObject locationObj = new JSONObject();
78+
if (location == null) return locationObj;
79+
JSONObject coordinateObj = new JSONObject();
80+
coordinateObj.put("lat", location.lat);
81+
coordinateObj.put("lon", location.lon);
82+
locationObj.put("coords", coordinateObj);
83+
locationObj.put("name", location.name);
84+
locationObj.put("place", location.place);
85+
locationObj.put("id", location.id);
86+
return locationObj;
87+
}
88+
89+
@SuppressWarnings("deprecation")
90+
public static String getDescription(List<Leg> legs) {
91+
String response = "";
92+
for (int i = 0; i < legs.size(); i++) {
93+
if (!(legs.get(i) instanceof Trip.Public)) continue;
94+
if (i == 0) {
95+
response += "Take the ";
96+
} else {
97+
response += " From there, take the ";
98+
}
99+
Trip.Public pub = (Trip.Public)legs.get(i);
100+
response += pub.line.label;
101+
response += " (departing at " + pub.getDepartureTime().getHours() + ":" + pub.getDepartureTime().getMinutes();
102+
response += ", +" + (pub.getDepartureDelay() / 60000.0) + " mins delay) to ";
103+
response += pub.arrival.name;
104+
response += " (arriving at " + pub.getArrivalTime().getHours() + ":" + pub.getArrivalTime().getMinutes();
105+
response += ", +" + (pub.getArrivalDelay() / 60000.0) + " mins delay).";
106+
}
107+
return response;
108+
}
109+
}

test/api/external/BahnTest.java

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package api.external;
2+
3+
import java.io.IOException;
4+
5+
import org.junit.Test;
6+
7+
import api.external.transit.*;
8+
import api.external.transit.BahnService.NoStationFoundException;
9+
10+
public class BahnTest {
11+
BahnService service = new BahnService();
12+
13+
@Test
14+
public void testConnection() throws IOException, NoStationFoundException {
15+
System.out.println(service.getConnections("Alexanderplatz", "Griebnitzsee"));
16+
System.out.println(service.getConnections("München HBF", "Griebnitzsee").getData().getJSONObject(0).getString("description"));
17+
}
18+
}

test/api/external/DeliverooTest.java

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package api.external;
2+
3+
import static org.junit.Assert.assertFalse;
4+
import static org.junit.Assert.assertTrue;
5+
6+
import java.io.IOException;
7+
import java.net.URISyntaxException;
8+
import java.util.List;
9+
10+
import org.apache.http.client.ClientProtocolException;
11+
import org.json.JSONObject;
12+
import org.junit.Test;
13+
14+
import api.external.deliveroo.*;
15+
16+
public class DeliverooTest {
17+
private static String rawJson = "{\"id\":36242,\"name\":\"Sigiriya\",\"name_with_branch\":\"Sigiriya\",\"uname\":\"sigiriya\",\"price_category\":2,\"currency_symbol\":\"\u20AC\",\"primary_image_url\":\"https://cdn1.deliveroo.co.uk/media/menus/28019/320x180.jpg?v=1481188440\",\"image_url\":\"https://cdn1.deliveroo.co.uk/media/menus/28019/{w}x{h}.jpg?v=1481188440{&filters}{&quality}\",\"neighborhood\":{\"id\":519,\"name\":\"Friedrichshain\",\"uname\":\"friedrichshain\"},\"coordinates\":[13.4579792,52.5113786],\"newly_added\":false,\"category\":\"Nur Bei Uns\",\"curr_prep_time\":20,\"delay_time\":0,\"baseline_deliver_time\":21,\"total_time\":20,\"distance_m\":590,\"travel_time\":10,\"kitchen_open_advance\":0,\"hours\":{\"today\":[],\"tomorrow\":[]},\"opening_hours\":{\"today\":[[\"12:00\",\"22:30\"]],\"tomorrow\":[[\"12:00\",\"22:30\"]]},\"target_delivery_time\":{\"minutes\":\"15 - 25\"},\"menu\":{\"menu_tags\":[{\"id\":293,\"type\":\"Collection\",\"name\":\"Nur Bei Uns\"},{\"id\":33,\"type\":\"Locale\",\"name\":\"S\u00FCdindisch\"},{\"id\":188,\"type\":\"Locale\",\"name\":\"Sri Lankisch\"},{\"id\":86,\"type\":\"Dietary\",\"name\":\"Vegetarier\"},{\"id\":71,\"type\":\"Food\",\"name\":\"Meeresfr\u00FCchte\"}]},\"open\":false,\"delivery_hours\":{\"today\":[],\"tomorrow\":[]}}";
18+
19+
@Test
20+
public void testParsing() {
21+
Restaurant restaurant = new Restaurant(new JSONObject(rawJson));
22+
assertTrue(restaurant.getName().equals("Sigiriya"));
23+
assertTrue(restaurant.getCoordinate().getLatitude().equals("13.4579792"));
24+
}
25+
26+
// test the exptected behaviour of the deliveroo API
27+
@Test
28+
public void testAPI() throws ClientProtocolException, URISyntaxException, IOException {
29+
Client client = new Client();
30+
List<Restaurant> restaurants = Restaurant.fetchRestaurants(client, new Coordinate("52.5166791", "13.4584727"));
31+
assertFalse(restaurants.isEmpty());
32+
restaurants.get(0).fetchMenuItems(client);
33+
}
34+
35+
// test the demo
36+
@Test
37+
public void testDemo() throws ClientProtocolException, URISyntaxException, IOException {
38+
DeliverooDemo.main(null);
39+
}
40+
}

0 commit comments

Comments
 (0)