alina.nazchowdhury 0 Newbie Poster

Dear,
All Viewers I need your help guys I need to convert the python Asterisk Gateway Interface (AGI) PHP or Java or Perl Asterisk Gateway Interface (AGI), Please if anyone know about it help me ASAP, I wait for your feedback guys. Thanks here is Code...

asterisk.py code is below:

#!/usr/bin/env python
import os, sys
from os.path import abspath, dirname, join
PROJECT_ROOT = abspath(dirname(__file__))
sys.path.insert(0, join(PROJECT_ROOT, "apps"))
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.core.management import execute_manager
try:
    import settings # Assumed to be in the same directory.
except ImportError:
    import sys
    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
    sys.exit(1)
import MySQLdb
from asterisk.agi import AGI
from users.models import  Profile,Dialplan,Origination,ActiveCall,Callcdr,Profile
from django.db.models import Q 
#initial global variable 

def live_call_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,start_time,channel,gateway_name,from_ip,dialplan):
    agi.verbose('start to store live call')
    new = ActiveCall()
    new.uniq = uniqueid
    new.channel = channel
    new.callerid = callerid_num
    new.callername = callerid_name
    new.callee = calleeid
    new.active = 1
    new.user = gateway_name
    if Origination.objects.filter(name = gateway_name):
        new.orig_user =  Origination.objects.filter(name = gateway_name)[0].user
    new.start_time = start_time
    new.from_ip = from_ip
    if dialplan != '':
        new.trunk = dialplan.termination.name
    else:
        new.trunk = ''
    new.save()
    agi.verbose('done store live call>>>>>>>>>>>>>>>>>>>> %s'%uniqueid)
    return True   

def live_call_remove(agi,uniqueid):
    agi.verbose('remove live call <<<<<<<<<<<<<<<<<<<<<<<<%s'%uniqueid)    
    try:
        codec = ActiveCall.objects.filter(uniq = uniqueid)[0].codec
        ActiveCall.objects.filter(uniq = uniqueid).delete()
        agi.verbose('done for remove live call>>>>>>>>>>')
        return codec
    except:
        return ''

import datetime
def cdr_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,channel,start_time,duration,dialstatus,gateway_name,from_ip,dialplan):
    agi.verbose('process store cdr >>>>>>>>>>>>>>>>>>>')
    if 1:
        new = Callcdr()
        new.uniqueid = uniqueid
        new.ipnumber = from_ip
        new.channel = channel
        new.callerid = callerid_num
        new.callednumber = calleeid
        new.callstart = datetime.datetime.now()
        new.call_status = dialstatus
    duration = '%s'%duration
    if duration.isdigit():
        new.duration = duration
    else:
        new.duration = 0
    if dialplan != '':
        new.trunk = dialplan.termination.name
    else:
        new.trunk = ''
    new.accountcode = gateway_name
    if Origination.objects.filter(name =gateway_name):
        new.username = Origination.objects.get(name =gateway_name).user.username
    else:
        new.username = 'Guest'
    new.save()
    agi.verbose('done for store cdr')
    return True

import time
def update_cdr_store(agi,uniqueid,channel,duration,dialstatus,codec):
    if Callcdr.objects.filter(uniqueid = uniqueid).filter(channel = channel):
        cdr = Callcdr.objects.filter(uniqueid = uniqueid).filter(channel = channel)[0]
        agi.verbose('start to update cdr')
        cdr.duration = duration
        if '%s'%dialstatus != '':
            cdr.call_status = dialstatus
        pdd = 1
        try:
            pdd = int(time.mktime(cdr.start_ring.timetuple())) - int(time.mktime(cdr.start_dial.timetuple()))
        except:
            agi.verbose('invalid pbb value')
        cdr.pdd=pdd
        cdr.codec = codec
        cdr.save()
        agi.verbose('done for update cdr')
    return True

def process_call_out(agi, gateway_name,from_ip,calleeid, dnid,dialplan):
    agi.verbose('process call out ........%s'%dialplan)
    if dialplan != '':
        agi.verbose('we have dialplan ')
        number = calleeid[len(dialplan.prefix):]
        number = '%s%s'%(dialplan.replace_prefix,number)
        agi.verbose('number after change to dial our %s'%number)
        dial_string  = '%s/%s/%s'%(dialplan.termination.provider_tech,dialplan.termination.name,number)
        agi.verbose('dial string %s'%dial_string)
        #dial_string = 'SIP/1002,60,Ttr'
        #agi.appexec('DIAL',dial_string)   
    else:
        dial_string = ''
        agi.verbose('dialplan not valie')
    return dial_string

