
    >gpm                        d Z ddlZddlZddlZddlZddlmZ dZdZ ej                  d      Z
 ej                  d      Z G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d d      Zed k(  rP e       Zej7                  d!       ej9                           ej:                  d       	 ej=                  d"d!       ejC                  d$d%       ejE                  d$       	 ejE                  d&       	 ejG                  d$d%d&       ejG                  d$d(d)       ejG                  d$d*d+       ejI                  d$d%      Z%ej>                  jA                  d,e%z         ejI                  d%d$      Z%ej>                  jA                  d,e%z         ejM                  d$d%       ejO                  d$       ej9                          yy# e$ r ej>                  jA                  d#       Y 'w xY w# e$ r ej>                  jA                  d'       Y w xY w# e$ r ej>                  jA                  d-       Y w xY w).a  
.. module:: agi
   :synopsis: This module contains functions and classes to implment AGI scripts in python. 
   
pyvr

{'agi_callerid' : 'mars.putland.int',
 'agi_channel'  : 'IAX[kputland@kputland]/119',
 'agi_context'  : 'default',
 'agi_dnid'     : '1000',
 'agi_enhanced' : '0.0',
 'agi_extension': '1000',
 'agi_language' : 'en',
 'agi_priority' : '1',
 'agi_rdnis'    : '',
 'agi_request'  : 'pyst',
 'agi_type'     : 'IAX'}

Specification
-------------
    N)PY3i  i N  z(^\d*)\s*(.*)z6(?P<key>\w+)=(?P<value>[^\s]+)\s*(?:\((?P<data>.*)\))*c                       e Zd Zy)AGIExceptionN__name__
__module____qualname__     ?/opt/asterisk_venv/lib/python3.12/site-packages/asterisk/agi.pyr   r   '       r   r   c                       e Zd Zy)AGIErrorNr   r
   r   r   r   r   +   r   r   r   c                       e Zd Zy)AGIUnknownErrorNr   r
   r   r   r   r   /   r   r   r   c                       e Zd Zy)AGIAppErrorNr   r
   r   r   r   r   3   r   r   r   c                       e Zd Zy)	AGIHangupNr   r
   r   r   r   r   :   r   r   r   c                       e Zd Zy)AGISIGHUPHangupNr   r
   r   r   r   r   >   r   r   r   c                       e Zd Zy)AGISIGPIPEHangupNr   r
   r   r   r   r   B   r   r   r   c                       e Zd Zy)AGIResultHangupNr   r
   r   r   r   r   F   r   r   r   c                       e Zd Zy)
AGIDBErrorNr   r
   r   r   r   r   J   r   r   r   c                       e Zd Zy)AGIUsageErrorNr   r
   r   r   r   r   N   r   r   r   c                       e Zd Zy)AGIInvalidCommandNr   r
   r   r   r!   r!   R   r   r   r!   c                      e Zd ZdZej
                  ej                  ej                  fdZd Z	d Z
d Zd Zd Zd Zej
                  fd	Zd
 Zd ZefdZd6dZefdZd7dZd8dZd9dZd Zd6dZd6dZd6dZd6dZd6dZd6dZd:dZ edfdZ!d8dZ"d Z#d Z$d  Z%d:d!Z&d"d#e'dd$dfd%Z(d& Z)d6d'Z*d6d(Z+d) Z,d6d*Z-d+ Z.d, Z/d;d.Z0d<d/Z1d0 Z2d1 Z3d2 Z4d6d3Z5d4 Z6d5 Z7y-)=AGIz
    This class encapsulates communication between Asterisk an a python script.
    It handles encoding commands to Asterisk and parsing responses from
    Asterisk.
    c                    || _         || _        || _        d| _        t	        j                  t        j
                  | j                         | j                  j                  d       | j                  j                  t        t        j                               | j                  j                  d       i | _        | j                          y )NFzARGS: 
)stdinstdoutstderr_got_sighupsignalSIGHUP_handle_sighupwritestrsysargvenv_get_agi_env)selfr&   r'   r(   s       r   __init__zAGI.__init__]   s    
 fmmT%8%89(##chh-($r   c                 
   	 | j                   j                         j                         }t        r"t	        |      t
        u r|j                  d      }| j                  j                  d       | j                  j                  |       | j                  j                  d       |dk(  rnm|j                  d      d   dj                  |j                  d      dd        }}|j                         }|j                         }|dk7  r|| j                  |<   | j                  j                  d       | j                  j                  t        j                  | j                               | j                  j                  d       y )	N   utf8z
