Commit 8ce6d5d4 authored by Valentin Samir's avatar Valentin Samir

[sip/asterisk] Une classe pour écrire des applications AGI

parent 8b724825
......@@ -10,7 +10,9 @@ import shutil
import syslog
import socket
import base64
import syslog
import psycopg2
import threading
import psycopg2.extras
from datetime import datetime
......@@ -202,7 +204,7 @@ class History(object):
class Manager(object):
def __init__(self, username, password, timeout=10, server='asterisk.adm.crans.org', port=5038, debug=False, event=False, auto_connect=True):
def __init__(self, username, password, timeout=10, server='asterisk.adm.crans.org', port=5038, debug=False, event=False, auto_connect=True, agi=None):
self.timeout = timeout
self.server = server
self.port = port
......@@ -214,6 +216,7 @@ class Manager(object):
self._event=[]
self._event_callback = {}
self._toread = ""
self._agi = agi
self.fullybooted = False
self.username = username
......@@ -223,6 +226,11 @@ class Manager(object):
if auto_connect:
self.connect()
def agi(self, *args, **kwargs):
if not self._agi:
self._agi = AGI(*args, manager=self, **kwargs)
return self._agi
def _FullyBooted(self, manager, params):
manager.fullybooted = True
......@@ -246,7 +254,7 @@ class Manager(object):
def _parse_msg(self, msg):
msg = msg.strip().split('\r\n')
type, value = msg[0].split(': ', 1)
params = dict([line.split(': ', 1) for line in msg[1:]])
params = dict([line.split(': ', 1) if len(line.split(': ', 1))==2 else (line.split(': ', 1)[0], '') for line in msg[1:]])
handler = getattr(self, "_do_"+type, None)
handler(value, params)
......@@ -339,6 +347,10 @@ class Manager(object):
raise EnvironmentError("%r should be a list or a bool" % param)
return self.action('events', eventmask=eventmask)
def hangup(self, channel):
"""Hangup a channel"""
return self.action('hangup', channel=channel)
def reload(self, module):
"""Synopsis: Send a reload event
Privilege: system,config,all"""
......@@ -351,3 +363,103 @@ class Manager(object):
if body_type == "str":
body = base64.b64encode(body).strip()
return self._action('messageSend', {'to':dst, 'from':src, 'base64body':body})
class AGI(object):
"""voir http://www.voip-info.org/wiki/view/Asterisk+AGI"""
def __init__(self, read=sys.stdin, write=sys.stdout, manager=None, **params):
self.debug = True
self.read=read
self.write=write
self.params=params
self._manager=manager
self._lock=False
self._locklock = threading.Lock()
self._read_params()
def manager(self, *args, **kwargs):
if not self._manager:
self._manager=Manager(*args, agi=self, **kwargs)
return self._manager
def __getitem__(self, key):
try:
return self.params[key]
except KeyError:
(result, data) = self.command("GET VARIABLE", key)
if int(result) != 1:
raise KeyError(key)
return data[1:-2]
def __setitem__(self, key, value):
if key in self.params.keys():
raise ValueError("ReadOnly value")
else:
(result, data) = self.command("SET VARIABLE", key, value)
return result
def _read_params(self):
line=self.read.readline()
while line.strip():
syslog.syslog(line)
if line.startswith('agi_'):
(key, data) = line[4:].split(':',1)
self.params[key.strip()]=data.strip()
line = self.read.readline()
def command(self, name, *params):
with self._locklock:
if self._lock:
raise AsteriskError("Cannot lauch AGI command %s, an other command is processing" % name, name, params)
else:
self._lock = True
cmd=' '.join([name] + ["%s" % p for p in params])
if self.debug:
syslog.syslog("%s\n" % cmd)
self.write.write("%s\n" % cmd)
self.write.flush()
line=self.read.readline()
if self.debug:
syslog.syslog(line)
lines=[line]
code=int(line[0:3])
type=line[3]
if type == '-':
while not "%s End of " % code not in line:
line=self.read.readline()
if self.debug:
syslog.syslog("%s\n" % cmd)
lines.append(line)
self._lock=False
if code != 200:
raise AsteriskError((code, '\n'.join(lines)), name, params)
try:
(result, data) = lines[0][4:].split(' ', 1)
except ValueError:
result = lines[0][4:]
data=""
result=result.split('=',1)[1].strip()
return (int(result), data)
def hangup(self):
self.command("hangup")
def set_callerid(self, callerid):
self.command("set_callerid", callerid)
def noop(self, str):
self.command("noop", str)
def launch_app(self, app, *params):
self.command("exec", app, *params)
def dial(self, to):
self.launch_app("dial", to)
def goto(self, arg):
self.launch_app("goto", arg)
### TODO
class FastAGI(object):
def __init__(self, bind, port, *args,**kwargs):
pass
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment