Example #1
0
    def parse_grammar(self, element, uri=None):
        Grammar.parse_grammar(self, element, uri)

        # Extract Loop attribute
        loop = int(self.extract_attribute_value("loop"))
        if loop < 0:
            raise RESTFormatException("Play loop must be a positive integer")
        self.loop_times = loop
        # Pull out the text within the element
        audio_path = element.text.strip()

        if audio_path is None:
            raise RESTFormatException("No File for play given!")

        if not is_valid_url(audio_path):
            if file_exists(audio_path):
                self.sound_file_path = audio_path
        else:
            if url_exists(audio_path):
                if audio_path[-4:].lower() != '.mp3':
                    error_msg = "Only mp3 files allowed for remote file play"
                    print error_msg
                if audio_path[:7].lower() == "http://":
                    audio_path = audio_path[7:]
                elif audio_path[:8].lower() == "https://":
                    audio_path = audio_path[8:]
                elif audio_path[:6].lower() == "ftp://":
                    audio_path = audio_path[6:]
                else:
                    pass
                self.sound_file_path = "shout://%s" % audio_path
Example #2
0
    def parse_grammar(self, element, uri=None):
        Grammar.parse_grammar(self, element, uri)
        max_length = self.extract_attribute_value("maxLength")
        timeout = self.extract_attribute_value("timeout")
        action = self.extract_attribute_value("action")
        finish_on_key = self.extract_attribute_value("finishOnKey")
        self.file_path = self.extract_attribute_value("filePath")
        if self.file_path:
            self.file_path = os.path.normpath(self.file_path) + os.sep
        self.play_beep = self.extract_attribute_value("playBeep")
        self.format = self.extract_attribute_value("format")
        self.prefix = self.extract_attribute_value("prefix")
        method = self.extract_attribute_value("method")
        if method != 'GET' and method != 'POST':
            raise RESTAttributeException("Method must be 'GET' or 'POST'")
        self.method = method

        if max_length < 0:
            raise RESTFormatException("Record 'maxLength' must be a positive integer")
        self.max_length = max_length
        if timeout < 0:
            raise RESTFormatException("Record 'timeout' must be positive")
        self.timeout = timeout
        if action and is_valid_url(action):
            self.action = action
        else:
            self.action = uri
        # :TODO Validate Finish on Key
        self.finish_on_key = finish_on_key
Example #3
0
    def parse_element(self, element, uri=None):
        Element.parse_element(self, element, uri)
        # Extract Loop attribute
        try:
            loop = int(self.extract_attribute_value("loop", 1))
        except ValueError:
            loop = 1
        if loop < 0:
            raise RESTFormatException("Play 'loop' must be a positive integer or 0")
        self.loop_times = loop
        # Pull out the text within the element
        audio_path = element.text.strip()

        if not audio_path:
            raise RESTFormatException("No File to play set !")

        if not is_valid_url(audio_path):
            if file_exists(audio_path):
                self.sound_file_path = audio_path
        else:
            if url_exists(audio_path):
                if audio_path[-4:].lower() != '.mp3':
                    raise RESTFormatException("Only mp3 files allowed for remote file play")
                if audio_path[:7].lower() == "http://":
                    audio_path = audio_path[7:]
                elif audio_path[:8].lower() == "https://":
                    audio_path = audio_path[8:]
                elif audio_path[:6].lower() == "ftp://":
                    audio_path = audio_path[6:]
                else:
                    pass
                self.sound_file_path = "shout://%s" % audio_path
Example #4
0
 def parse_grammar(self, element, uri=None):
     Grammar.parse_grammar(self, element, uri)
     method = self.extract_attribute_value("method")
     if not method in ('GET', 'POST'):
         raise RESTAttributeException("Method must be 'GET' or 'POST'")
     self.method = method
     url = element.text.strip()
     if not url:
         raise RESTFormatException("Redirect must have a URL")
     if not is_valid_url(url):
         raise RESTFormatException("Redirect URL not valid!")
     self.url = url
Example #5
0
    def parse_grammar(self, element, uri=None):
        Grammar.parse_grammar(self, element, uri)
        num_digits = int(self.extract_attribute_value("numDigits"))
        if num_digits > self.DEFAULT_MAX_DIGITS:
            num_digits = self.DEFAULT_MAX_DIGITS
        if num_digits < 1:
            raise RESTFormatException("GetDigits 'numDigits' must be greater than 0")
        try:
            timeout = int(self.extract_attribute_value("timeout"))
        except ValueError:
            timeout = self.DEFAULT_TIMEOUT * 1000
        if timeout < 0:
            raise RESTFormatException("GetDigits 'timeout' must be a positive integer")

        finish_on_key = self.extract_attribute_value("finishOnKey")
        play_beep = self.extract_attribute_value("playBeep")
        self.invalid_digits_sound = \
                            self.extract_attribute_value("invalidDigitsSound")
        self.valid_digits = self.extract_attribute_value("validDigits")
        action = self.extract_attribute_value("action")

        try:
            retries = int(self.extract_attribute_value("retries"))
        except ValueError:
            retries = 1
        if retries < 0:
            raise RESTFormatException("GetDigits 'retries' must be greater than 0")

        method = self.extract_attribute_value("method")
        if method != 'GET' and method != 'POST':
            raise RESTAttributeException("Method, must be 'GET' or 'POST'")
        self.method = method

        if play_beep == 'true':
            self.play_beep = True
        else:
            self.play_beep = False
        if action and is_valid_url(action):
            self.action = action
        else:
            self.action = uri
        self.num_digits = num_digits
        self.timeout = timeout * 1000
        self.finish_on_key = finish_on_key
        self.retries = retries
Example #6
0
File: api.py Project: samof76/plivo
    def transfer_call(self):
        """Transfer Call
        Realtime call transfer allows you to interrupt an in-progress
        call and place it another scenario.

        To transfer a live call, you make an HTTP POST request to a
        resource URI.

        POST Parameters
        ---------------
        The following parameters are available for you to POST when transfering
        a phone call:

        CallUUID: Unique Call ID to which the action should occur to.

        URL: A valid URL that returns RESTXML. Plivo will immediately fetch
              the XML and continue the call as the new XML.
        """
        msg = ""
        result = False

        call_uuid = get_post_param(request, 'CallUUID')
        new_xml_url = get_post_param(request, 'Url')

        if not call_uuid:
            msg = "CallUUID Parameter must be present"
            return flask.jsonify(Success=result, Message=msg)
        elif not new_xml_url:
            msg = "URL Parameter must be present"
            return flask.jsonify(Success=result, Message=msg)
        elif not is_valid_url(new_xml_url):
            msg = "URL is not Valid"
            return flask.jsonify(Success=result, Message=msg)
        msg = "Call UUID must be present with URL"
        res = self._rest_inbound_socket.transfer_call(new_xml_url,
                                                      call_uuid)
        if res:
            msg = "Transfer Call Executed"
            result = True
        else:
            msg = "Transfer Call Failed"
        return flask.jsonify(Success=result, Message=msg)
Example #7
0
 def _prepare_moh(self):
     mohs = []
     if not self.dial_music:
         return mohs
     for audio_path in self.dial_music.split(','):
         if not is_valid_url(audio_path):
             if file_exists(audio_path):
                 mohs.append(audio_path)
         else:
             if url_exists(audio_path):
                 if audio_path[-4:].lower() != '.mp3':
                     raise RESTFormatException("Only mp3 files allowed for remote file play")
                 if audio_path[:7].lower() == "http://":
                     audio_path = audio_path[7:]
                 elif audio_path[:8].lower() == "https://":
                     audio_path = audio_path[8:]
                 elif audio_path[:6].lower() == "ftp://":
                     audio_path = audio_path[6:]
                 else:
                     pass
                 mohs.append("shout://%s" % audio_path)
     return mohs