ENV LINE: r%    :r   zclass AGI: self.env = )r&   readlinestripr   typebytesdecoder(   r-   splitjoinr1   pprintpformat)r3   linekeydatas       r   r2   zAGI._get_agi_envi   s   ::&&(..0D:&t{{6/BKKl+KKd#KKd#rz

3*CHHTZZ_QR5H,IC))+C::<Dby $  	23&..23$r   c                     t        |t              rt        |      }t        |t              rt        |      }t        rdj                  d|dg      S dj                  d|j                  dd      dg      S )z? provides double quotes to string, converts int/bool to string r8   "r7   ignore)
isinstanceintr.   floatr   r@   encode)r3   strings     r   _quotez
AGI._quote}   sb    fc"v;&fe$v;&77C-..77Cvx!@#FGGr   c                     d| _         y)zHandle the SIGHUP signalTN)r)   )r3   signumframes      r   r,   zAGI._handle_sighup   s
    r   c                 2    | j                   rt        d      y)z;This function throws AGIHangup if we have recieved a SIGHUPzReceived SIGHUP from AsteriskN)r)   r   r3   s    r   test_hangupzAGI.test_hangup   s    !"ABB r   c                     | j                          	  | j                  |g|  | j                         S # t        $ r }|j                  dk(  rt        d       d }~ww xY w)N    zReceived SIGPIPE)rT   send_command
get_resultIOErrorerrnor   )r3   commandargses       r   executezAGI.execute   s_    	Dg--??$$ 	ww"}&'9::	s   "5 	AAAc                 L   |j                         }|ddj                  t        t        |            }|j                         }|d   dk7  r|dz  }| j                  j                  d|z         | j                  j                  |       | j                  j                          y)zSend a command to Asterisk r%   z    COMMAND: %sN)r;   r@   mapr.   r(   r-   r'   flushr3   r[   r\   s      r   rW   zAGI.send_command   s    --/$chhs3~&>?--/2;$tOG+g56'"r   c                    d}ddi}| j                   j                         j                         }t        r"t	        |      t
        u r|j                  d      }| j                  j                  d|z         t        j                  |      }|r|j                         \  }}t        |      }|dk(  r~t        j                        D ]3  \  }}}	||	f||<   |	dk(  rt        d      |dk(  s$|d	k(  s*t!        d
       | j                  j                  dt#        j$                  |      z         |S |dk(  rt'              |dk(  r|g}
| j                   j                         j                         }t        r"t	        |      t
        u r|j                  d      }|dd dk7  rj|
j)                  |       | j                   j                         j                         }t        r"t	        |      t
        u r|j                  d      }|dd dk7  rj|
j)                  |       ddj+                  |
      z  }
t-        |
      t/        |d      )z*Read the result of a command from Asteriskr   result)r8   r8   r7   z    RESULT_LINE: %s
   hangupzUser hungup during execution-1z&Error executing application, or hangupz    RESULT_DICT: %s