from  users.models import PrefixAllow
from django.db.models import Q
def get_matching_user(user,calleeid,agi):
    agi.verbose('start to check allow prefix in user')
    i = 1
    matching_req = PrefixAllow.objects.none()
    while i < ( len(calleeid) + 1):
        req = PrefixAllow.objects.filter(Q(prefix1=calleeid[:i])|Q(prefix2=calleeid[:i])|Q(prefix3=calleeid[:i])|Q(prefix4=calleeid[:i])|Q(prefix5=calleeid[:i])).filter(user = user)
        if req.exists():
            matching_req = req
        i += 1
    return matching_req

from  users.models import Dialplan
from django.db.models import Min
def get_matching_dialplan(user,calleeid,agi):
    agi.verbose('DialPlan routing')
    i = 1
    matching_req = Dialplan.objects.none()
    while i < ( len(calleeid) + 1):
        req = Dialplan.objects.filter(prefix=calleeid[:i])
        if req.exists():
            matching_req = req
        i += 1
    return_row = Dialplan.objects.none()
    if len(matching_req) > 0:
        agi.verbose('dielplan define')
        #all row match prefix is matching_req
        #get first row available
        min_prio = matching_req.filter(inuse = 0).aggregate(Min('priority'))
        agi.verbose('get min dialplan %s'%min_prio['priority__min'])
        if min_prio['priority__min'] is not None:
            agi.verbose('get min priority next')
            return_row = matching_req.filter(priority = int(min_prio['priority__min']))[0]
            return_row.inuse = 1
            return_row.save()
        else:
            agi.verbose('reset and get min priority')
            matching_req.update(inuse = 0)
            min_prio = matching_req.aggregate(Min('priority'))
            return_row = matching_req.filter(priority = int(min_prio['priority__min']))[0]
            return_row.inuse = 1
            return_row.save()
    else:
        agi.verbose('dialplan not define')
    return return_row

def authen_call_out(agi,protocol,from_ip,calleeid):
    agi.verbose('authen call')    
    if Origination.objects.filter(host_ip = from_ip):
        gw_name = Origination.objects.filter(host_ip = from_ip)[0].name
        agi.verbose('call pass, return')
        if Origination.objects.filter(host_ip = from_ip)[0].call_limit > len(ActiveCall.objects.filter(user = gw_name)):
            if  protocol==Origination.objects.filter(host_ip = from_ip)[0].protocol:
                #protocal support => get prefix alllow in this user
                user = Origination.objects.filter(host_ip = from_ip)[0].user
                agi.verbose('process to check call limit in this user')
                agi.verbose('limit_ext = %s , len = %s'%(Profile.objects.get(user = user).limit_ext, len(ActiveCall.objects.filter(orig_user = user))))
                if int(Profile.objects.get(user = user).limit_ext) > len(ActiveCall.objects.filter(orig_user = user)):
                    agi.verbose('allow call because call limit > current call')
                    agi.verbose('get prefix and check allow call or not')
                    match_user_allow = get_matching_user(user,calleeid,agi)
                    if len(match_user_allow) > 0:
                        dialplan = get_matching_dialplan(user,calleeid,agi)
                        agi.verbose('this user allow to make this call')
                        return (1,gw_name,'OK',dialplan)
                    else:
                        agi.verbose('this user not allow to mkae this call with prefix')
                        return (0,gw_name,'Prefix Not Allow','')
                else:
                    agi.verbose('call limit reach, hangup call')
                    return (0,gw_name,'Call Limit reached','')
            else:
                return (0,gw_name,'Protocol Not allow','')
        else:
            return (0,gw_name,'Call Limit','')
    else:
        return (0,'Not Exist','Reject','')