Example #8
0
File: api.py Project: samof76/plivo
    def bulk_call(self):
        """Make Bulk Outbound Calls in one request
        Allow initiating bulk outbound calls via the REST API. To make a
        bulk outbound call, make an HTTP POST request to the resource URI.

        POST Parameters
        ----------------

        Required Parameters - You must POST the following parameters:

        From: The phone number to use as the caller id for the call without
        the leading +

        To: The number to call without the leading +

        Gateways: Comma separated string of gateways to dial the call out

        GatewayCodecs: Comma separated string of codecs for gateways

        GatewayTimeouts: Comma separated string of timeouts for gateways

        GatewayRetries: Comma separated string of retries for gateways

        AnswerUrl: The URL that should be requested for XML when the call
        connects. Similar to the URL for your inbound calls

        TimeLimit: Define the max time of the calls

        Optional Parameters - You may POST the following parameters:

        [HangUpUrl]: URL that Plivo will notify to, with POST params when
        calls ends

        [RingUrl]: URL that Plivo will notify to, with POST params when
        calls starts ringing

        [HangupOnRing]: If Set to 0 we will hangup as soon as the number ring,
        if set to value X we will wait X seconds when start ringing and then
        hang up

        [OriginateDialString]: Additional Originate dialstring to be executed
        while making the outbound call

        [SendDigits]: A string of keys to dial after connecting to the number.
        Valid digits in the string include: any digit (0-9), '#' and '*'.
        Very useful, if you want to connect to a company phone number,
        and wanted to dial extension 1234 and then the pound key,
        use SendDigits=1234#.
        Remember to URL-encode this string, since the '#' character has
        special meaning in a URL.
        To wait before sending DTMF to the extension, you can add leading 'w'
        characters. Each 'w' character waits 0.5 seconds instead of sending a
        digit.
        """
        msg = ""
        result = False
        request_uuid = ""

        request_uuid_list = []
        i = 0

        caller_id = get_post_param(request, 'From')
        to_str = get_post_param(request, 'To')
        gw_str = get_post_param(request, 'Gateways')
        answer_url = get_post_param(request, 'AnswerUrl')
        delimiter = get_post_param(request, 'Delimiter')

        if delimiter in (',', '/'):
            msg = "This Delimiter not allowed"
        elif not caller_id or not to_str or not gw_str or not answer_url or\
            not delimiter:
            msg = "Mandatory Parameters Missing"
        elif not is_valid_url(answer_url):
            msg = "Answer URL is not Valid"
        else:
            hangup_url = get_post_param(request, 'HangupUrl')
            ring_url = get_post_param(request, 'RingUrl')
            if hangup_url and not is_valid_url(hangup_url):
                msg = "Hangup URL is not Valid"
            elif ring_url and not is_valid_url(ring_url):
                msg = "Ring URL is not Valid"
            else:
                extra_dial_string = get_post_param(request,
                                                        'ExtraDialString')
                # Is a string of strings
                gw_codecs_str = get_post_param(request, 'GatewayCodecs')
                gw_timeouts_str = get_post_param(request, 'GatewayTimeouts')
                gw_retries_str = get_post_param(request, 'GatewayRetries')
                send_digits_str = get_post_param(request, 'SendDigits')
                time_limit_str = get_post_param(request, 'TimeLimit')
                hangup_on_ring_str = get_post_param(request, 'HangupOnRing')

                to_str_list = to_str.split(delimiter)
                gw_str_list = gw_str.split(delimiter)
                gw_codecs_str_list = gw_codecs_str.split(delimiter)
                gw_timeouts_str_list = gw_timeouts_str.split(delimiter)
                gw_retries_str_list = gw_retries_str.split(delimiter)
                send_digits_list = send_digits_str.split(delimiter)
                time_limit_list = time_limit_str.split(delimiter)
                hangup_on_ring_list = hangup_on_ring_str.split(delimiter)

                if len(to_str_list) < 2:
                    msg = "BulkCalls should be used for at least 2 numbers"
                elif len(to_str_list) != len(gw_str_list):
                    msg = "'To' parameter length does not match 'GW' Length"
                else:
                    for to in to_str_list:
                        try:
                            gw_codecs = gw_codecs_str_list[i]
                        except IndexError:
                            gw_codecs = ""
                        try:
                            gw_timeouts = gw_timeouts_str_list[i]
                        except IndexError:
                            gw_timeouts = ""
                        try:
                            gw_retries = gw_retries_str_list[i]
                        except IndexError:
                            gw_retries = ""
                        try:
                            send_digits = send_digits_list[i]
                        except IndexError:
                            send_digits = ""
                        try:
                            time_limit = time_limit_list[i]
                        except IndexError:
                            time_limit = ""
                        try:
                            hangup_on_ring = hangup_on_ring_list[i]
                        except IndexError:
                            hangup_on_ring = ""

                        call_req = self._prepare_call_request(
                                    caller_id, to, extra_dial_string,
                                    gw_str_list[i], gw_codecs, gw_timeouts, gw_retries,
                                    send_digits, time_limit, hangup_on_ring,
                                    answer_url, ring_url, hangup_url)
                        request_uuid = call_req.request_uuid
                        request_uuid_list.append(request_uuid)
                        self._rest_inbound_socket.call_requests[request_uuid] = call_req
                        i += 1

                    # now do the calls !
                    if self._rest_inbound_socket.bulk_originate(request_uuid_list):
                        msg = "BulkCalls Requests Executed"
                        result = True
                    else:
                        msg = "BulkCalls Requests Failed"
                        request_uuid_list = []

        return flask.jsonify(Success=result, Message=msg,
                             RequestUUID=request_uuid_list)
