Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Intents To Use String Constants #163

Merged
merged 1 commit into from
Sep 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions mycity/mycity/intents/feedback_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
"""

from mycity.mycity_response_data_model import MyCityResponseDataModel
import mycity.intents.speech_constants.feedback_intent as speech_constants
import requests
import json
import os

SLACK_WEBHOOKS_URL = os.environ['SLACK_WEBHOOKS_URL']

CARD_TITLE = "Feedback"

def submit_feedback(mycity_request):
"""
Expand Down Expand Up @@ -49,13 +50,12 @@ def submit_feedback(mycity_request):
build_slack_message(feedback_type, feedback_text)
)
if status == 200:
mycity_response.output_speech = 'Thanks for your feedback.'
mycity_response.output_speech = speech_constants.BIG_THANKS
else:
mycity_response.output_speech = \
'There was a problem with your feedback. Please try again.'
mycity_response.output_speech = speech_constants.PROBLEM_SAVING_FEEDBACK
mycity_response.reprompt_text = None
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "Feedback"
mycity_response.card_title = CARD_TITLE
return mycity_response


Expand Down
6 changes: 4 additions & 2 deletions mycity/mycity/intents/get_alerts_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from urllib import request
from enum import Enum
from mycity.mycity_response_data_model import MyCityResponseDataModel
import mycity.intents.speech_constants.get_alerts_intent as constants

class Services(Enum):

Expand All @@ -46,6 +47,7 @@ class Services(Enum):
HEADER_2 = "str str--r m-v300"
HEADER_3 = "t--sans t--cb lh--000 m-b500"

ALERTS_INTENT_CARD_TITLE = "City Alerts"

def get_alerts_intent(mycity_request):
"""
Expand All @@ -66,7 +68,7 @@ def get_alerts_intent(mycity_request):
alerts = prune_normal_responses(alerts)
print("[dictionary after pruning]:\n" + str(alerts))
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "City Alerts"
mycity_response.card_title = ALERTS_INTENT_CARD_TITLE
mycity_response.reprompt_text = None
mycity_response.output_speech = alerts_to_speech_output(alerts)
mycity_response.should_end_session = True # leave this as True for right now
Expand All @@ -89,7 +91,7 @@ def alerts_to_speech_output(alerts):
for alert in alerts.values():
all_alerts += alert + ' '
if all_alerts.strip() == "": # this is a kludgy fix for the {'alert header': ''} bug
return "There are no alerts. City services are running on normal schedules."
return constants.NO_ALERTS
else:
return all_alerts

Expand Down
34 changes: 10 additions & 24 deletions mycity/mycity/intents/snow_parking_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,12 @@


import mycity.intents.intent_constants as intent_constants
import mycity.utilities.google_maps_utils as g_maps_utils
import mycity.intents.speech_constants.snow_parking_intent as constants
from mycity.utilities.finder.FinderCSV import FinderCSV
from mycity.mycity_response_data_model import MyCityResponseDataModel





# Constants
PARKING_INFO_URL = ("http://bostonopendata-boston.opendata.arcgis.com/datasets/"
"53ebc23fcc654111b642f70e61c63852_0.csv")
DRIVING_DIST = g_maps_utils.DRIVING_DISTANCE_TEXT_KEY
DRIVING_TIME = g_maps_utils.DRIVING_TIME_TEXT_KEY
OUTPUT_SPEECH_FORMAT = \
("The closest snow emergency parking lot, {Name}, is at "
"{Address}. It is {" + DRIVING_DIST + "} away and should take "
"you {" + DRIVING_TIME + "} to drive there. The lot has "
"{Spaces} spaces when empty. {Fee} {Comments} {Phone}")
PARKING_INFO_URL = "http://bostonopendata-boston.opendata.arcgis.com/datasets/53ebc23fcc654111b642f70e61c63852_0.csv"
SNOW_PARKING_CARD_TITLE = "Snow Parking"
ADDRESS_KEY = "Address"


Expand All @@ -32,10 +20,10 @@ def format_record_fields(record):
fields from the closest record
:return: None
"""
record["Phone"] = "Call {} for information.".format(record["Phone"]) \
if record["Phone"].strip() != "" else ""
record["Fee"] = " The fee is {}. ".format(record["Fee"]) \
if record["Fee"] != "No Charge" else " There is no fee. "
record["Phone"] = constants.PHONE_PREPARED_STRING.format(record["Phone"]) \
if record["Phone"].strip() != "" else constants.NO_PHONE
record["Fee"] = constants.FEE_PREPARED_STRING.format(record["Fee"]) \
if record["Fee"] != "No Charge" else constants.NO_FEE