i  i  N   520z%s
r%   z$Unhandled code or undefined response)r&   r:   r;   r   r<   r=   r>   r(   r-   re_codesearchgroupsrJ   re_kvfindallr   r   rA   rB   r!   appendr@   r   r   )r3   r&   coderf   rC   mresponserD   valuerE   usages              r   rX   zAGI.get_result   s   H%zz""$**,DzU"4;;v+>D1D89NN4 XXZND(t9D3;$)MM($; P UD$dms 8#)*HII(?u}%&NOOP KK5v8NNOMS[#H--S[FE::&&(..0D:&t{{6/Br(e#T"zz**,224DzU*4;;v3FD	 r(e#
 LLTYYu--E&&!$(NOOr   c                     t        |      t        u rdj                  t        t        |            }| j                  |      S )Nr8   )r<   listr@   rb   r.   rN   )r3   digitss     r   _process_digit_listzAGI._process_digit_list   s2    <4WWSf-.F{{6""r   c                 2    | j                  d      d   d    y)zUagi.answer() --> None
        Answer channel if not already in answer state.
        ANSWERrf   r   Nr^   rS   s    r   answerz
AGI.answer   s     	Xx(+r   c                     | j                  d|      d   d   }|dk(  ry	 t        t        |            S # t        $ r t	        d|z        w xY w)zagi.wait_for_digit(timeout=DEFAULT_TIMEOUT) --> digit
        Waits for up to 'timeout' milliseconds for a channel to receive a DTMF
        digit.  Returns digit dialed
        Throws AGIError on channel falure
        zWAIT FOR DIGITrf   r   0r8   %Unable to convert result to digit: %s)r^   chrrJ   
ValueErrorr   r3   timeoutress      r   wait_for_digitzAGI.wait_for_digit   s_     ll+W5h?B#:N3s8}$ NFLMMNs	   4 Ac                 R    | j                  d| j                  |            d   d    y)zagi.send_text(text='') --> None
        Sends the given text on a channel.  Most channels do not support the
        transmission of text.
        Throws AGIError on error/hangup
        z	SEND TEXTrf   r   Nr^   rN   )r3   texts     r   	send_textzAGI.send_text   s%     	[$++d"34X>qAr   c                     | j                  d|      d   d   }|dk(  ry	 t        t        |            S #  t        d|z        xY w)a  agi.receive_char(timeout=DEFAULT_TIMEOUT) --> chr
        Receives a character of text on a channel.  Specify timeout to be the
        maximum time to wait for input in milliseconds, or 0 for infinite. Most channels
        do not support the reception of text.
        zRECEIVE CHARrf   r   r   r8   $Unable to convert result to char: %s)r^   r   rJ   r   r   s      r   receive_charzAGI.receive_char   sU     ll>73H=a@#:M3s8}$MEKLLs	   4 Ac                 T    | j                  d|      d   d   }|dk(  rt        d      y)zagi.tdd_mode(mode='on'|'off') --> None
        Enable/Disable TDD transmission/reception on a channel.
        Throws AGIAppError if channel is not TDD-capable.
        zTDD MODErf   r   r   zChannel %s is not TDD-capableN)r^   r   )r3   moder   s      r   tdd_modezAGI.tdd_mode  s6    
 ll:t,X6q9#:=>> r   r   c                     | j                  |      }| j                  d|||      }|d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)aC  agi.stream_file(filename, escape_digits='', sample_offset=0) --> digit
        Send the given file, allowing playback to be interrupted by the given
        digits, if any.  escape_digits is a string '12345' or a list  of
        ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
        If sample offset is provided then the audio will seek to sample
        offset before play starts.  Returns  digit if one was pressed.
        Throws AGIError if the channel was disconnected.  Remember, the file
        extension must not be included in the filename.
        zSTREAM FILErf   r   r   r8   r   rz   r^   r   rJ   r   )r3   filenameescape_digitssample_offsetrt   r   s         r   stream_filezAGI.stream_file  sr     00?<<8]MCx ##:M3s8}$MEKLLs   A	 	Ac                 T   | j                  |      }| j                  d| j                  |      || j                  |      | j                  |      | j                  |      | j                  |            }|d   d   }|dk(  ry	 t        t	        |            S #  t        d|z        xY w)a  
        Send the given file, allowing playback to be interrupted by the given
        digits, if any.  escape_digits is a string '12345' or a list  of
        ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
        If sample offset is provided then the audio will seek to sample
        offset before play starts.  Returns  digit if one was pressed.
        Throws AGIError if the channel was disconnected.  Remember, the file
        extension must not be included in the filename.
        zCONTROL STREAM FILErf   r   r   r8   r   rz   r^   rN   r   rJ   r   )	r3   r   r   skipmsfwdrewpausert   r   s	            r   control_stream_filezAGI.control_stream_file&  s     00?<< 5t{{87Lm]a]h]hio]prvr}r}  B  sC  EI  EP  EP  QT  EU  W[  Wb  Wb  ch  Wi  jx ##:M3s8}$MEKLLs   B B'c                     | j                  d|      d   d   }|dk7  r(t        d| j                  j                  dd      z        y)	zagi.send_image(filename) --> None
        Sends the given image on a channel.  Most channels do not support the
        transmission of images.   Image names should not include extensions.
        Throws AGIError on channel failure
        z
SEND IMAGErf   r   r   zChannel falure on channel %sagi_channelUNKNOWNN)r^   r   r1   get)r3   r   r   s      r   
send_imagezAGI.send_image;  sT     ll<28<Q?#:<"hhll=)DE F F r   c                     | j                  |      }| j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_digits(digits, escape_digits='') --> digit
        Say a given digit string, returning early if any of the given DTMF digits
        are received on the channel.
        Throws AGIError on channel failure
        z
