def get_alerts_intent( mycity_request: MyCityRequestDataModel, get_alerts_function_for_test: typing.Callable[[], typing.Dict] = None, prune_normal_responses_function_for_test: typing.Callable[ [], typing.Dict] = None, alerts_to_speech_output_function_for_test: typing.Callable[ [], typing.AnyStr] = None ) -> MyCityResponseDataModel: """ Generate response object with information about citywide alerts :param mycity_request: MyCityRequestDataModel object :param get_alerts_function_for_test: Injectable function for unit tests :param prune_normal_responses_function_for_test: Injectable function for unit tests :param alerts_to_speech_output_function_for_test: Injectable function for unit tests :return: MyCityResponseDataModel object """ logger.debug('MyCityRequestDataModel received:' + mycity_request.get_logger_string()) alerts = get_alerts( ) if get_alerts_function_for_test is None else get_alerts_function_for_test( ) logger.debug("[dictionary with alerts scraped from boston.gov]:\n" + str(alerts)) pruned_alerts = prune_normal_responses(alerts) \ if prune_normal_responses_function_for_test is None else prune_normal_responses_function_for_test(alerts) logger.debug("[dictionary after pruning]:\n" + str(alerts)) mycity_response = _create_response_object() mycity_response.output_speech = alerts_to_speech_output(pruned_alerts) \ if alerts_to_speech_output_function_for_test is None else alerts_to_speech_output_function_for_test(pruned_alerts) return mycity_response
def get_inclement_weather_alert( mycity_request: MyCityRequestDataModel, get_alerts_function_for_test: typing.Callable[[], typing.Dict] = None, ) -> MyCityResponseDataModel: """ Generates a response with information about any inclement weather alerts. :param mycity_request: MyCityRequestDataModel object :param get_alerts_function_for_test: Injectable function for unit tests :return: MyCityResponseDataModel object """ logger.debug('MyCityRequestDataModel received:' + mycity_request.get_logger_string()) alerts = get_alerts( ) if get_alerts_function_for_test is None else get_alerts_function_for_test( ) logger.debug("[dictionary with alerts scraped from boston.gov]:\n" + str(alerts)) logger.debug("filtering for inclement weather alerts") output_speech = constants.NO_INCLEMENT_WEATHER_ALERTS if Services.ALERT_HEADER.value in alerts: if any(query in alerts[Services.ALERT_HEADER.value].lower() for query in SNOW_ALERT_QUERY): logger.debug("inclement weather alert found") output_speech = alerts[Services.ALERT_HEADER.value] mycity_response = _create_response_object() mycity_response.session_attributes = mycity_request.session_attributes mycity_response.output_speech = output_speech return mycity_response
def get_alerts_intent( mycity_request: MyCityRequestDataModel, get_alerts_function_for_test: typing.Callable[[], typing.Dict] = None, prune_normal_responses_function_for_test: typing.Callable[[], typing.Dict] = None, alerts_to_speech_output_function_for_test: typing.Callable[[], typing.AnyStr] = None ) -> MyCityResponseDataModel: """ Generate response object with information about citywide alerts :param mycity_request: MyCityRequestDataModel object :param get_alerts_function_for_test: Injectable function for unit tests :param prune_normal_responses_function_for_test: Injectable function for unit tests :param alerts_to_speech_output_function_for_test: Injectable function for unit tests :return: MyCityResponseDataModel object """ logger.debug('MyCityRequestDataModel received:' + mycity_request.get_logger_string()) # get the intent_variables and sessions_attribute object from the request intent_variables = mycity_request.intent_variables session_attributes = mycity_request.session_attributes service_name = intent_variables['ServiceName'].get('value') \ if 'ServiceName' in intent_variables else None if service_name: service_name = service_name.lower() session_alerts = session_attributes.get('alerts', None) if not session_alerts: session_alerts = get_pruned_alerts( get_alerts_function_for_test, prune_normal_responses_function_for_test) # Build the response. mycity_response = _create_response_object() mycity_response.session_attributes = session_attributes.copy() mycity_response.should_end_session = True if session_alerts is None: logger.debug( "Could not get alerts from session attributes or Boston webpage") mycity_response.should_end_session = False mycity_response.output_speech = constants.LAUNCH_REPROMPT_SPEECH return mycity_response if service_name is None: # If the user hasn't give us a service name, check if we should # list alerts if there are only a few, or ask the user to select one if len(session_alerts) > 1: mycity_response.session_attributes['alerts'] = session_alerts mycity_response.dialog_directive = "ElicitSlotServiceName" mycity_response.should_end_session = False mycity_response.output_speech = list_alerts_output(session_alerts) else: mycity_response.output_speech = \ alerts_to_speech_output(session_alerts) \ if alerts_to_speech_output_function_for_test is None \ else alerts_to_speech_output_function_for_test(session_alerts) elif service_name == 'all': # Respond with all alert text mycity_response.output_speech = \ alerts_to_speech_output(session_alerts) \ if alerts_to_speech_output_function_for_test is None \ else alerts_to_speech_output_function_for_test(session_alerts) elif service_name in session_alerts: # Grab the requested service alert alert = {service_name: session_alerts[service_name]} mycity_response.output_speech = alerts_to_speech_output(alert) \ if alerts_to_speech_output_function_for_test is None \ else alerts_to_speech_output_function_for_test(alert) else: # Service not found. Re-ask for the desired service. mycity_response.session_attributes['alerts'] = session_alerts mycity_response.should_end_session = False mycity_response.output_speech = constants.INVALID_SERVICE_NAME_SCRIPT mycity_response.output_speech += list_alerts_output(session_alerts) mycity_response.dialog_directive = "ElicitSlotServiceName" return mycity_response
def get_voting_location(mycity_request: MyCityRequestDataModel) -> \ MyCityResponseDataModel: """ Generates response object for a polling location inquiry which includes a user's location to vote. :param mycity_request: MyCityRequestDataModel object :return: MyCityResponseDataModel object """ logger.debug('MyCityRequestDataModel received:' + mycity_request.get_logger_string()) mycity_response = MyCityResponseDataModel() mycity_response.card_title = CARD_TITLE # check for address for locating voting location if intent_constants.CURRENT_ADDRESS_KEY not in \ mycity_request.session_attributes: mycity_request, location_permissions = \ get_address_from_user_device(mycity_request) if not location_permissions: return request_device_address_permission_response() elif intent_constants.CURRENT_ADDRESS_KEY not in \ mycity_request.session_attributes: return request_user_address_response(mycity_request) current_address = \ mycity_request.session_attributes[intent_constants.CURRENT_ADDRESS_KEY] # If we have more specific info then just the street # address, make sure we are in Boston if not is_address_in_city(current_address): mycity_response.output_speech = NOT_IN_BOSTON_SPEECH mycity_response.should_end_session = True mycity_response.card_title = CARD_TITLE return mycity_response # grab relevant information from session address parsed_address, _ = usaddress.tag(current_address) if not is_address_valid(parsed_address): mycity_response.output_speech = ADDRESS_NOT_UNDERSTOOD mycity_response.dialog_directive = "ElicitSlotVotingIntent" mycity_response.reprompt_text = None mycity_response.session_attributes = mycity_request.session_attributes mycity_response.card_title = CARD_TITLE mycity_response.should_end_session = True return clear_address_from_mycity_object(mycity_response) zipcode = None if "Zipcode" in mycity_request.intent_variables and \ "value" in mycity_request.intent_variables["Zipcode"]: zipcode = \ mycity_request.intent_variables["Zipcode"]["value"].zfill(5) mycity_response.reprompt_text = None mycity_response.should_end_session = True try: top_candidate = gis_utils.geocode_address(current_address, zipcode) ward_precinct = vote_utils.get_ward_precinct_info(top_candidate) poll_location = vote_utils.get_polling_location(ward_precinct) output_speech = LOCATION_SPEECH. \ format(poll_location[LOCATION_NAME], poll_location[LOCATION_ADDRESS]) mycity_response.output_speech = output_speech except ParseError: mycity_response.output_speech = NO_WARD_OR_PRECINCT except BadAPIResponse: mycity_response.output_speech = BAD_API_RESPONSE except MultipleAddressError as error: address_list = ', '.join(error.addresses) mycity_response.output_speech = MULTIPLE_ADDRESS_ERROR mycity_response.dialog_directive = "ElicitSlotZipCode" mycity_response.should_end_session = False return mycity_response