def extract_tas_action_result(reg_object): action_line = reg_object.group(4) action_reg_object = re.match("(\S+)/(\d+)", action_line) if (action_reg_object): action = action_reg_object.group(1) message_id = None if (action == "plays"): message_id = tas_command_type.RESULT_PLAY elif (action == "says"): message_id = tas_command_type.RESULT_SAY elif (action == "collects"): message_id = tas_command_type.RESULT_COLLECT else: logging.error( "Unkown result action from TAS is detected '%s'.", action) return None return { struct_field.id: message_id, struct_field.account_id: reg_object.group(1), struct_field.script_id: reg_object.group(2), struct_field.session_id: reg_object.group(3), struct_field.action_id: action_reg_object.group(2) } else: logging.error( "Unkown result action format from TAS is detected '%s'.", action) return None
def __get_failure_descriptor(section, key): failure = [None, None] success = True if (configuration.get_failure_mode_enable() is True): failure_descriptor = configuration.__get_section( section)[key].lstrip().rstrip() failure = failure_descriptor.split() if (len(failure) == 2): try: failure[0] = int(failure[0]) except: success = False elif (len(failure) == 1): try: failure[0] = int(failure[0]) failure.append("") except: success = False else: success = False if (success is not True): logging.error("Impossible to extract failure descriptor '%s'.", failure_descriptor) return failure
def __get_integer(section, key): try: return int(configuration.__get_section(section)[key]) except: logging.error("Impossible extract integer value '%s'.", configuration.__get_section(section)[key]) return None
def get_variable(self, name): if (name not in self.__variables): logging.error( "Impossible to get value of variable '%s' because it does not exist.", name) return None return self.__variables[name]
def load(): if (os.path.isfile(configuration.__configuration_filename) is False): logging.error("Impossible to find configuration file.") return os._exit(error_code.ERROR_CONFIGURATION_NOT_FOUND) configuration.__configuration_instance = ConfigParser.ConfigParser() configuration.__configuration_instance.read( configuration.__configuration_filename) return True
def evaluate(self): (variables_names, variables_values) = self.__extract_variables(); for index_variable in range(len(variables_names)): internal_variable_name = "variables_values[" + str(index_variable) + "]"; self.__expression = self.__expression.replace(variables_names[index_variable], internal_variable_name); result = None; try: result = eval(self.__expression); except: logging.error("Impossible to evaluate expression '%s'.", self.__expression); return result;
def load(script_id): script_filepath = os.path.join(script.__DEFAULT_FOLDER, script_id); if (script_filepath is False): logging.error("Impossible to load script because it does not exist."); os._exit(error_code.ERROR_SCRIPT_NOT_FOUND); with open(script_filepath) as file_descriptor: content = file_descriptor.readlines(); block = code_block(0, content); block.load(); return block;
def send_request(self, http_method, http_link, json_request): response_status = 404 response_body = None connection = httplib.HTTPConnection(self.__address, self.__port, timeout=1) try: logging.debug("Send HTTP request to TAS (%s:%s): '%s' '%s'.", self.__address, self.__port, http_method, http_link) logging.debug("JSON payload of the HTTP request to TAS: '%s'.", json_request) headers = { 'Content-Type': 'application/json' } body = None if (json_request is not None): body = json_request.encode("utf-8") headers['Content-Length'] = len(body) statistical.inc_ivr_requests() connection.request(http_method, http_link, body, headers) logging.debug("Check for HTTP response from TAS.") response = connection.getresponse() response_status = response.status logging.debug("Read body of the HTTP response from TAS.") response_body = response.read() statistical.inc_ivr_responses() logging.debug("HTTP response (code: %d) from TAS:\n%s", response_status, response_body) except: response_status = 404 logging.error( "Impossible to communicate correctly with TAS using HTTP.") finally: connection.close() return (response_status, response_body)
def __run(self): logging.debug("(IVR session '%s') session '%s' is started at '%s'.", self.__context.get_id(), self.__context.get_id(), time.ctime()); with self.__code_block_locker: command_container = self.__context.get_next_command(); while( (self.__active is True) and (command_container is not None) ): (command, arguments) = command_container; if (command == command_type.COMMAND_SEND): self.__process_send_command(arguments[0], arguments[1], arguments[2]); elif (command == command_type.COMMAND_TIMEOUT): self.__process_timeout_command(arguments[0]); elif (command == command_type.COMMAND_WAIT): self.__process_wait_command(arguments[0]); elif (command == command_type.COMMAND_PRINT): self.__process_print_comand(arguments[0]); elif (command == command_type.COMMAND_EXIT): logging.info("(IVR session '%s') exit command is detected - termination...", self.__context.get_id()); self.__active = False; elif (command == command_type.COMMAND_MOVE_JSON): self.__process_move_json(arguments[0]); elif (command == command_type.COMMAND_IF): self.__process_conditional_block(arguments[0], arguments[1]); else: logging.error("(IVR session '%s') unexpected command is detected...", self.__context.get_id()); with self.__code_block_locker: command_container = self.__context.get_next_command(); self.__manager.delete(self.__context.get_id(), internal = True); logging.info("(IVR session '%s') session is terminated at '%s'.", self.__context.get_id(), time.ctime());
def parse(method, path): if (method == http_method.HTTP_POST): reg_object = re.match( "/telephony/v1/account/(\d+)/distribution-services/ivrs/(\d+)/instances$", path) if (reg_object): return http_parser.extract_ivr_start_request(reg_object) reg_object = re.match( "/telephony/v1/account/(\d+)/distribution-services/ivrs/(\d+)/instances/(\d+)/actions/(.*)", path) if (reg_object): return http_parser.extract_tas_action_result(reg_object) elif (method == http_method.HTTP_DELETE): reg_object = re.match( "/telephony/v1/account/(\d+)/distribution-services/ivrs/(\d+)/instances/(\d+)", path) if (reg_object): return http_parser.extract_ivr_stop_request(reg_object) elif (method == http_method.HTTP_GET): reg_object = re.match( "/telephony/v1/account/(\d+)/distribution-services/ivrs/(\d+)/instances/(\d+)", path) if (reg_object): return http_parser.extract_ivr_execution_status(reg_object) reg_object = re.match( "/telephony/v1/account/(\d+)/distribution-services/status(.*)", path) if (reg_object): return http_parser.extract_ivr_service_status(reg_object) else: logging.error("HTTP method '%s' is not supported.", method) return None
def __extract_variables(self): variables_names = []; variables_values = []; start_variable = self.__expression.find("$(", 0) while (start_variable >= 0): stop_variable = self.__expression.find(")", start_variable + 1); if (stop_variable < 0): logging.error("Impossible to parse expression with variable - incorrect format of variables (expression: '%s').", self.__expression); break; # extract variable name variable_name = self.__expression[start_variable : stop_variable + 1]; if (variable_name not in self.__context.get_variables()): logging.error("Impossible to find variable '%s' because of not declaration (expression: '%s').", variable_name, self.__expression); break; if (variable_name not in variables_names): variables_names.append(variable_name); variables_values.append(self.__context.get_variable(variable_name)); start_variable = self.__expression.find("$(", stop_variable); return (variables_names, variables_values);
def __process_send_command(self, method, tas_content, arguments): logging.debug("(IVR session '%s') command SEND is executing...", self.__context.get_id()); tas_link = None; tas_method = None; if (method == "SAY"): tas_link = self.__context.get_tas_link_say(); tas_method = "POST"; elif (method == "STOP_SAY"): tas_link = self.__context.get_tas_link_stop_say(); tas_method = "DELETE"; elif (method == "PLAY"): tas_link = self.__context.get_tas_link_play(); tas_method = "POST"; elif (method == "STOP_PLAY"): tas_link = self.__context.get_tas_link_stop_play(); tas_method = "DELETE"; elif (method == "COLLECT"): tas_link = self.__context.get_tas_link_collect(); tas_method = "POST"; elif (method == "STOP_COLLECT"): tas_link = self.__context.get_tas_link_stop_collect(); tas_method = "DELETE"; elif (method == "FORWARD"): tas_link = self.__context.get_tas_link_forward(); tas_method = "PUT"; elif (method == "EXCEPTION"): tas_link = self.__context.get_tas_link_exception(); tas_method = "PUT"; if (len(arguments) > 0): tas_link_pattern = arguments[0]; tas_link = self.__change_tas_link(tas_link, tas_link_pattern); tas_content = self.__translate_content(tas_content); logging.info("(IVR session '%s') send command request to TAS ('%s', '%s').", self.__context.get_id(), tas_method, method); (status, json_response) = self.__send(tas_method, tas_link, tas_content); if ( (status >= 200) and (status <= 299) ): if (tas_method == "POST"): response = json.loads(json_response); if (response.get("id", None) == None): logging.error("(IVR session '%s') TAS reply to '%s' command '%s' without JSON body with 'id' key.", self.__context.get_id(), tas_method, method); else: action_id = response['id']; if (method == "SAY"): self.__context.set_say_id(action_id); elif (method == "PLAY"): self.__context.set_play_id(action_id); elif (method == "COLLECT"): self.__context.set_collect_id(action_id); logging.info("(IVR session '%s') TAS accepts '%s' command '%s' and return action id: '%s'.", self.__context.get_id(), tas_method, method, action_id) else: logging.warning("(IVR session '%s') TAS reply to '%s' command '%s' by failure status (code: '%d').", self.__context.get_id(), tas_method, method, status);
def do_POST(self): tas_host, tas_port = self.client_address[:2] logging.info( "Receive HTTP POST request from TAS: '%s' (address: '%s:%s').", self.path, tas_host, tas_port) request = http_parser.parse(http_method.HTTP_POST, self.path) if (request == None): self.__send_response(http_code.HTTP_BAD_REQUEST, "\"Impossible to parse POST request.\"") return # # TAS_IVR_START_REQ # if (request[struct_field.id] == tas_command_type.IVR_START): if (configuration.get_failure_start_ivr_code() is not None): self.__send_response( configuration.get_failure_start_ivr_code(), None, configuration.get_failure_start_ivr_message()) return # extract TAS request for session and attach additional information json_request = self.rfile.read(int(self.headers['Content-Length'])) tas_request = json.loads(json_request) tas_request["tas_address"] = { "ip": tas_host, "port": tas_port } tas_request["account_id"] = request[struct_field.account_id] session_id = self.__get_session_manager().create( request[struct_field.script_id], tas_request) if (session_id is None): self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"") return json_response = json_builder.start_ivr_response(session_id) self.__send_response(http_code.HTTP_OK_CREATED, json_response) self.__get_session_manager().launch(session_id) # # RESULT_ACTION # elif (request[struct_field.id] == tas_command_type.RESULT_COLLECT or request[struct_field.id] == tas_command_type.RESULT_PLAY or request[struct_field.id] == tas_command_type.RESULT_SAY): if (configuration.get_failure_action_result_code() is not None): self.__send_response( configuration.get_failure_action_result_code(), None, configuration.get_failure_action_result_message()) return session_id = request[struct_field.session_id] message_id = request[struct_field.id] # script_id = request[struct_field.script_id]; json_result = self.rfile.read(int(self.headers['Content-Length'])) logging.info("Callback action result is received (id: '%d').", request[struct_field.id]) logging.debug("Content of the callback result:\n%s", json_result) # it is represented by map because most probably other staff may be conveyed to session. json_instance = None try: json_instance = json.loads(json_result) except: logging.error( "Impossible to parse JSON - corrupted JSON payload is received." ) self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Corrupted JSON payload in POST request.\"") return message_playload = { 'json': json_instance } if (self.__get_session_manager().exist(session_id)): reply_code = self.__get_session_manager().notify( session_id, message_id, message_playload) reply_message = None if (reply_code is None): reply_code = http_code.HTTP_OK reply_message = "\"Success.\"" else: reply_message = "\"Specified reply code is used.\"" self.__send_response(reply_code, reply_message) return self.__send_response( http_code.HTTP_NOT_FOUND, "\"Session '" + str(session_id) + "' is not found.\"") else: self.__send_response( http_code.HTTP_BAD_REQUEST, "\"Unknown POST type command '" + str(request[struct_field.id]) + "'.\"") return