SAY DIGITSrf   r   r   r8   r   r   )r3   ry   r   r   s       r   
say_digitszAGI.say_digitsF  w     ))&100?ll<?I!L#:M3s8}$MEKLL   A A'c                     | j                  |      }| j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_number(number, escape_digits='') --> digit
        Say a given digit string, returning early if any of the given DTMF digits
        are received on the channel.
        Throws AGIError on channel failure
        z
SAY NUMBERrf   r   r   r8   r   r   )r3   numberr   r   s       r   
say_numberzAGI.say_numberW  r   r   c                     | j                  |      }| j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_alpha(string, escape_digits='') --> digit
        Say a given character string, returning early if any of the given DTMF
        digits are received on the channel.
        Throws AGIError on channel failure
        z	SAY ALPHArf   r   r   r8   r   r   r3   
charactersr   r   s       r   	say_alphazAGI.say_alphah  sw     --j9
00?ll;
MB8LQO#:M3s8}$MEKLLr   c                     | j                  |      }| j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_phonetic(string, escape_digits='') --> digit
        Phonetically say a given character string, returning early if any of
        the given DTMF digits are received on the channel.
        Throws AGIError on channel failure
        zSAY PHONETICrf   r   r   r8   r   r   r   s       r   say_phoneticzAGI.say_phoneticy  s     --j9
00?llJ77?AABD#:M3s8}$MEKLLr   c                     | j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_date(seconds, escape_digits='') --> digit
        Say a given date, returning early if any of the given DTMF digits are
        pressed.  The date should be in seconds since the UNIX Epoch (Jan 1, 1970 00:00:00)
        zSAY DATErf   r   r   r8   r   r   r3   secondsr   r   s       r   say_datezAGI.say_date  g    
 00?ll:w>xHK#:M3s8}$MEKLL   A Ac                     | j                  |      }| j                  d||      d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)zagi.say_time(seconds, escape_digits='') --> digit
        Say a given time, returning early if any of the given DTMF digits are
        pressed.  The time should be in seconds since the UNIX Epoch (Jan 1, 1970 00:00:00)
        zSAY TIMErf   r   r   r8   r   r   r   s       r   say_timezAGI.say_time  r   r   c                     | j                  |      }|r| j                  |      }| j                  d||||      d   d   }|dk(  ry	 t        t	        |            S #  t        d|z        xY w)a1  agi.say_datetime(seconds, escape_digits='', format='', zone='') --> digit
        Say a given date in the format specfied (see voicemail.conf), returning
        early if any of the given DTMF digits are pressed.  The date should be
        in seconds since the UNIX Epoch (Jan 1, 1970 00:00:00).
        zSAY DATETIMErf   r   r   r8   r   )rz   rN   r^   r   rJ   r   )r3   r   r   formatzoner   s         r   say_datetimezAGI.say_datetime  s     00?[[(FllG]FDBBJLLMO#:M3s8}$MEKLLs   A A+   c                 >    | j                  d|||      }|d   \  }}|S )zagi.get_data(filename, timeout=DEFAULT_TIMEOUT, max_digits=255) --> digits
        Stream the given file and receive dialed digits
        zGET DATArf   r}   )r3   r   r   