Example #9
0
File: api.py Project: samof76/plivo
    def call(self):
        """Make Outbound Call
        Allow initiating outbound calls via the REST API. To make an
        outbound call, make an HTTP POST request to the resource URI.

        POST Parameters
        ----------------

        Required Parameters - You must POST the following parameters:

        From: The phone number to use as the caller id for the call without
        the leading +

        To: The number to call without the leading +

        Gateways: Comma separated string of gateways to dial the call out

        GatewayCodecs: Comma separated string of codecs for gateways

        GatewayTimeouts: Comma separated string of timeouts for gateways

        GatewayRetries: Comma separated string of retries for gateways

        AnswerUrl: The URL that should be requested for XML when the call
        connects

        TimeLimit: Define the max time of the call

        Optional Parameters - You may POST the following parameters:

        [HangUpUrl]: URL that Plivo will notify to, with POST params when
        calls ends

        [RingUrl]: URL that Plivo will notify to, with POST params when
        calls starts ringing

        [HangupOnRing]: If Set to 0 we will hangup as soon as the number ring,
        if set to value X we will wait X seconds when start ringing and then
        hang up

        [OriginateDialString]: Additional Originate dialstring to be executed
        while making the outbound call

        [SendDigits]: A string of keys to dial after connecting to the number.
        Valid digits in the string include: any digit (0-9), '#' and '*'.
        Very useful, if you want to connect to a company phone number,
        and wanted to dial extension 1234 and then the pound key,
        use SendDigits=1234#.
        Remember to URL-encode this string, since the '#' character has
        special meaning in a URL.
        To wait before sending DTMF to the extension, you can add leading 'w'
        or 'W' characters. Each 'w' character waits 0.5 seconds and each 'W'
        character waits for 1.0 seconds instead of sending a digit.
        """
        msg = ""
        result = False
        request_uuid = ""

        caller_id = get_post_param(request, 'From')
        to = get_post_param(request, 'To')
        gw = get_post_param(request, 'Gateways')
        answer_url = get_post_param(request, 'AnswerUrl')

        if not caller_id or not to or not gw or not answer_url:
            msg = "Mandatory Parameters Missing"
        elif not is_valid_url(answer_url):
            msg = "Answer URL is not Valid"
        else:
            hangup_url = get_post_param(request, 'HangupUrl')
            ring_url = get_post_param(request, 'RingUrl')
            if hangup_url and not is_valid_url(hangup_url):
                msg = "Hangup URL is not Valid"
            elif ring_url and not is_valid_url(ring_url):
                msg = "Ring URL is not Valid"
            else:
                extra_dial_string = get_post_param(request, 'ExtraDialString')
                gw_codecs = get_post_param(request, 'GatewayCodecs')
                gw_timeouts = get_post_param(request, 'GatewayTimeouts')
                gw_retries = get_post_param(request, 'GatewayRetries')
                send_digits = get_post_param(request, 'SendDigits')
                time_limit = get_post_param(request, 'TimeLimit')
                hangup_on_ring = get_post_param(request, 'HangupOnRing')

                call_req = self._prepare_call_request(
                                    caller_id, to, extra_dial_string,
                                    gw, gw_codecs, gw_timeouts, gw_retries,
                                    send_digits, time_limit, hangup_on_ring,
                                    answer_url, ring_url, hangup_url)

                request_uuid = call_req.request_uuid
                self._rest_inbound_socket.call_requests[request_uuid] = call_req
                self._rest_inbound_socket.spawn_originate(request_uuid)
                msg = "Call Request Executed"
                result = True

        return flask.jsonify(Success=result,
                             Message=msg,
                             RequestUUID=request_uuid)
    def play_on_call(self, call_uuid="", sounds_list=[], legs="aleg", length=3600, schedule=0, mix=True, loop=False):
        cmds = []
        error_count = 0
        bleg = None

        # set flags
        if loop:
            aflags = "l"
            bflags = "l"
        else:
            aflags = ""
            bflags = ""
        if mix:
            aflags += "m"
            bflags += "mr"
        else:
            bflags += "r"

        if schedule <= 0:
            name = "Call Play"
        else:
            name = "Call SchedulePlay"
        if not call_uuid:
            self.log.error("%s Failed -- Missing CallUUID" % name)
            return False
        if not sounds_list:
            self.log.error("%s Failed -- Missing Sounds" % name)
            return False
        if not legs in ('aleg', 'bleg', 'both'):
            self.log.error("%s Failed -- Invalid legs arg '%s'" % (name, str(legs)))
            return False

        # get sound files
        sounds_to_play = []
        for sound in sounds_list:
            if is_valid_sound_proto(sound):
                sounds_to_play.append(sound)
            elif not is_valid_url(sound):
                if file_exists(sound):
                    sounds_to_play.append(sound)
                else:
                    self.log.warn("%s -- File %s not found" % (name, sound))
            else:
                url = normalize_url_space(sound)
                sound_file_path = get_resource(self, url)
                if sound_file_path:
                    sounds_to_play.append(sound_file_path)
                else:
                    self.log.warn("%s -- Url %s not found" % (name, url))
        if not sounds_to_play:
            self.log.error("%s Failed -- Sound files not found" % name)
            return False

        # build command
        play_str = '!'.join(sounds_to_play)
        play_aleg = 'file_string://%s' % play_str
        play_bleg = 'file_string://silence_stream://1!%s' % play_str

        # aleg case
        if legs == 'aleg':
            # add displace command
            for displace in self._get_displace_media_list(call_uuid):
                cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                cmds.append(cmd)
            cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_aleg, length, aflags)
            cmds.append(cmd)
        # bleg case
        elif legs  == 'bleg':
            # get bleg
            bleg = self.get_var("bridge_uuid", uuid=call_uuid)
            # add displace command
            if bleg:
                for displace in self._get_displace_media_list(call_uuid):
                    cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                    cmds.append(cmd)
                cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_bleg, length, bflags)
                cmds.append(cmd)
            else:
                self.log.error("%s Failed -- No BLeg found" % name)
                return False
        # both legs case
        elif legs == 'both':
            # get bleg
            bleg = self.get_var("bridge_uuid", uuid=call_uuid)
            # add displace commands
            for displace in self._get_displace_media_list(call_uuid):
                cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                cmds.append(cmd)
            cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_aleg, length, aflags)
            cmds.append(cmd)
            # get the bleg
            if bleg:
                cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_bleg, length, bflags)
                cmds.append(cmd)
            else:
                self.log.warn("%s -- No BLeg found" % name)
        else:
            self.log.error("%s Failed -- Invalid Legs '%s'" % (name, legs))
            return False

        # case no schedule
        if schedule <= 0:
            for cmd in cmds:
                res = self.api(cmd)
                if not res.is_success():
                    self.log.error("%s Failed '%s' -- %s" % (name, cmd, res.get_response()))
                    error_count += 1
            if error_count > 0:
                return False
            return True

        # case schedule
        sched_id = str(uuid.uuid1())
        for cmd in cmds:
            sched_cmd = "sched_api +%d %s %s" % (schedule, sched_id, cmd)
            res = self.api(sched_cmd)
            if res.is_success():
                self.log.info("%s '%s' with SchedPlayId %s" % (name, sched_cmd, sched_id))
            else:
                self.log.error("%s Failed '%s' -- %s" % (name, sched_cmd, res.get_response()))
                error_count += 1
        if error_count > 0:
            return False
        return sched_id
    def play_on_call(self, call_uuid="", sounds_list=[], legs="aleg", length=3600, schedule=0, mix=True, loop=False):
        cmds = []
        error_count = 0
        bleg = None

        # set flags
        if loop:
            aflags = "l"
            bflags = "l"
        else:
            aflags = ""
            bflags = ""
        if mix:
            aflags += "m"
            bflags += "mr"
        else:
            bflags += "r"

        if schedule <= 0:
            name = "Call Play"
        else:
            name = "Call SchedulePlay"
        if not call_uuid:
            self.log.error("%s Failed -- Missing CallUUID" % name)
            return False
        if not sounds_list:
            self.log.error("%s Failed -- Missing Sounds" % name)
            return False
        if not legs in ('aleg', 'bleg', 'both'):
            self.log.error("%s Failed -- Invalid legs arg '%s'" % (name, str(legs)))
            return False

        # get sound files
        sounds_to_play = []
        for sound in sounds_list:
            if is_valid_sound_proto(sound):
                sounds_to_play.append(sound)
            elif not is_valid_url(sound):
                if file_exists(sound):
                    sounds_to_play.append(sound)
                else:
                    self.log.warn("%s -- File %s not found" % (name, sound))
            else:
                url = normalize_url_space(sound)
                sound_file_path = get_resource(self, url)
                if sound_file_path:
                    sounds_to_play.append(sound_file_path)
                else:
                    self.log.warn("%s -- Url %s not found" % (name, url))
        if not sounds_to_play:
            self.log.error("%s Failed -- Sound files not found" % name)
            return False

        # build command
        play_str = '!'.join(sounds_to_play)
        play_aleg = 'file_string://%s' % play_str
        play_bleg = 'file_string://silence_stream://1!%s' % play_str

        # aleg case
        if legs == 'aleg':
            # add displace command
            for displace in self._get_displace_media_list(call_uuid):
                cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                cmds.append(cmd)
            cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_aleg, length, aflags)
            cmds.append(cmd)
        # bleg case
        elif legs  == 'bleg':
            # get bleg
            bleg = self.get_var("bridge_uuid", uuid=call_uuid)
            # add displace command
            if bleg:
                for displace in self._get_displace_media_list(call_uuid):
                    cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                    cmds.append(cmd)
                cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_bleg, length, bflags)
                cmds.append(cmd)
            else:
                self.log.error("%s Failed -- No BLeg found" % name)
                return False
        # both legs case
        elif legs == 'both':
            # get bleg
            bleg = self.get_var("bridge_uuid", uuid=call_uuid)
            # add displace commands
            for displace in self._get_displace_media_list(call_uuid):
                cmd = "uuid_displace %s stop %s" % (call_uuid, displace)
                cmds.append(cmd)
            cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_aleg, length, aflags)
            cmds.append(cmd)
            # get the bleg
            if bleg:
                cmd = "uuid_displace %s start %s %d %s" % (call_uuid, play_bleg, length, bflags)
                cmds.append(cmd)
            else:
                self.log.warn("%s -- No BLeg found" % name)
        else:
            self.log.error("%s Failed -- Invalid Legs '%s'" % (name, legs))
            return False

        # case no schedule
        if schedule <= 0:
            for cmd in cmds:
                res = self.api(cmd)
                if not res.is_success():
                    self.log.error("%s Failed '%s' -- %s" % (name, cmd, res.get_response()))
                    error_count += 1
            if error_count > 0:
                return False
            return True

        # case schedule
        sched_id = str(uuid.uuid1())
        for cmd in cmds:
            sched_cmd = "sched_api +%d %s %s" % (schedule, sched_id, cmd)
            res = self.api(sched_cmd)
            if res.is_success():
                self.log.info("%s '%s' with SchedPlayId %s" % (name, sched_cmd, sched_id))
            else:
                self.log.error("%s Failed '%s' -- %s" % (name, sched_cmd, res.get_response()))
                error_count += 1
        if error_count > 0:
            return False
        return sched_id
