[asterisk-users] Desktop integration

Michał Niklas michal.niklas at heuthes.pl
Tue Nov 14 04:38:54 MST 2006


Ondrej Valousek napisał(a):
> Hello Michal,
>
> Thank you for the hint!
> Can I ask you for your script so I have some idea how it works?
> I have apache already running on my * box.
>

OK.  Python code for my script is below.  Read it while you must prepare 
it to your
environment (prefixes, cellular phones recognition etc.).
Some strings and comments are in Polish, but most names are in English.
You also have to create dir: /var/spool/asterisk/outgoing_ht/
and do some chmod

<code>
#!/usr/bin/python
# -*- coding: cp1250 -*-
__version__ = '$Id: make_call.py 209 2006-11-03 09:47:05Z mn $'

# Make asterisk call file connecting both lines
# parameters:
#     tel1 - phone nr 1
#     tel2 - phone nr 2
# phones with technology prefix like 'SIP/Michal.Niklas' are not changed
# phones with numbers are changed to Zap or CAPI channel

# autor: Michal Niklas

import sys
import time
import re
import cgi
import os

BAN_PAID_NUMBERS = 1
START = time.time()

def write_debug(s):
   """write s to stderr"""
   t = int((time.time() - START) * 1000)
   sys.stderr.write("%d %s\n" % (t, s))
   sys.stderr.flush()


# asterisk callfile looks like:
CALL_FILE_CONTENT = """
# w Channel wpisujemy pierwszy numer (nasz)
#Channel: CAPI/39:41
Channel: %s
Callerid: %s
MaxRetries: 0
RetryTime: 0
WaitTime: 45
Context: call_out
Extension: %s
Priority: 1
SetVar: phone=%s
SetVar: digits=%s
SetVar: agi_callerid=%s
SetVar: orig_call=
SetVar: kntrh=
SetVar: kntrh_grp=
SetVar: destination=%s
"""

OK_HTML = """Content-Type: text/html

<html>
<head>
<title>SCT-10 - ok</title>
</head>
<body>
Centrala SCT-10: Zainicjowano dzwonienie ...
</body>
</html>
"""

ERR_HTML = """Content-Type: text/html

<html>
<head>
<title>SCT-10 - błąd</title>
</head>
<body>
Centrala SCT-10: Nie można zainicjowac dzwonienia!<br>
%s
</body>
</html>
"""

PHONEDICT_LOCAL = {'canal': 'Zap/g0', 'prefix': '091'}
PHONEDICT_OUTSIDE = {'canal': 'Zap/g0', 'prefix': '0'}
PHONEDICT_CELLURAL = {'canal': 'Zap/g0', 'prefix': '0'}
PHONEDICT_ABROAD = {'canal': 'Zap/g0', 'prefix': '00'}
PHONEDICT_INSIDE = {'canal': 'SIP', 'prefix': ''}
PHONEDICT_EMPTY = {'canal': '', 'prefix': ''}
ALARM_PREFIX = 'alarm:'
PHONEDICT_ALARM = {'canal': 'Zap/g0', 'prefix': ''}


class PhoneException(Exception):
   """cannot correct phone number exception"""
   pass


PREFIXES = ('iax2/', 'iax/', 'sip/', 'zap/', 'h323/', 'oh323/', 'capi/')
CELLURAL_PREFIXES = ('50', '51', '60', '66', '69', '88')

def is_prefixed(phone_nr):
   """czy podany numer ma prefix"""
   for prefix in PREFIXES:
       if phone_nr.startswith(prefix):
           return 1
   return 0


def correct_nr(phone_nr):
   """corrects number -- remove spaces, add prefix etc
      return numbers divided by 'w'
   """
   w = ''
   nr = phone_nr.lower()
   phone_dict = PHONEDICT_EMPTY
   if is_prefixed(nr):
       return (phone_nr, '')
   if nr.startswith(ALARM_PREFIX):
       phone_dict = PHONEDICT_ALARM
       nr = nr[len(ALARM_PREFIX):]
   else:
       nr = re.sub('^\D*', '', nr)
       # szukamy nr wewnetrznego
       i = nr.rfind('w')
       if i > 0:
           w = nr[i + 1:]
           w = re.sub('\D', '', w)
           nr = nr[:i - 1]
       # remove not digits
       if nr.startswith('+48'):
           nr = nr[3:]
       nr = re.sub('\D', '', nr)
       nr = nr.lstrip('0')
       # usuwamy kod kraju
       if len(nr) > 9:
           if nr.startswith('48'):
               nr = nr[2:]
       #sprawdzamy, czy wewnetrzny
       if len(nr) > 0 and len(nr) < 3:
           nr = "%03d" % (int(nr))
       # !!!!
       # klasyfikujemy numer
       # !!!!
       if len(nr) == 0:
           raise PhoneException, 'Numer nie nadaje sie do normalizacji: 
 >%s<, wychodzi pusty' % (phone_nr)
       elif len(nr) == 3 and (nr.startswith('9') or nr == '112'):
           phone_dict = PHONEDICT_ALARM
       elif len(nr) < 4:
           phone_dict = PHONEDICT_INSIDE
       elif len(nr) == 4 and nr.startswith('9'):
           phone_dict = PHONEDICT_ALARM
       elif len(nr) == 6 and nr.startswith('22'):
           phone_dict = PHONEDICT_OUTSIDE
       elif len(nr) == 6 and nr.startswith('118'):
           # 