max_digitsrf   r   ru   s          r   get_datazAGI.get_data  s+     j(GZHH%
U
r   c                     | j                  |      }|r| j                  d|||      }n| j                  d||      }|d   d   }|dk(  ry	 t        t        |            S #  t	        d|z        xY w)a  agi.get_option(filename, escape_digits='', timeout=0) --> digit
        Send the given file, allowing playback to be interrupted by the given
        digits, if any.  escape_digits is a string '12345' or a list  of
        ints [1,2,3,4,5] or strings ['1','2','3'] or mixed [1,'2',3,'4']
        Returns  digit if one was pressed.
        Throws AGIError if the channel was disconnected.  Remember, the file
        extension must not be included in the filename.
        z
GET OPTIONrf   r   r   r8   r   r   )r3   r   r   r   rt   r   s         r   
get_optionzAGI.get_option  s     00?||hw@H ||L(MJHx ##:M3s8}$MEKLLs   A A/c                 (    | j                  d|       y)zagi.set_context(context)
        Sets the context for continuation upon exiting the application.
        No error appears to be produced.  Does not set exten or priority
        Use at your own risk.  Ensure that you specify a valid context.
        zSET CONTEXTNr}   )r3   contexts     r   set_contextzAGI.set_context  s     	]G,r   c                 (    | j                  d|       y)a  agi.set_extension(extension)
        Sets the extension for continuation upon exiting the application.
        No error appears to be produced.  Does not set context or priority
        Use at your own risk.  Ensure that you specify a valid extension.
        zSET EXTENSIONNr}   )r3   	extensions     r   set_extensionzAGI.set_extension  s     	_i0r   c                 (    | j                  d|       y)zagi.set_priority(priority)
        Sets the priority for continuation upon exiting the application.
        No error appears to be produced.  Does not set exten or context
        Use at your own risk.  Ensure that you specify a valid priority.
        zset priorityNr}   )r3   prioritys     r   set_priorityzAGI.set_priority  s     	^X.r   c                     |xs | j                   d   }|xs | j                   d   }|xs | j                   d   }| j                  |       | j                  |       | j                  |       y )Nagi_contextagi_extensionagi_priority)r1   r   r   r   )r3   r   r   r   s       r   goto_on_exitzAGI.goto_on_exit  se    4TXXm4:/!:	7txx7!9%(#r   gsm#beepc                     | j                  |      }| j                  d| j                  |      |||||d|z        d   d   }	 t        t	        |            S #  t        d|z        xY w)a  agi.record_file(filename, format, escape_digits, timeout=DEFAULT_TIMEOUT, offset=0, beep='beep', silence=0) --> None
        Record to a file until a given dtmf digit in the sequence is received. Returns
        '-1' on hangup or error.  The format will specify what kind of file will be
        recorded. The <timeout> is the maximum record time in milliseconds, or '-1'
        for no <timeout>. <offset samples> is optional, and, if provided, will seek
        to the offset without exceeding the end of the file. <silence> is the number
        of seconds of silence allowed before the function returns despite the lack
        of dtmf digits or reaching <timeout>. <silence> value must be preceded by
        's=' and is also optional.
        zRECORD FILEzs=%srf   r   r   r   )	r3   r   r   r   r   offsetr   silencer   s	            r   record_filezAGI.record_file  s     00?ll=$++h*?('64&7BRUU]__`b	Js3x= 	JBSHIIr   c                 (    | j                  d|       y)a  agi.set_autohangup(secs) --> None
        Cause the channel to automatically hangup at <secs> seconds in the
        future.  Of course it can be hungup before then as well.   Setting to
        0 will cause the autohangup feature to be disabled on this channel.
        zSET AUTOHANGUPNr}   )r3   secss     r   set_autohangupzAGI.set_autohangup  s     	%t,r   c                 (    | j                  d|       y)zagi.hangup(channel='')
        Hangs up the specified channel.
        If no channel name is given, hangs up the current channel
        HANGUPNr}   )r3   channels     r   rh   z
