diff --git a/chatbot/api/v2/api.py b/chatbot/api/v2/api.py index 4f6fc7e..419e0c2 100644 --- a/chatbot/api/v2/api.py +++ b/chatbot/api/v2/api.py @@ -25,7 +25,7 @@ }) conflict_model = api.model('Conflict', { - 'conflict_id': fields.String(description='Document ID for conflict'), + 'id': fields.String(description='Document ID for conflict'), 'title': fields.String(description='Title of conflict content') }) @@ -87,14 +87,14 @@ class ConflictIDs(Resource): @api.marshal_with(conflict_model) def get(self): conflict_ids = factory.get_collection(conflict_col).find() - return [models.Conflict(conflict['conflict_id'], conflict['title']) + return [models.Conflict(conflict['id'], conflict['title']) for conflict in conflict_ids] @api.marshal_with(delete_model) @api.response(200, 'Success', delete_model) @api.response(404, 'Conflict not found') def delete(self, conflict_id): - result = factory.delete_document({"conflict_id": conflict_id}, + result = factory.delete_document({'id': conflict_id}, conflict_col) if result.deleted_count > 0: return result @@ -146,6 +146,9 @@ def delete(self, content_id): factory.update_document(query, {'manually_changed': False}, manual_col) factory.update_document(query, {'manually_changed': False}, prod_col) + # Delete conflict if there was one + factory.delete_document({'id': content_id}, conflict_col) + if result.deleted_count > 0: return result else: @@ -193,7 +196,7 @@ def put(self, content_id): .update(*index) # delete this document from the conflict collection - query = {"conflict_id": content_id} + query = {'id': content_id} factory.get_database().get_collection(conflict_col).delete_one(query) if new_document['updatedExisting']: diff --git a/chatbot/api/v2/models.py b/chatbot/api/v2/models.py index a40f690..c621526 100644 --- a/chatbot/api/v2/models.py +++ b/chatbot/api/v2/models.py @@ -20,7 +20,7 @@ def __init__(self, user_input='', response_format='plain'): class Conflict(object): def __init__(self, conflict_id, title): - self.conflict_id = conflict_id + self.id = conflict_id self.title = title diff --git a/chatbot/api/v2/test/test_v2_api.py b/chatbot/api/v2/test/test_v2_api.py index d62d9a0..4a17c1b 100644 --- a/chatbot/api/v2/test/test_v2_api.py +++ b/chatbot/api/v2/test/test_v2_api.py @@ -38,7 +38,7 @@ def test_response(client): def test_get_conflict_ids(client): # Setup two conflicts - conflicts = [{"conflict_id": "test_conflict_id_{}".format(i), + conflicts = [{"id": "test_conflict_id_{}".format(i), "title": "test_conflict_title_{}".format(i)} for i in range(2)] @@ -50,25 +50,26 @@ def test_get_conflict_ids(client): response_data = json.loads(response.data.decode()) for conflict in conflicts: - assert conflict['conflict_id'] in [response['conflict_id'] - for response in response_data] + assert conflict['id'] in [response['id'] + for response in response_data] finally: for conflict in conflicts: - factory.delete_document({'conflict_id': conflict['conflict_id']}, + factory.delete_document({'id': conflict['id']}, conflict_col) def test_delete_conflict_ids(client): - conflict = {'conflict_id': 'test conflict id', + conflict = {'id': 'test conflict id', 'title': 'test title'} factory.post_document(conflict, conflict_col) try: - idx = conflict['conflict_id'] + idx = conflict['id'] response = client.delete('/v2/conflict_ids/{}/'.format(idx)) + print(response.data.decode()) assert json.loads(response.data.decode())['deleted_count'] > 0 finally: - factory.delete_document({'conflict_id': 'test conflict id'}, + factory.delete_document({'id': 'test conflict id'}, conflict_col) diff --git a/chatbot/api/wsgi.py b/chatbot/api/wsgi.py new file mode 100644 index 0000000..10d37a2 --- /dev/null +++ b/chatbot/api/wsgi.py @@ -0,0 +1,4 @@ +from chatbot.api.server import app + +if __name__ == '__main__': + app.run() diff --git a/chatbot/chat/index.html b/chatbot/chat/index.html index 4a88db9..59f9507 100644 --- a/chatbot/chat/index.html +++ b/chatbot/chat/index.html @@ -13,6 +13,8 @@

Chatbot Boligadministrasjonen

Hei! Jeg er en chatbot som svarer for Boligadministrasjonen. Hva kan jeg hjelpe deg med?

+
+

Jeg forstår korte og konsise spørsmål best!

@@ -22,6 +24,10 @@

Chatbot Boligadministrasjonen

+
+

Denne boten er en del av et pilot-prosjekt. Alle spørsmål vil bli + lagret - det frarådes derfor å oppgi personlige eller sensitiv data.

+
diff --git a/chatbot/chat/scripts/chat.js b/chatbot/chat/scripts/chat.js index 7420178..b19aac5 100644 --- a/chatbot/chat/scripts/chat.js +++ b/chatbot/chat/scripts/chat.js @@ -27,6 +27,10 @@ function getUserInput() { */ function query() { var input = getUserInput(); + + // Don't do anything if the field is empty + if (!input) { return; } + populateChatWithMessage(input, "user") http.open("POST", host+"v1/dialogflow/response", true); diff --git a/chatbot/chat/style.css b/chatbot/chat/style.css index 18ff6a1..25f1c4a 100644 --- a/chatbot/chat/style.css +++ b/chatbot/chat/style.css @@ -38,7 +38,7 @@ h1 { margin: 20px auto; width: 80%; - height: 900px; + height: 80vh; max-height: 900px; overflow: auto; border-style: solid; @@ -48,13 +48,13 @@ h1 { .msg { height: auto; width: 100%; - max-height: 450px; margin-bottom: 10px; } .user { margin-left: auto; margin-right: 0; + float: right; } .user p { @@ -93,3 +93,8 @@ p { flex-direction: row; justify-content: center; } + +.disclaimer { + color: red; + margin: 5px auto; +} diff --git a/chatbot/launch.py b/chatbot/launch.py index a1d3355..5e48111 100644 --- a/chatbot/launch.py +++ b/chatbot/launch.py @@ -60,13 +60,13 @@ def insert_documents(data): None) if prod_doc and temp_doc: - if temp_doc["content"] != prod_doc["content"]: + if not temp_doc["content"] == prod_doc["content"]: title = temp_doc["content"]["title"] - conflicts.append({"conflict_id": idx, + conflicts.append({"id": idx, "title": title}) print("Conflicts: {}".format(conflicts)) - factory.get_collection(conflict_col).create_index([("conflict_id", 1)], + factory.get_collection(conflict_col).create_index([("id", 1)], unique=True) for conflict in conflicts: try: @@ -101,9 +101,6 @@ def insert_documents(data): factory.get_collection(unknown_col).create_index([("query_text", 1)], unique=True) - if not conflicts: - factory.get_collection(conflict_col).drop() - return conflicts diff --git a/chatbot/web/package.json b/chatbot/web/package.json index cdb0df7..cb6efa5 100644 --- a/chatbot/web/package.json +++ b/chatbot/web/package.json @@ -1,6 +1,6 @@ { "name": "chatbot_website", - "version": "1.1.8", + "version": "1.1.9", "private": true, "homepage": "https://127.0.0.1/", "dependencies": { diff --git a/chatbot/web/src/App.js b/chatbot/web/src/App.js index 8938053..99d99b0 100644 --- a/chatbot/web/src/App.js +++ b/chatbot/web/src/App.js @@ -17,7 +17,7 @@ class App extends Component { fetchAllConflictIDs = async () => { const conflictDocs = await fetchData( - process.env.REACT_APP_SERVER_URL + 'v1/web/conflict_ids', + process.env.REACT_APP_SERVER_URL + 'v2/conflict_ids/', 'GET' ); this.setState({ conflictDocs }); @@ -25,7 +25,7 @@ class App extends Component { fetchAllUnknownQueries = async () => { const queries = await fetchData( - process.env.REACT_APP_SERVER_URL + 'v1/web/unknown_queries', + process.env.REACT_APP_SERVER_URL + 'v2/unknown_queries/', 'GET' ); this.setState({ queries }); diff --git a/chatbot/web/src/components/DocumentList.js b/chatbot/web/src/components/DocumentList.js index 2741e72..0848fcf 100644 --- a/chatbot/web/src/components/DocumentList.js +++ b/chatbot/web/src/components/DocumentList.js @@ -41,4 +41,4 @@ const DocumentList = ({ docs, changeView, title }) => { ); }; -export default DocumentList; \ No newline at end of file +export default DocumentList; diff --git a/chatbot/web/src/components/DocumentView.js b/chatbot/web/src/components/DocumentView.js index 420b561..0d00830 100644 --- a/chatbot/web/src/components/DocumentView.js +++ b/chatbot/web/src/components/DocumentView.js @@ -25,19 +25,19 @@ class DocumentView extends React.Component { async componentDidMount() { // Fetch content. const content = await fetchData( - process.env.REACT_APP_SERVER_URL + 'v1/web/content/?id=' + this.props.id, + process.env.REACT_APP_SERVER_URL + 'v2/content/' + this.props.id + '/', 'GET', ); this.setState({ - manual: content.manual || content.prod, + manual: content.manual.id ? content.manual : content.prod, automatic: content.prod, title: content.prod.title, url: content.url, }); } - validateKeywords = () => this.state.manual.keywords.every(entry => + validateKeywords = () => this.state.manual.content.keywords.every(entry => !/\s/g.test(entry['keyword'])); @@ -57,11 +57,11 @@ class DocumentView extends React.Component { }); // Save data and delete entry in manual collection if needed. - const data = { data: { id: this.props.id, content: this.state.manual } }; + const data = { id: this.props.id, content: this.state.manual.content }; await fetchData( - process.env.REACT_APP_SERVER_URL + 'v1/web/content/', - 'POST', + process.env.REACT_APP_SERVER_URL + 'v2/content/' + this.props.id + '/', + 'PUT', data, ); @@ -76,8 +76,10 @@ class DocumentView extends React.Component { if (this.state.manual) { this.setState(prevState => ({ manual: { - ...prevState.manual, - texts: [...prevState.manual.texts, ''], + content: { + ...prevState.manual.content, + texts: [...prevState.manual.content.texts, ''], + } }, })); } @@ -88,11 +90,13 @@ class DocumentView extends React.Component { if (this.state.manual) { this.setState(prevState => ({ manual: { - ...prevState.manual, - keywords: [ - ...prevState.manual.keywords, - { keyword: '', confidence: 1 }, - ], + content: { + ...prevState.manual.content, + keywords: [ + ...prevState.manual.content.keywords, + { keyword: '', confidence: 1 }, + ], + } }, })); } @@ -102,11 +106,13 @@ class DocumentView extends React.Component { e.preventDefault(); this.setState(prevState => ({ manual: { - ...prevState.manual, - keywords: [ - ...prevState.manual.keywords.slice(0, i), - ...prevState.manual.keywords.slice(i + 1), - ], + content: { + ...prevState.manual.content, + keywords: [ + ...prevState.manual.content.keywords.slice(0, i), + ...prevState.manual.content.keywords.slice(i + 1), + ], + } }, })); }; @@ -115,22 +121,22 @@ class DocumentView extends React.Component { e.preventDefault(); this.setState(prevState => ({ manual: { - ...prevState.manual, - texts: [ - ...prevState.manual.texts.slice(0, i), - ...prevState.manual.texts.slice(i + 1), - ], + content: { + ...prevState.manual.content, + texts: [ + ...prevState.manual.content.texts.slice(0, i), + ...prevState.manual.content.texts.slice(i + 1), + ], + } }, })); }; deleteDocument = (e, i) => { e.preventDefault(); - const document = { data: { id: this.props.id } }; fetchData( - process.env.REACT_APP_SERVER_URL + 'v1/web/doc', - 'DELETE', - document + process.env.REACT_APP_SERVER_URL + 'v2/content/' + this.props.id + '/', + 'DELETE' ).then(() => { this.props.changeView('main'); }); @@ -140,7 +146,7 @@ class DocumentView extends React.Component { let textAreasManual; if (this.state.manual) { /* map through the texts field from manual */ - textAreasManual = this.state.manual.texts.map((text, i) => ( + textAreasManual = this.state.manual.content.texts.map((text, i) => (