http://www.stacjonarny.com/modules.php?op=modload&name=News&file=article&sid=396&mode=thread&order=0&thold=0 

           phone_dict = PHONEDICT_ALARM
       elif len(nr) == 7:
           phone_dict = PHONEDICT_LOCAL
       elif len(nr) == 9:
           if BAN_PAID_NUMBERS:
               if nr.startswith('70'):
                   raise PhoneException, 'Numer zabroniony: %s' % 
(phone_nr)
               elif nr.startswith('300'):
                   raise PhoneException, 'Numer zabroniony: %s' % 
(phone_nr)
           prefix = nr[:2]
           if prefix in CELLURAL_PREFIXES:
               phone_dict = PHONEDICT_CELLURAL
           else:
               phone_dict = PHONEDICT_OUTSIDE
       elif len(nr) > 9:
           phone_dict = PHONEDICT_ABROAD
           #raise PhoneException, 'Numer zagraniczne nie sa obslugiwane: 
%s' % (phone_nr)
       else:
           raise PhoneException, 'Numer nie nadaje sie do normalizacji: 
%s -> %s' % (phone_nr, nr)
   return ("%s/%s%s" % (phone_dict['canal'], phone_dict['prefix'], nr), w)



class MakeCall:
   """Make callfile with (eventually corrected) numbers from CGI request"""

   def __init__(self):
       """init phone numbers"""
       self.tel1 = ''
       self.tel2 = ''
       self.caller_id = ''
       self.status = 'error'
       self.digits = ''

   def ReadQuery(self):
       """Read and parse cgi form"""
       form = cgi.FieldStorage()
       self.tel1 = form["tel1"].value
       self.tel2 = form["tel2"].value
       self.caller_id = self.tel1


   def MakeCallFile(self):
       """write callfile and move it to asterisk dir"""
       step = ''
       try:
           tmp_dir = '/var/spool/asterisk/outgoing_ht/'
           out_dir = '/var/spool/asterisk/outgoing/'
           step = 'prepare numbers'
           write_debug('tel1: ' + self.tel1)
           write_debug('tel2: ' + self.tel2)
           (self.tel1, dummy) = correct_nr(self.tel1)
           (self.tel2, self.digits) = correct_nr(self.tel2)
           write_debug('tel1n: ' + self.tel1)
           write_debug('tel2n: ' + self.tel2)
           channel = self.tel1
           caller_id = self.caller_id
           extension = self.tel2
           phone = self.tel2
           digits = self.digits
           agi_callerid = self.caller_id
           destination = self.tel2
           call = CALL_FILE_CONTENT % (channel, caller_id, extension, 
phone, digits, agi_callerid, destination)
           write_debug(call)
           # remove special chars to create proper file name
           r = re.compile('\W')
           self.tel1 = r.sub('_', self.tel1)
           self.tel2 = r.sub('_', self.tel2)
           bname = 'call_' + self.tel1 + '_to_' + self.tel2 + '.txt'
           step = 'open'
           f = open(tmp_dir + bname, 'wr')
           f.write(call)
           f.close()
           step = 'chmod'
           os.chmod(tmp_dir + bname, 0666)
           step = 'rename'
           os.rename(tmp_dir + bname, out_dir + bname)
           step = 'copy'
           self.status = 'ok'
       except:
           ex = sys.exc_info()
           self.status = '%s: exception %s %s' % (step, ex[0], ex[1])

   def WriteOutput(self):
       """write XML output to caller"""
       if self.status == 'ok':
           print OK_HTML
       else:
           print ERR_HTML % (self.status)

def test_nr(nr):
   """test how we correct various numbers"""
   (nr1, nr2) = correct_nr(nr)
   if len(nr2) > 0:
       print "%-20s | %-20s | %-20s" % (nr, nr1, nr2)
   else:
       print "%-20s | %-20s" % (nr, nr1)


def main():
   """main function"""
   sys.stderr = open('/tmp/make_call_cgi.log', 'a')
   write_debug(time.strftime('\n\n%Y-%m-%d %H:%M:%S'))
   mk = MakeCall()
   try:
       mk.ReadQuery()
       mk.MakeCallFile()
   finally:
       mk.WriteOutput()
       write_debug(mk.status)


if __name__ == '__main__' and '--test' in sys.argv:
   test_nr('418 90 50')
   test_nr('604 123 821')
   test_nr('(22) 418 90 50')
   test_nr('+48 418 90 50')
   test_nr('SIP/Michal.Niklas')
   test_nr('OH323/169.0.1.51')
   test_nr('460 89 75 w.41')
   test_nr('0604 123 821')
   test_nr('0604123821')
   test_nr('+48604123821')
   test_nr('alarm:992')
   test_nr('0228556232')
   test_nr('0229622')
   test_nr('0229622')
   test_nr('9622')
   test_nr('41')
   test_nr('(61)8792081')
   test_nr('+48 61 876 51 79')
else:
   main()

</code>


HTML code to test it:
<html>
<head>
</head>
<body>
MakeCall
<form method="post" action="/cgi-bin/asterisk/make_call.py">
<input type="text" name="tel1" value="21">
<input type="text" name="tel2" value="29">
<input type="submit">
</form>
</body>
</html>

I hope you got the idea :)

Regards,
Michał Niklas




More information about the asterisk-users mailing list