AGI.hangup  s    
 	Xw'r   c                     | j                  d|| j                  |            }|d   d   }|dk(  rt        d|z        |S )zagi.appexec(application, options='')
        Executes <application> with given <options>.
        Returns whatever the application returns, or -2 on failure to find
        application
        EXECrf   r   z-2zUnable to find application: %s)r^   rN   r   )r3   applicationoptionsrf   r   s        r   appexeczAGI.appexec  sK     fk4;;w3GHXq!$;>LMM
r   c                 (    | j                  d|       y)z_agi.set_callerid(number) --> None
        Changes the callerid of the current channel.
        zSET CALLERIDNr}   )r3   r   s     r   set_calleridzAGI.set_callerid+  s     	^V,r   c                     	 | j                  d|      }t        |d   d         S # t        $ r  t        $ r ddi}Y )w xY w)a  agi.channel_status(channel='') --> int
        Returns the status of the specified channel.  If no channel name is
        given the returns the status of the current channel.

        Return values:
        0 Channel is down and available
        1 Channel is down, but reserved
        2 Channel is off hook
        3 Digits (or equivalent) have been dialed
        4 Line is ringing
        5 Remote end is ringing
        6 Line is up
        7 Line is busy
        zCHANNEL STATUSrf   )ri   r8   r   )r^   r   r   rJ   )r3   r   rf   s      r   channel_statuszAGI.channel_status1  sU    	,\\"2G<F 6(#A&''  	 	,
+F	,s   % >>c                 f    | j                  d| j                  |      | j                  |             y)z Set a channel variable.
        zSET VARIABLENr   )r3   nameru   s      r   set_variablezAGI.set_variableI  s&     	^T[[%6E8JKr   c                     	 | j                  d| j                  |            }|d   \  }}|S # t        $ r ddi}Y w xY w)Get a channel variable.

        This function returns the value of the indicated channel variable.  If
        the variable is not set, an empty string is returned.
        zGET VARIABLErf   1rh   r^   rN   r   )r3   r   rf   r   ru   s        r   get_variablezAGI.get_variableN  sP    	1\\.$++d2CDF H%
U	  	10F	1s   !- ==Nc                     	 |r2| j                  d| j                  |      | j                  |            }n!| j                  d| j                  |            }|d   \  }}|S # t        $ r ddi}Y w xY w)r   zGET FULL VARIABLErf   r   r   )r3   r   r   rf   r   ru   s         r   get_full_variablezAGI.get_full_variable\  s    	1&9&*kk$&7W9MO &94;;t;LM
 H%
U	  	10F	1s   AA! !A10A1c                 H    | j                  d| j                  |      |       y)zagi.verbose(message='', level=1) --> None
        Sends <message> to the console via verbose message system.
        <level> is the the verbose level (1-4)
        VERBOSENr   )r3   messagelevels      r   verbosezAGI.verboseo  s    
 	YG 4e<r   c           
         d|z  }d|z  }| j                  d| j                  |      | j                  |            }|d   \  }}|dk(  rt        d|d|      |dk(  r|S t        d|d|d	t	        j
                  |            )
a)  agi.database_get(family, key) --> str
        Retrieves an entry in the Asterisk database for a given family and key.
        Returns 0 if <key> is not set.  Returns 1 if <key>
        is set and returns the variable in parenthesis
        example return code: 200 result=1 (testvariable)
        z"%s"zDATABASE GETrf   r   z"Key not found in database: family=, key=r   zUnknown exception for : family=z	, result=)r^   rN   r   r   rA   rB   r3   familyrD   rf   r   ru   s         r   database_getzAGI.database_getv  s     &slDKK/S1ACH%