def get_snow_emergency_parking_intent(mycity_request):
Expand All @@ -54,22 +42,20 @@ def get_snow_emergency_parking_intent(mycity_request):
mycity_response = MyCityResponseDataModel()
if intent_constants.CURRENT_ADDRESS_KEY in mycity_request.session_attributes:
finder = FinderCSV(mycity_request, PARKING_INFO_URL, ADDRESS_KEY,
OUTPUT_SPEECH_FORMAT, format_record_fields)
constants.OUTPUT_SPEECH_FORMAT, format_record_fields)
print("Finding snow emergency parking for {}".format(finder.origin_address))
finder.start()
mycity_response.output_speech = finder.get_output_speech()

else:
print("Error: Called snow_parking_intent with no address")
mycity_response.output_speech = "I need a valid address to find the closest parking"
mycity_response.output_speech = constants.ERROR_SPEECH

# Setting reprompt_text to None signifies that we do not want to reprompt
# the user. If the user does not respond or says something that is not
# understood, the session will end.
mycity_response.reprompt_text = None
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "Snow Parking"
mycity_response.card_title = SNOW_PARKING_CARD_TITLE

return mycity_response


1 change: 1 addition & 0 deletions mycity/mycity/intents/speech_constants/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
To make testing easier, put any utterances for your intent here
Empty file.
7 changes: 7 additions & 0 deletions mycity/mycity/intents/speech_constants/feedback_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Speech constants for feedback_intent.py

"""

BIG_THANKS = "Thanks for your feedback."
PROBLEM_SAVING_FEEDBACK = "There was a problem with your feedback. Please try again."
6 changes: 6 additions & 0 deletions mycity/mycity/intents/speech_constants/get_alerts_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""
Speech utterances for get_alerts_intent.py

"""

NO_ALERTS = "There are no alerts. City services are running on normal schedules."
20 changes: 20 additions & 0 deletions mycity/mycity/intents/speech_constants/snow_parking_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""
Speech utterances for snow_parking_intent.py

"""

import mycity.utilities.google_maps_utils as g_maps_utils

OUTPUT_SPEECH_FORMAT = \
("The closest snow emergency parking lot, {Name}, is at "
"{Address}. It is {" + g_maps_utils.DRIVING_DISTANCE_TEXT_KEY + "} away and should take "
"you {" + g_maps_utils.DRIVING_TIME_TEXT_KEY + "} to drive there. The lot has "
"{Spaces} spaces when empty. {Fee} {Comments} {Phone}")

# Formatted strings for the phone number and fee for the parking lot
PHONE_PREPARED_STRING = "Call {} for information."
FEE_PREPARED_STRING = " The fee is {}. "
NO_PHONE = ""
NO_FEE = " There is no fee. "

ERROR_SPEECH = "I need a valid address to find the closest parking"
10 changes: 10 additions & 0 deletions mycity/mycity/intents/speech_constants/trash_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""
Speech constants for the trash day intent

"""

PICK_UP_DAY = "Trash and recycling is picked up on {}."
ADDRESS_NOT_FOUND = "I can't seem to find {}. Try another address"
BAD_API_RESPONSE = "Hmm something went wrong. Maybe try again?"
MULTIPLE_ADDRESS_ERROR = "I found multiple places with the address {}. What's the zip code?"
ADDRESS_NOT_UNDERSTOOD = "I didn't understand that address, please try again"
7 changes: 7 additions & 0 deletions mycity/mycity/intents/speech_constants/unhandled_intent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"""
Speech constants for unhandled_intent.py

"""

