Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
 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
Exemple #4
0
    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]
Exemple #5
0
    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
Exemple #6
0
    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;
Exemple #7
0
 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;
Exemple #8
0
    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)
Exemple #9
0
 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());
Exemple #10
0
    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
Exemple #11
0
 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);
Exemple #12
0
    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);
Exemple #13
0
    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