Skip to content

Commit 532646e

Browse files
committed
Location Scenario
1 parent f090012 commit 532646e

File tree

17 files changed

+234
-21
lines changed

17 files changed

+234
-21
lines changed

app/src/js/components/chat/ChatInput.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class ChatInput extends React.Component {
2626
submitHandler(event) {
2727
event.preventDefault();
2828
if(this.state.chatInput != '') {
29-
this.setState({chatInput: '', sendDisabled: true, showSendButton: false, inputMargin: this.inputMargin});
29+
this.setState({chatInput: '', sendDisabled: true});
3030
this.props.onSend({
3131
messageType: Constants.request.RequestType.TEXT_MESSAGE,
3232
messageData: [{text: this.state.chatInput}]

app/src/js/components/chat/Messages.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ class Messages extends React.Component {
88
componentDidUpdate() {
99
const element = document.getElementById("messages-container");
1010
if(!this.props.isAdmin) {
11-
element.scrollTop = element.scrollHeight;
11+
var target = $('.bubble-user').last().parent();
12+
if(target.length) {
13+
$(element).animate({
14+
scrollTop: target.offset().top - $(element).offset().top + $(element).scrollTop()
15+
});
16+
}
1217
}
1318
}
1419

pom.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,6 @@
107107
<artifactId>cloudant-spring-boot-starter</artifactId>
108108
<version>0.9.5</version>
109109
</dependency>
110-
111110
<dependency>
112111
<groupId>com.wolfram</groupId>
113112
<artifactId>alpha</artifactId>

src/main/java/chatbot/cache/WolframModel.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ private String queryWolframAlpha(String apiKey) {
4545

4646
WAQuery query = engine.createQuery();
4747
query.setInput(question);
48-
String result = null;
4948

5049
try {
5150
// For educational purposes, print out the URL we are about to send:
@@ -84,7 +83,7 @@ private String queryWolframAlpha(String apiKey) {
8483

8584
public WolframModel getAnswer(String apiKey) {
8685
String wolframAnswer = queryWolframAlpha(apiKey);
87-
if (wolframAnswer != null) {
86+
if (wolframAnswer != null && !wolframAnswer.isEmpty() && !wolframAnswer.equals("(data not available)")) {
8887
String uri = new SpotlightService().search(wolframAnswer);
8988
// If URI found
9089
if (uri != null) {
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package chatbot.lib.api;
2+
3+
import chatbot.lib.Constants;
4+
import chatbot.lib.Utility;
5+
import chatbot.lib.response.Response;
6+
import chatbot.lib.response.ResponseData;
7+
import chatbot.lib.response.ResponseType;
8+
import org.apache.http.HttpResponse;
9+
import org.apache.http.client.HttpClient;
10+
import org.apache.http.client.config.RequestConfig;
11+
import org.apache.http.client.methods.HttpGet;
12+
import org.apache.http.impl.client.HttpClientBuilder;
13+
import org.apache.http.util.EntityUtils;
14+
import org.codehaus.jackson.JsonNode;
15+
import org.codehaus.jackson.map.ObjectMapper;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
18+
19+
import java.util.ArrayList;
20+
import java.util.LinkedHashMap;
21+
import java.util.List;
22+
23+
/**
24+
* Created by ramgathreya on 7/27/17.
25+
*/
26+
public class NominatimService {
27+
private static final Logger logger = LoggerFactory.getLogger(NominatimService.class);
28+
private static final String URL = "http://nominatim.openstreetmap.org";
29+
30+
private int maxHits = 1;
31+
private HttpClient client;
32+
33+
public NominatimService() {
34+
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(Constants.API_TIMEOUT).build();
35+
client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
36+
}
37+
38+
public ResponseData reverseGeoCode(String query) {
39+
try {
40+
String url = "/search?q=" + Utility.urlEncode(query) + "&addressdetails=1&extratags=1&limit=" + maxHits;
41+
HttpGet httpGet = new HttpGet(URL + url + "&format=json");
42+
httpGet.addHeader("Accept", "application/json");
43+
HttpResponse response = client.execute(httpGet);
44+
45+
// Error Scenario
46+
if(response.getStatusLine().getStatusCode() >= 400) {
47+
return null;
48+
}
49+
else {
50+
String responseString = EntityUtils.toString(response.getEntity());
51+
JsonNode responseObj = new ObjectMapper().readTree(responseString).get(0);
52+
JsonNode extratags = responseObj.get("extratags");
53+
JsonNode address = responseObj.get("address");
54+
ResponseData place = new ResponseData();
55+
56+
place.setTitle(query + " (Location Info)");
57+
place.setText(responseObj.get("display_name").getTextValue());
58+
if(extratags != null) {
59+
if(extratags.get("image") != null) {
60+
place.setImage(extratags.get("image").getTextValue());
61+
}
62+
if(extratags.get("website") != null) {
63+
String website = extratags.get("website").getTextValue();
64+
place.addField(new ResponseData.Field()
65+
.setName("Website")
66+
.setValues(new LinkedHashMap<String, String>(){{
67+
put(website, website);
68+
}})
69+
);
70+
}
71+
if(extratags.get("opening_hours") != null) {
72+
place.addField(new ResponseData.Field("Opening Hours", extratags.get("opening_hours").getTextValue()));
73+
}
74+
}
75+
76+
if(address != null) {
77+
if(address.get("country") != null) {
78+
place.addField(new ResponseData.Field("Country", address.get("country").getTextValue()));
79+
}
80+
if(address.get("state") != null) {
81+
place.addField(new ResponseData.Field("State", address.get("state").getTextValue()));
82+
}
83+
if(address.get("city") != null) {
84+
place.addField(new ResponseData.Field("City", address.get("city").getTextValue()));
85+
}
86+
}
87+
88+
place.addField(new ResponseData.Field("Latitude", responseObj.get("lat").getTextValue()));
89+
place.addField(new ResponseData.Field("Longitude", responseObj.get("lon").getTextValue()));
90+
place.addButton(new ResponseData.Button("View Map", ResponseType.BUTTON_LINK, URL + url));
91+
return place;
92+
}
93+
}
94+
catch (Exception e) {
95+
e.printStackTrace();
96+
}
97+
return null;
98+
}
99+
100+
public int getMaxHits() {
101+
return maxHits;
102+
}
103+
104+
public NominatimService setMaxHits(int maxHits) {
105+
this.maxHits = maxHits;
106+
return this;
107+
}
108+
}

src/main/java/chatbot/lib/api/SPARQL.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,20 @@ public String buildQuery(String query) {
4949
// Remove the pronounciation information that appears at the beginning of the article enclosed by ()
5050
// Additionally can be checked to contain unnecessary characters instead of blindly stripping based on brackets
5151
private String stripWikiepdiaContent(String text) {
52-
int indexStart = text.indexOf("(");
53-
if(indexStart != -1) {
54-
int indexEnd = text.indexOf(")", indexStart) + 2;
52+
int indexStart = text.indexOf("("), indexEnd;
53+
if(indexStart > 0) {
54+
indexEnd = text.indexOf(")", indexStart) + 2;
5555
if(indexEnd != -1) {
5656
return text.replace(text.substring(indexStart, indexEnd), "");
5757
}
5858
}
59+
else if(indexStart == 0) {
60+
// When abstract starts with info on Disambiguation
61+
indexEnd = text.lastIndexOf("(disambiguation).)");
62+
if(indexEnd != -1) {
63+
return text.replace(text.substring(indexStart, indexEnd + 18), "");
64+
}
65+
}
5966
return text;
6067
}
6168

src/main/java/chatbot/lib/api/dbpedia/LookupService.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public LookupService() {
3434
client = HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build();
3535
}
3636

37+
// Need to be extended for multiple answers
3738
public String search(String query) {
3839
try {
3940
String url = "?QueryString=" + Utility.urlEncode(query) + "&MaxHits=" + String.valueOf(maxHits);

src/main/java/chatbot/lib/api/qa/QAService.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,15 @@ public QAService(WolframRepository wolframRepository) {
3636
}
3737

3838
// Calls QA Service then returns resulting data as a list of Data Objects. The Data class is defined below as an inner class to be used here locally
39-
public Data search(String question) throws Exception {
40-
return qanary.search(question)
41-
.addData(wolframAlpha.search(question), true);
39+
public Data search(String question) {
40+
try {
41+
return qanary.search(question)
42+
.addData(wolframAlpha.search(question), true);
43+
}
44+
catch (Exception e) {
45+
e.printStackTrace();
46+
}
47+
return null;
4248
}
4349

4450
public static class Data {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package chatbot.lib.handlers;
2+
3+
import chatbot.Application;
4+
import chatbot.lib.api.NominatimService;
5+
import chatbot.lib.api.dbpedia.LookupService;
6+
import chatbot.lib.api.qa.QAService;
7+
import chatbot.lib.request.Request;
8+
import chatbot.lib.response.ResponseData;
9+
import chatbot.lib.response.ResponseGenerator;
10+
import chatbot.rivescript.RiveScriptReplyType;
11+
import org.slf4j.Logger;
12+
import org.slf4j.LoggerFactory;
13+
14+
import java.util.ArrayList;
15+
import java.util.Iterator;
16+
import java.util.List;
17+
18+
/**
19+
* Created by ramgathreya on 7/26/17.
20+
*/
21+
public class LocationHandler {
22+
private static final Logger logger = LoggerFactory.getLogger(LocationHandler.class);
23+
24+
private String question;
25+
private Request request;
26+
private Application.Helper helper;
27+
private LookupService lookupService;
28+
29+
public LocationHandler(Request request, String question, Application.Helper helper) {
30+
this.request = request;
31+
this.question = question;
32+
this.helper = helper;
33+
lookupService = new LookupService();
34+
}
35+
36+
private List<ResponseData> getResponseData(String uri) {
37+
List<ResponseData> responseDataList = new ArrayList<>();
38+
ResponseData entityData = helper.getSparql().getEntityInformation(uri);
39+
ResponseData data = new NominatimService().reverseGeoCode(entityData.getTitle());
40+
41+
if(data != null) {
42+
responseDataList.add(data);
43+
}
44+
responseDataList.add(entityData);
45+
return responseDataList;
46+
}
47+
48+
public ResponseGenerator getLocation() {
49+
ResponseGenerator responseGenerator = new ResponseGenerator();
50+
List<ResponseData> responseDataList = new ArrayList<>();
51+
52+
String uri = lookupService.setQueryClass("place").search(question);
53+
// If entity has been found
54+
if(uri != null) {
55+
responseDataList = getResponseData(uri);
56+
}
57+
// When there is no direct entity match
58+
else {
59+
QAService qaService = new QAService(helper.getWolframRepository());
60+
QAService.Data data = qaService.search(question);
61+
if(data != null && data.getUris().size() > 0) {
62+
Iterator iterator = data.getUris().iterator();
63+
uri = (String) iterator.next();
64+
responseDataList = getResponseData(uri);
65+
66+
}
67+
}
68+
69+
if(responseDataList.size() > 0) {
70+
responseGenerator.addTextResponse(new ResponseData(helper.getRiveScriptBot().answer(request.getUserId(), RiveScriptReplyType.NL_ANSWER_TEXT)[0]));
71+
responseGenerator.addCarouselResponse(responseDataList);
72+
}
73+
return responseGenerator;
74+
}
75+
}

src/main/java/chatbot/lib/handlers/NLHandler.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ else if(uris.size() > 0) {
109109

110110
// Not a disambiguation page
111111
if(count == 0) {
112-
ResponseData _data = helper.getSparql().getEntityInformation(uri);
113-
if (_data != null) {
114-
processedResponse.addResponseData(_data);
112+
ResponseData responseData = helper.getSparql().getEntityInformation(uri);
113+
if (responseData != null) {
114+
processedResponse.addResponseData(responseData);
115115
}
116116
}
117117
// Disambiguation page

src/main/java/chatbot/lib/handlers/TextHandler.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ public ResponseGenerator handleTextMessage() throws Exception {
4949
case RiveScriptReplyType.STATUS_CHECK_SCENARIO:
5050
responseGenerator = new StatusCheckHandler(request, rootNode.get("name").getTextValue(), helper).handleStatusCheck();
5151
break;
52+
case RiveScriptReplyType.LOCATION_SCENARIO:
53+
responseGenerator = new LocationHandler(request, rootNode.get("query").getTextValue(), helper).getLocation();
54+
break;
5255
case RiveScriptReplyType.FALLBACK_SCENARIO:
5356
// Eliza
5457
if(textMessage.endsWith("!") || textMessage.endsWith(".")) {

src/main/java/chatbot/lib/handlers/templates/dbpedia/DBpediaTemplateHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public ResponseGenerator handleTemplateMessage() {
4646
add(new ResponseData.Button("Mailing List", ResponseType.BUTTON_LINK, service[3]));
4747
add(new ResponseData.Button("FAQ", ResponseType.BUTTON_PARAM, TemplateType.FAQ + Utility.STRING_SEPARATOR + payload[1]));
4848
}}));
49+
responseGenerator.setShowFeedback(false);
4950
break;
5051
}
5152
return responseGenerator;

src/main/java/chatbot/lib/response/ResponseData.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public ResponseData setFields(List<Field> fields) {
3232
return this;
3333
}
3434

35+
public ResponseData addField(Field field) {
36+
this.fields.add(field);
37+
return this;
38+
}
39+
3540
public ResponseData addButton(Button button) {
3641
this.buttons.add(button);
3742
return this;
@@ -206,6 +211,11 @@ public Field() {
206211

207212
}
208213

214+
public Field(String name, String value) {
215+
this.name = name;
216+
this.value = value;
217+
}
218+
209219
public String getName() {
210220
return name;
211221
}
@@ -224,11 +234,6 @@ public Field setValue(String value) {
224234
return this;
225235
}
226236

227-
public Field(String name, String value) {
228-
this.name = name;
229-
this.value = value;
230-
}
231-
232237
public Field(String name, String value, boolean isShort) {
233238
this.name = name;
234239
this.value = value;

src/main/java/chatbot/platforms/web/controllers/AdminController.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public String actionAdminGet() {
4343
try {
4444
return helper.getChatDB().getViewRequestBuilder("chats", "getUserList")
4545
.newRequest(Key.Type.COMPLEX, UserList.class)
46-
.startKey(Key.complex("z", "\ufff0"))
46+
.startKey(Key.complex("\ufff0"))
4747
.endKey(Key.complex(""))
4848
.limit(MAX_SIZE)
4949
.skip((Integer.parseInt(page) - 1) * MAX_SIZE)

src/main/java/chatbot/rivescript/RiveScriptReplyType.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public interface RiveScriptReplyType {
88
String TEMPLATE_SCENARIO = "template";
99
String STATUS_CHECK_SCENARIO = "status_check";
1010
String LANGUAGE_SCENARIO = "language";
11+
String LOCATION_SCENARIO = "location";
1112

1213
// String Scenarios where we just want different kinds of messages from Rive
1314
String FALLBACK_TEXT = "fallbacktext";

src/main/resources/rivescript/bot.rive

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
+ [*] what are you [*]
1313
@ about
1414

15-
+ [*] who (made|created) you [*]
15+
+ [*] who (made|created|built|coded|produced) you [*]
1616
- My makers are from the Open Source DBpedia Organization
1717

1818
+ [*] how are you [*]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Handles scenarios where user asks for a place
2+
+ [*] where is *
3+
- {"type": "location", "query": "<star>"}

0 commit comments

Comments
 (0)