if __name__ == "__main__":
    agi = AGI()
    global_var = sys.argv[1]
    start_time = datetime.datetime.now()
    callerid_num = agi.get_variable('CALLERID(num)')
    callerid_name = agi.get_variable('CALLERID(name)')
    account_code = agi.get_variable('ACCOUNTCODE')
    calleeid = agi.get_variable('EXTEN')
    dnid  = agi.get_variable('DNID')
    blind_transfer = agi.get_variable('BLINDTRANSFER')
    channel = agi.get_variable('CHANNEL')
    context = agi.get_variable('CONTEXT')
    uniqueid = agi.get_variable('UNIQUEID')
    from_ip = ''
    agi.verbose(global_var);
    duration = 0
    if  '/' in channel:
        from_ip = channel.split('/')[1].split('-')[0]
        protocol = channel.split('/')[0]
    else:
        protocol = ''
        from_ip = channel
    agi.verbose('asterisk authen call')
    allow,gateway_name,reason,dialplan  = authen_call_out(agi,protocol,from_ip,calleeid)
   # allow = 1
 #   cdr_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,channel,start_time,'Counting','Calling',gateway_name,from_ip,dialplan)
    if allow == 1:
        if global_var == 'n':
            live_call_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,start_time,channel,gateway_name,from_ip,dialplan)
            agi.verbose('process call out11111111111111111111111111111111')
            cdr_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,channel,start_time,'Counting','ANSWERING',gateway_name,from_ip,dialplan)
            dial_string = process_call_out(agi,gateway_name,from_ip,calleeid, dnid,dialplan)
            agi.appexec('DIAL',dial_string)
            #agi.appexec('DIAL','SIP/1002')
            #application = 'DIAL %s'%dial_string
            #result =agi.execute('EXEC', application)
            #agi.verbose('sdsfdfsfsdfsdf %s'%result['result'][0])
    else:
        if global_var == 'n':
            agi.verbose('sssssssssssssssssssssss')
            cdr_store(agi,uniqueid,callerid_num,callerid_name,account_code,calleeid,dnid,channel,start_time,duration,reason,gateway_name,from_ip,dialplan)
    codec = live_call_remove(agi,uniqueid)
    duration = agi.get_variable('ANSWEREDTIME')
    agi.verbose('duration of this call is %s'%duration)
    #if reason == 'OK':
    dialstatus = agi.get_variable('DIALSTATUS')
    #else:
    #    dialstatus = reason
    if duration == '':
        duration = 0
    #get pdd value
    #epoch = agi.get_variable('PDD')
    #pdd will be update in script
    update_cdr_store(agi,uniqueid,channel,duration,dialstatus,codec)
    agi.hantup()

Dani AI

Generated

— two practical ways to get from that Python AGI to PHP or Java, and which one I recommend.

First (recommended): keep the Django/business logic where it is and write a thin AGI in the language you want. The posted script calls Django models a lot, so reimplementing the ORM and business rules is the slowest, riskiest route. Instead expose the necessary operations (authorize call, reserve a dialplan, create/update CDR/active-call) as small HTTP endpoints in your Django app, and have a lightweight AGI (PHP or Java) do only three things: read AGI variables, call the Django API, and run the Asterisk command (DIAL / HANGUP) based on the response. This keeps one source of truth, avoids reimplementing complex prefix/dialplan logic, and makes testing much simpler.

Second (full port): if you must port everything, use a proper AGI library and a FastAGI server for production (process-per-call AGI is fine for quick tests but not for high call volumes). In PHP use phpagi (CLI or FastAGI wrapper) and talk to the DB via PDO with prepared statements. In Java use asterisk-java (BaseAgiScript / FastAGI) and JDBC or JPA for DB work. Example skeletons:

<?php
require 'phpagi.php';
$agi = new AGI();
$exten = $agi->request['agi_extension'];
$agi->verbose("exten=".$exten);
$agi->exec('DIAL', 'SIP/1002,60');
import org.asteriskjava.agi.*;
public class ExampleAgi extends BaseAgiScript {
  public void service(AgiRequest req, AgiChannel chan) throws AgiException {
    String exten = chan.getVariable("EXTEN");
    chan.exec("DIAL", "SIP/1002,60");
  }
}

Practical cautions and tips: prefer FastAGI for pooled connections and fewer forks; keep DB connections pooled (don't open a new heavyweight connection per call); always use prepared statements or ORM to avoid SQL issues; add lots of AGI logging and test with Asterisk's AGI debug; and check small errors — for example verify your hangup invocation is correct in the target language (typos there silently leave calls hanging). If time is short, run the existing Python code as a FastAGI service and call it from the dialplan while you build the new AGI gradually.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.