Example #12
0
 def run(self, outbound_socket):
     outbound_socket.log.info("Dial Started")
     dial_options = []
     numbers = []
     # Set timeout
     outbound_socket.set("call_timeout=%d" % self.timeout)
     outbound_socket.set("answer_timeout=%d" % self.timeout)
     # Set callerid
     if self.caller_id:
         caller_id = "effective_caller_id_number=%s" % self.caller_id
         dial_options.append(caller_id)
     # Set numbers to dial from Number nouns
     for child in self.children:
         if isinstance(child, Number):
             dial_num = self.create_number(child)
             if not dial_num:
                 continue
             numbers.append(dial_num)
     # Create dialstring
     self.dial_str = '{'
     self.dial_str += ','.join(dial_options)
     self.dial_str += '}'
     self.dial_str += ','.join(numbers)
     # Don't hangup after bridge !
     outbound_socket.set("hangup_after_bridge=false")
     # Set time limit: when reached, B Leg is hung up
     sched_hangup_id = str(uuid.uuid1())
     hangup_str = "api_on_answer=sched_api +%d %s uuid_transfer %s -bleg 'hangup:ALLOTTED_TIMEOUT' inline" \
                   % (self.time_limit, sched_hangup_id,
                      outbound_socket.get_channel_unique_id())
     outbound_socket.set(hangup_str)
     # Set hangup on '*'
     if self.hangup_on_star:
         outbound_socket.set("bridge_terminate_key=*")
     # Play Dial music or bridge the early media accordingly
     if self.dial_music:
         outbound_socket.set("bridge_early_media=true")
         outbound_socket.set("instant_ringback=true")
         outbound_socket.set("ringback=file_string://%s" % self.dial_music)
     else:
         outbound_socket.set("bridge_early_media=true")
     if self.confirm_sound:
         # Use confirm key if present else just play music
         if self.confirm_key:
             confirm_music_str = "group_confirm_file=%s" % self.confirm_sound
             confirm_key_str = "group_confirm_key=%s" % self.confirm_key
         else:
             confirm_music_str = "group_confirm_file=playback %s" % self.confirm_sound
             confirm_key_str = "group_confirm_key=exec"
         # Cancel the leg timeout after the call is answered
         outbound_socket.set("group_confirm_cancel_timeout=1")
         outbound_socket.set(confirm_music_str)
         outbound_socket.set(confirm_key_str)
     # Start dial
     outbound_socket.bridge(self.dial_str)
     event = outbound_socket._action_queue.get()
     reason = None
     originate_disposition = event['variable_originate_disposition']
     hangup_cause = originate_disposition
     if hangup_cause == 'ORIGINATOR_CANCEL':
         reason = '%s (A leg)' % hangup_cause
     else:
         reason = '%s (B leg)' % hangup_cause
     if not hangup_cause or hangup_cause == 'SUCCESS':
         hangup_cause = outbound_socket.get_hangup_cause()
         reason = '%s (A leg)' % hangup_cause
         if not hangup_cause:
             hangup_cause = outbound_socket.get_var('bridge_hangup_cause')
             reason = '%s (B leg)' % hangup_cause
             if not hangup_cause:
                 hangup_cause = outbound_socket.get_var('hangup_cause')
                 reason = '%s (A leg)' % hangup_cause
     outbound_socket.log.info("Dial Finished with reason: %s" \
                              % reason)
     # Unsched hangup
     outbound_socket.bgapi("sched_del %s" % sched_hangup_id)
     # Call url action
     if self.action and is_valid_url(self.action):
         self.fetch_rest_xml(self.action, method=self.method)
