예제 #1
0
    def do_GET(self):
        logging.info("Receive GET media request: '%s'.", self.path)

        reg_object = re.match("/media/(\S+)", self.path)
        if (reg_object is None):
            self.reply(404)
            return

        media_name = reg_object.group(1)
        media_filepath = os.path.join(os.path.dirname(__file__),
                                      configuration.get_media_storage(),
                                      media_name)
        if (media_filepath is False):
            self.reply(404)
            return

        if (os.path.isfile(media_filepath) is False):
            self.reply(404)
            return

        media_descriptior = open(media_filepath)
        file_stat = os.fstat(media_descriptior.fileno())

        self.send_response(200)
        self.send_header('Content-type', 'audio/x-wav')
        self.send_header('Content-Length', file_stat.st_size)
        self.send_header('Accept-Ranges', 'bytes')
        self.end_headers()

        self.wfile.write(media_descriptior.read())

        media_descriptior.close()

        logging.info("Sent audio file '%s'.", media_name)
예제 #2
0
 def stop(self):
     with self.__code_block_locker:
         self.__context.insert_code_block([ (command_type.COMMAND_EXIT, "") ]);
         reply_code = self.notify(tas_command_type.IVR_STOP);
     
     logging.info("Stop command from session manager is received (reply code: '%s').", str(reply_code));
     
     return reply_code;
예제 #3
0
    def do_GET(self):
        tas_host, tas_port = self.client_address[:2]

        logging.info(
            "Receive HTTP GET request from TAS: '%s' (address: '%s:%s').",
            self.path, tas_host, tas_port)
        request = http_parser.parse(http_method.HTTP_GET, self.path)

        if (request == None):
            self.__send_response(http_code.HTTP_BAD_REQUEST,
                                 "\"Impossible to parse GET request.\"")
            return

        #
        # TAS_IVR_EXECUTION_STATUS
        #
        if (request[struct_field.id] == tas_command_type.EXECUTION_STATUS):
            if (configuration.get_failure_execution_status_code() is not None):
                self.__send_response(
                    configuration.get_failure_execution_status_code(), None,
                    configuration.get_failure_execution_status_message())
                return

            session_id = request[struct_field.session_id]
            #script_id   = request[struct_field.script_id];

            if (self.__get_session_manager().exist(session_id)):
                json_response = json_builder.execution_status_response("Ok")
                self.__send_response(http_code.HTTP_OK, json_response)

            else:
                self.__send_response(
                    http_code.HTTP_NOT_FOUND,
                    "\"Session '" + str(session_id) + "' is not found.\"")

        #
        # TAS_IVR_SERVICE_STATUS
        #
        elif (request[struct_field.id] == tas_command_type.SERVICE_STATUS):
            if (configuration.get_failure_service_status_code() is not None):
                self.__send_response(
                    configuration.get_failure_service_status_code(), None,
                    configuration.get_failure_service_status_message())
                return

            json_response = json_builder.service_status_response(
                "Ok",
                {"amount_sessions": session_manager.get_amount_sessions()})
            self.__send_response(http_code.HTTP_OK, json_response)

        else:
            self.__send_response(
                http_code.HTTP_BAD_REQUEST, "\"Unknown GET type command '" +
                str(request[struct_field.id]) + "'.\"")
예제 #4
0
    def __run(self):
        while (self.__stop_flag is not True):
            with self.__stop_condition:
                self.__stop_condition.wait(self.__logging_period_seconds)

            logging.info(
                "IVR Simulator statistics:\n\n"
                "\tTAS REQs (in):  %4d,    TAS RESPs (in):  %4d\n"
                "\tIVR REQs (out): %4d,    IVR RESPs (out): %4d\n\n",
                statistical.get_tas_requests(),
                statistical.get_tas_responses(),
                statistical.get_ivr_requests(),
                statistical.get_ivr_responses())
예제 #5
0
    def notify(self, tas_notification_id, message_payload = None):
        reply_code = None;
        string_message_id = tas_command_type.to_string(tas_notification_id);
        
        with self.__code_block_locker:
            trigger = self.__context.get_trigger(string_message_id);
            if (trigger is not None):
                self.__context.insert_code_block(trigger.commands);
                reply_code = trigger.reply_code;
                
                logging.info("Code block for the message '%s' is found (reply code: '%s').", string_message_id, str(reply_code));

        with self.__tas_response_condition:
            self.__context.set_last_input_message((tas_notification_id, message_payload));
            self.__tas_responses.append(string_message_id);
            self.__tas_response_condition.notify_all();
        
        return reply_code;
예제 #6
0
    def do_DELETE(self):
        tas_host, tas_port = self.client_address[:2]

        logging.info(
            "Receive HTTP DELETE request from TAS: '%s' (address: '%s:%s').",
            self.path, tas_host, tas_port)
        request = http_parser.parse(http_method.HTTP_DELETE, self.path)

        if (request == None):
            self.__send_response(http_code.HTTP_BAD_REQUEST,
                                 "\"Impossible to parse DELETE request.\"")
            return

        #
        # TAS_IVR_STOP_REQ
        #
        if (request[struct_field.id] != tas_command_type.IVR_STOP):
            self.__send_response(
                http_code.HTTP_BAD_REQUEST, "\"Unknown DELETE type command '" +
                str(request[struct_field.id]) + "'.\"")
            return

        if (configuration.get_failure_stop_ivr_code() is not None):
            self.__send_response(configuration.get_failure_stop_ivr_code(),
                                 None,
                                 configuration.get_failure_stop_ivr_message())
            return

        session_id = request[struct_field.session_id]
        # script_id   = request[struct_field.script_id];

        if (self.__get_session_manager().exist(session_id) is True):
            reply_code = self.__get_session_manager().delete(session_id)
            if (reply_code is None):
                reply_code = http_code.HTTP_OK_DELETED

            json_response = json_builder.stop_ivr_response()
            self.__send_response(reply_code, json_response)

        else:
            self.__send_response(
                http_code.HTTP_NOT_FOUND,
                "\"Session '" + str(session_id) + "' is not found.\"")
예제 #7
0
    def __send_response(self, http_code, json_data=None, http_message=None):
        time.sleep(configuration.get_response_delay() / 1000.0)

        self.send_response(http_code, http_message)
        self.send_header('Content-Type', 'application/json')

        body = None
        if (json_data is not None):
            body = json_data.encode("utf-8")
            self.send_header('Content-Length', len(body))

        self.end_headers()

        if (body is not None):
            self.wfile.write(body)

        statistical.inc_ivr_responses()

        logging.info(
            "Send response to TAS (HTTP code '%d (%s)', HTTP body '%s')",
            http_code, str(http_message), body)
예제 #8
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());
예제 #9
0
 def launch(session_id):
     with session_manager.__resource_locker:
         logging.info("Launch session instance (session id: '%s').",
                      session_id)
         session_manager.__sessions[session_id].start()
예제 #10
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);
예제 #11
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