U#:$c+ , ,CZLU[]`bhbpbpqwbxyzzr   c                     | j                  d| j                  |      | j                  |      | j                  |            }|d   \  }}|dk(  rt        d|d|d|      y)zagi.database_put(family, key, value) --> None
        Adds or updates an entry in the Asterisk database for a
        given family, key, and value.
        zDATABASE PUTrf   r   z(Unable to put vaule in databale: family=r   z, value=Nr^   rN   r   )r3   r   rD   ru   rf   r   s         r   database_putzAGI.database_put  sh    
 ndkk/[[%t{{5'9;H%
U#:_egjlqrss r   c                     | j                  d| j                  |      | j                  |            }|d   \  }}|dk(  rt        d|d|      y)zagi.database_del(family, key) --> None
        Deletes an entry in the Asterisk database for a
        given family and key.
        zDATABASE DELrf   r   z'Unable to delete from database: family=r   Nr   r   s         r   database_delzAGI.database_del  sX    
 DKK/S1ACH%
U#:TZ\_`aa r   c                     | j                  d| j                  |      | j                  |            }|d   \  }}|dk(  rt        d|d|      y)zagi.database_deltree(family, key='') --> None
        Deletes a family or specific keytree with in a family
        in the Asterisk database.
        zDATABASE DELTREErf   r   z,Unable to delete tree from database: family=r   Nr   r   s         r   database_deltreezAGI.database_deltree  sX    
 F 3T[[5EGH%
U#:Y_adeff r   c                 &    | j                  d       y)z1agi.noop() --> None
        Does nothing
        NOOPNr}   rS   s    r   noopzAGI.noop  s     	Vr   c                 f    dj                  t        t        |            }| j                  d||      S )zDSend an arbitrary asterisk command with args (even not AGI commands),r   )r@   rb   r.   r^   rd   s      r   exec_commandzAGI.exec_command  s+     xxC'||FGT22r   )r8   )off)r8   r   )r8   i  r8   r8   r8   )r8   r8   r8   )N)r6   )8r   r   r	   __doc__r/   r&   r'   r(   r4   r2   rN   r,   rT   r^   rW   rX   rz   r~   DEFAULT_TIMEOUTr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   DEFAULT_RECORDr   r   rh   r   r   r   r   r   r   r   r   r   r   r  r  r  r
   r   r   r#   r#   V   sF    !YYszz#** 
 (	H C
	  #yy *PX#
, &5 NB $3 M ?M,M*	FM"M"M"M$MMM& *9S M2-1/$ ,1^delr|} J&-(
-(0L
&={(	t	b	g3r   r#   __main__zdemo-congratsbackgrounderz7Handled exception for missing application backgrounder
foobarfoobarz.Handled exception for missing variable foobar
bazfoobazbatfoobatzDBVALUE foo:bar = %s
z5Handled exception for missing database entry bar:foo
)(r
  r/   rA   rer*   sixr   r  r  compilerl   ro   	Exceptionr   r   r   r   r   r   r   r   r   r   r!   r#   r   agir   rh   exitr   r(   r-   r   r   r   r   vr   r  r
   r   r   <module>r     s  ,   	  
"**%
&

LM	9 		| 		h 		( 		 		i 		y 		i 		 		H 		 	_	3 _	3D z
%C LL!JJLCHHQK
HNO4
 UE"UL"Fx0x0x0UE*

1A56UE*

1A56&U#
 JJLc .  H

F	HH  L

JKL  F

D	FFs7   H ;I B<I)  H?>H? I&%I&) JJ