Example #13
0
 def execute(self, outbound_socket):
     dial_options = []
     numbers = []
     # Set timeout
     outbound_socket.set("call_timeout=%d" % self.timeout)
     outbound_socket.set("answer_timeout=%d" % self.timeout)
     # Set callerid or unset if not provided
     if self.caller_id:
         caller_id = "effective_caller_id_number=%s" % self.caller_id
         dial_options.append(caller_id)
     else:
         outbound_socket.unset("effective_caller_id_number")
     # Set ring flag if dial will ring.
     # But first set plivo_dial_rang to false
     # to be sure we don't get it from an old Dial
     outbound_socket.set("plivo_dial_rang=false")
     outbound_socket.set("execute_on_ring=eval ${uuid_setvar(%s plivo_dial_rang true}" \
                         % outbound_socket.get_channel_unique_id())
     # Set numbers to dial from Number nouns
     for child in self.children:
         if isinstance(child, Number):
             dial_num = self.create_number(child, outbound_socket)
             if not dial_num:
                 continue
             numbers.append(dial_num)
     if not numbers:
         outbound_socket.log.error("Dial Aborted, No Number to dial !")
         return
     # Create dialstring
     self.dial_str = '{'
     self.dial_str += ','.join(dial_options)
     self.dial_str += '}'
     self.dial_str += ','.join(numbers)
     # Don't hangup after bridge !
     outbound_socket.set("hangup_after_bridge=false")
     # Set time limit: when reached, B Leg is hung up
     sched_hangup_id = str(uuid.uuid1())
     hangup_str = "api_on_answer=sched_api +%d %s uuid_transfer %s -bleg 'hangup:ALLOTTED_TIMEOUT' inline" \
                   % (self.time_limit, sched_hangup_id,
                      outbound_socket.get_channel_unique_id())
     outbound_socket.set(hangup_str)
     # Set hangup on '*' or unset if not provided
     if self.hangup_on_star:
         outbound_socket.set("bridge_terminate_key=*")
     else:
         outbound_socket.unset("bridge_terminate_key")
     # Play Dial music or bridge the early media accordingly
     mohs = self._prepare_moh()
     if not mohs:
         outbound_socket.set("bridge_early_media=true")
         outbound_socket.unset("instant_ringback")
         outbound_socket.unset("ringback")
     else:
         outbound_socket.set("playback_delimiter=!")
         play_str = "file_string://silence_stream://1"
         for moh in mohs:
             play_str = "%s!%s" % (play_str, moh)
         outbound_socket.set("bridge_early_media=true")
         outbound_socket.set("instant_ringback=true")
         outbound_socket.set("ringback=%s" % play_str)
     # Set confirm sound and key or unset if not provided
     if self.confirm_sound:
         # Use confirm key if present else just play music
         if self.confirm_key:
             confirm_music_str = "group_confirm_file=%s" % self.confirm_sound
             confirm_key_str = "group_confirm_key=%s" % self.confirm_key
         else:
             confirm_music_str = "group_confirm_file=playback %s" % self.confirm_sound
             confirm_key_str = "group_confirm_key=exec"
         # Cancel the leg timeout after the call is answered
         outbound_socket.set("group_confirm_cancel_timeout=1")
         outbound_socket.set(confirm_music_str)
         outbound_socket.set(confirm_key_str)
     else:
         outbound_socket.unset("group_confirm_cancel_timeout")
         outbound_socket.unset("group_confirm_file")
         outbound_socket.unset("group_confirm_key")
     # Start dial
     outbound_socket.log.info("Dial Started %s" % self.dial_str)
     outbound_socket.bridge(self.dial_str)
     event = outbound_socket.wait_for_action()
     reason = None
     originate_disposition = event['variable_originate_disposition']
     hangup_cause = originate_disposition
     if hangup_cause == 'ORIGINATOR_CANCEL':
         reason = '%s (A leg)' % hangup_cause
     else:
         reason = '%s (B leg)' % hangup_cause
     if not hangup_cause or hangup_cause == 'SUCCESS':
         hangup_cause = outbound_socket.get_hangup_cause()
         reason = '%s (A leg)' % hangup_cause
         if not hangup_cause:
             hangup_cause = outbound_socket.get_var('bridge_hangup_cause')
             reason = '%s (B leg)' % hangup_cause
             if not hangup_cause:
                 hangup_cause = outbound_socket.get_var('hangup_cause')
                 reason = '%s (A leg)' % hangup_cause
     outbound_socket.log.info("Dial Finished with reason: %s" \
                              % reason)
     # Unschedule hangup task
     outbound_socket.bgapi("sched_del %s" % sched_hangup_id)
     # Get ring status
     dial_rang = outbound_socket.get_var("plivo_dial_rang") == 'true'
     # If action is set, redirect to this url
     # Otherwise, continue to next Element
     if self.action and is_valid_url(self.action):
         params = {}
         if dial_rang:
             params['RingStatus'] = 'true'
         else:
             params['RingStatus'] = 'false'
         params['HangupCause'] = hangup_cause
         self.fetch_rest_xml(self.action, params, method=self.method)