REPROMPT_TEXT = "So, what can I help you with today?"
OUTPUT_SPEECH = "I'm not sure what you're asking me. Please ask again."
22 changes: 9 additions & 13 deletions mycity/mycity/intents/trash_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import re
import requests
from . import intent_constants
import mycity.intents.speech_constants.trash_intent as speech_constants

CARD_TITLE = "Trash Day"

def get_trash_day_info(mycity_request):
"""
Expand Down Expand Up @@ -48,45 +50,39 @@ def get_trash_day_info(mycity_request):
trash_days = get_trash_and_recycling_days(address, zip_code)
trash_days_speech = build_speech_from_list_of_days(trash_days)

mycity_response.output_speech = "Trash and recycling is picked up on {}."\
.format(trash_days_speech)
mycity_response.output_speech = speech_constants.PICK_UP_DAY.format(trash_days_speech)

except InvalidAddressError:
address_string = address
if zip_code:
address_string = address_string + " with zip code {}"\
.format(zip_code)
mycity_response.output_speech =\
"I can't seem to find {}. Try another address"\
.format(address_string)
mycity_response.output_speech = speech_constants.ADDRESS_NOT_FOUND.format(address_string)
mycity_response.dialog_directive = "ElicitSlotTrash"
mycity_response.reprompt_text = None
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "Trash Day"
mycity_response.card_title = CARD_TITLE
mycity_request = clear_address_from_mycity_object(mycity_request)
mycity_response = clear_address_from_mycity_object(mycity_response)
return mycity_response

except BadAPIResponse:
mycity_response.output_speech =\
"Hmm something went wrong. Maybe try again?"
mycity_response.output_speech = speech_constants.BAD_API_RESPONSE
except MultipleAddressError:
mycity_response.output_speech \
= "I found multiple places with the address {}. " \
"What's the zip code?".format(address)
mycity_response.output_speech = speech_constants.MULTIPLE_ADDRESS_ERROR.format(address)
mycity_response.dialog_directive = "ElicitSlotZipCode"

mycity_response.should_end_session = False
else:
print("Error: Called trash_day_intent with no address")
mycity_response.output_speech = "I didn't understand that address, please try again"
mycity_response.output_speech = speech_constants.ADDRESS_NOT_UNDERSTOOD

# Setting reprompt_text to None signifies that we do not want to reprompt
# the user. If the user does not respond or says something that is not
# understood, the session will end.
mycity_response.reprompt_text = None
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "Trash Day"
mycity_response.card_title = CARD_TITLE
return mycity_response


Expand Down
10 changes: 6 additions & 4 deletions mycity/mycity/intents/unhandled_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"""

from mycity.mycity_response_data_model import MyCityResponseDataModel
import mycity.intents.speech_constants.unhandled_intent as speech_constants

CARD_TITLE = "Unhandled"

def unhandled_intent(mycity_request):
"""
Expand All @@ -19,10 +22,9 @@ def unhandled_intent(mycity_request):
)
mycity_response = MyCityResponseDataModel()
mycity_response.session_attributes = mycity_request.session_attributes
mycity_response.card_title = "Unhandled"
mycity_response.reprompt_text = "So, what can I help you with today?"
mycity_response.output_speech = "I'm not sure what you're asking me. " \
"Please ask again."
mycity_response.card_title = CARD_TITLE
mycity_response.reprompt_text = speech_constants.REPROMPT_TEXT
mycity_response.output_speech = speech_constants.OUTPUT_SPEECH
mycity_response.should_end_session = False

return mycity_response
6 changes: 4 additions & 2 deletions mycity/mycity/test/integration_tests/test_get_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import mycity.test.integration_tests.intent_test_mixins as mix_ins
import mycity.test.integration_tests.intent_base_case as base_case
import mycity.test.test_constants as test_constants
import mycity.intents.get_alerts_intent as get_alerts
import mycity.intents.speech_constants.get_alerts_intent as get_alerts_speech_constants


########################################
Expand All @@ -13,7 +15,7 @@ class GetAlertsTestCase(mix_ins.RepromptTextTestMixIn,
base_case.IntentBaseCase):

intent_to_test = "GetAlertsIntent"
expected_title = 'City Alerts'
expected_title = get_alerts.ALERTS_INTENT_CARD_TITLE
returns_reprompt_text = False
# if we don't create copies of these dictionaries we'll create empty
# dictionary errors after successive setUps and tearDowns
Expand Down Expand Up @@ -42,7 +44,7 @@ def tearDown(self):
return_value=no_alerts.copy())
def test_response_with_no_alerts(self, mock_get_alerts):
response = self.controller.on_intent(self.request)
expected_response = test_constants.GET_ALERTS_EXPECTED_RESPONSE
expected_response = get_alerts_speech_constants.NO_ALERTS
self.assertEqual(response.output_speech, expected_response)

@mock.patch('mycity.intents.get_alerts_intent.get_alerts',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import mycity.test.integration_tests.intent_test_mixins as mix_ins
import mycity.test.integration_tests.intent_base_case as base_case
import mycity.test.test_constants as test_constants
import mycity.intents.snow_parking_intent as snow_parking


##########################################
Expand All @@ -15,9 +16,9 @@ class SnowEmergencyTestCase(mix_ins.RepromptTextTestMixIn,
base_case.IntentBaseCase):

intent_to_test = "SnowParkingIntent"
expected_title = "Snow Parking"
expected_title = snow_parking.SNOW_PARKING_CARD_TITLE
returns_reprompt_text = False
expected_card_title = "Snow Parking"
expected_card_title = snow_parking.SNOW_PARKING_CARD_TITLE

def setUp(self):
"""
Expand Down Expand Up @@ -45,8 +46,7 @@ def fake_filter(record):
test_constants.CLOSEST_PARKING_DRIVING_DATA
self.get_driving_info_patch = \
mock.patch(
('mycity.intents.snow_parking_intent.g_maps_utils'
'._get_driving_info'),
'mycity.utilities.finder.Finder.g_maps_utils._get_driving_info',
return_value=mock_get_driving_info_return
)
self.mock_filtered_record.start()
Expand Down
5 changes: 3 additions & 2 deletions mycity/mycity/test/integration_tests/test_trash_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import mycity.test.test_constants as test_constants
import mycity.test.integration_tests.intent_base_case as base_case
import mycity.test.integration_tests.intent_test_mixins as mix_ins
import mycity.intents.trash_intent as trash_intent


###################################
Expand All @@ -14,9 +15,9 @@ class TrashDayTestCase(mix_ins.RepromptTextTestMixIn,
base_case.IntentBaseCase):

intent_to_test = "TrashDayIntent"
expected_title = "Trash Day"
expected_title = trash_intent.CARD_TITLE
returns_reprompt_text = False
expected_card_title = "Trash Day"
expected_card_title = trash_intent.CARD_TITLE

def setUp(self):
"""
Expand Down
5 changes: 3 additions & 2 deletions mycity/mycity/test/integration_tests/test_unhandled_intent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mycity.test.integration_tests.intent_test_mixins as mix_ins
import mycity.test.integration_tests.intent_base_case as base_case
import mycity.intents.unhandled_intent as unhandled_intent


########################################
Expand All @@ -13,6 +14,6 @@ class UnhandledIntentTestCase(mix_ins.RepromptTextTestMixIn,
base_case.IntentBaseCase):

intent_to_test = "UnhandledIntent"
expected_title = "Unhandled"
expected_title = unhandled_intent.CARD_TITLE
returns_reprompt_text = True
expected_card_title = "Unhandled"
expected_card_title = unhandled_intent.CARD_TITLE
2 changes: 0 additions & 2 deletions mycity/mycity/test/test_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,8 +850,6 @@
'Alert header': 'Godzilla inbound!'
}

GET_ALERTS_EXPECTED_RESPONSE = "There are no alerts. City services are running on normal schedules."

# get_open_spaces intent

OPEN_SPACES_TEST_CSV = os.getcwd() + "/mycity/test/test_data/.csv"
Expand Down