[mod_python3, ESL py3mod] Add Python3 support.

This commit is contained in:
Andrey Volk 2021-09-26 13:23:46 +03:00
parent 3a66eb415f
commit e44fd2ea38
35 changed files with 20248 additions and 13 deletions

1
.gitignore vendored
View File

@ -156,6 +156,7 @@ Release/
/src/mod/languages/mod_lua/mod_lua_wrap.cpp.orig
/src/mod/languages/mod_perl/mod_perl_wrap.cpp.orig
/src/mod/languages/mod_python/mod_python_wrap.cpp.orig
/src/mod/languages/mod_python3/mod_python_wrap.cpp.orig
/src/mod/say/mod_say_de/Makefile
/src/mod/say/mod_say_es/Makefile
/src/mod/say/mod_say_fr/Makefile

View File

@ -742,7 +742,7 @@ pristine:
git clean -fdx
git reset --hard
update-clean: clean python-reconf
update-clean: clean python-reconf python3-reconf
cd libs/esl && $(MAKE) clean
cd libs/srtp && $(MAKE) clean
@ -759,6 +759,10 @@ python-reconf:
rm -f src/mod/languages/mod_python/Makefile
./config.status
python3-reconf:
rm -f src/mod/languages/mod_python3/Makefile
./config.status
reconf:
rm config.cache
sh ./config.status --recheck

View File

@ -134,6 +134,7 @@ languages/mod_lua
#languages/mod_managed
#languages/mod_perl
#languages/mod_python
#languages/mod_python3
#languages/mod_v8
#languages/mod_yaml
loggers/mod_console

View File

@ -127,7 +127,7 @@ languages/mod_java
languages/mod_lua
languages/mod_managed
languages/mod_perl
languages/mod_python
languages/mod_python3
#languages/mod_v8
languages/mod_yaml
loggers/mod_console

View File

@ -13,6 +13,11 @@ make swigclean
make mod_python_wrap.cpp
cd ../../../..
cd src/mod/languages/mod_python3
make swigclean
make mod_python_wrap.cpp
cd ../../../..
cd src/mod/languages/mod_java
make reswig
cd ../../../..

View File

@ -81,6 +81,7 @@
<load module="mod_v8"/>
<!-- <load module="mod_perl"/> -->
<!-- <load module="mod_python"/> -->
<!-- <load module="mod_python3"/> -->
<!-- <load module="mod_java"/> -->
<load module="mod_lua"/>

View File

@ -122,6 +122,7 @@
<!-- <load module="mod_v8"/> -->
<!-- <load module="mod_perl"/> -->
<!-- <load module="mod_python"/> -->
<!-- <load module="mod_python3"/> -->
<!-- <load module="mod_java"/> -->
<load module="mod_lua"/>

View File

@ -1702,7 +1702,7 @@ if test "x$ac_cv_have_php" != "xno" -a "x$ac_cv_have_php_config" != "xno"; then
fi
#
# Python checks for mod_python
# Python checks for mod_python (scroll down to see python3 checks for mod_python3)
#
AC_ARG_WITH(
[python],
@ -1822,6 +1822,127 @@ else
AC_MSG_WARN([python support disabled, building mod_python will fail!])
fi
#
# Python3 checks for mod_python3
#
AC_ARG_WITH(
[python3],
[AS_HELP_STRING([--with-python3], [Use system provided version of python3 (default: try)])],
[with_python3="$withval"],
[with_python3="try"]
)
if test "$with_python3" != "no"
then
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
if test "$with_python3" != "yes" -a "$with_python3" != "try" ; then
AC_MSG_CHECKING([for python3])
if test ! -x "$with_python3" ; then
AC_MSG_ERROR([Specified python3 does not exist or is not executable: $with_python3])
fi
AC_MSG_RESULT([$with_python3])
AC_SUBST([PYTHON3], ["$with_python3"])
else
AC_PATH_PROG([PYTHON3], ["python3"], ["no"], ["$PATH:/usr/bin:/usr/local/bin"])
fi
if test "$PYTHON3" != "no" ; then
AC_MSG_CHECKING([python3 version])
PYTHON3_VER="`$PYTHON3 -V 2>&1 | cut -d' ' -f2`"
if test -z "$PYTHON3_VER" ; then
AC_MSG_ERROR([Unable to detect python3 version])
fi
AC_MSG_RESULT([$PYTHON3_VER])
AC_MSG_CHECKING([for python3 distutils])
python3_result="`$PYTHON3 -c 'import distutils;' 2>&1`"
if test -z "$python3_result" ; then
python3_has_distutils="yes"
else
python3_has_distutils="no"
fi
AC_MSG_RESULT([$python3_has_distutils])
if test "$python3_has_distutils" != "no" ; then
AC_MSG_CHECKING([location of python3 site-packages])
PYTHON3_SITE_DIR="`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_python_lib(0));'`"
if test -z "$PYTHON3_SITE_DIR" ; then
AC_MSG_ERROR([Unable to detect python3 site-packages path])
elif test ! -d "$PYTHON3_SITE_DIR" ; then
AC_MSG_ERROR([Path $PYTHON3_SITE_DIR returned by python3 does not exist!])
fi
AC_MSG_RESULT([$PYTHON3_SITE_DIR])
AC_SUBST([PYTHON3_SITE_DIR], [$PYTHON3_SITE_DIR])
#
# python3 distutils found, get settings from python3 directly
#
PYTHON3_CFLAGS="`$PYTHON3 -c 'from distutils import sysconfig; flags = [[\"-I\" + sysconfig.get_python_inc(0), \"-I\" + sysconfig.get_python_inc(1), \" \".join(sysconfig.get_config_var(\"CFLAGS\").split())]]; print(\" \".join(flags));' | sed -e 's/-arch i386//g;s/-arch x86_64//g'`"
PYTHON3_LDFLAGS="`$PYTHON3 -c 'from distutils import sysconfig; ldver = sysconfig.get_config_var(\"LDVERSION\"); libs = sysconfig.get_config_var(\"LIBS\").split() + sysconfig.get_config_var(\"SYSLIBS\").split(); libs.append(\"-lpython\" + [[ldver,sysconfig.get_config_var(\"VERSION\")]][[ldver==None]]); print(\" \".join(libs));'`"
PYTHON3_LIB="`$PYTHON3 -c 'from distutils import sysconfig; ldver = sysconfig.get_config_var(\"LDVERSION\"); print(\"python\" + [[ldver,sysconfig.get_config_var(\"VERSION\")]][[ldver==None]]);'`"
PYTHON3_LIBDIR="`$PYTHON3 -c 'from distutils import sysconfig; print(sysconfig.get_config_var(\"LIBDIR\"));'`"
# handle python3 being installed into /usr/local
AC_MSG_CHECKING([python3 libdir])
if test -z "`echo $PYTHON3_LIBDIR | grep "/usr/lib"`" ; then
PYTHON3_LDFLAGS="-L$PYTHON3_LIBDIR $PYTHON3_LDFLAGS"
LIBS="-L$PYTHON3_LIBDIR $LIBS"
fi
AC_MSG_RESULT([$PYTHON3_LIBDIR])
# check libpython3
AC_CHECK_LIB([$PYTHON3_LIB], [main], [has_libpython3="yes"], [has_libpython3="no"])
if test "$has_libpython3" = "no" ; then
AS_IF([test "$with_python3" = "try"],
[AC_MSG_WARN([$PYTHON3_LIB is unusable])],
[AC_MSG_ERROR([$PYTHON3_LIB is unusable])]
)
fi
# check whether system libpython3 is usable and has threads support
CFLAGS="$PYTHON3_CFLAGS"
LIBS="$PYTHON3_LDFLAGS"
AC_CHECK_FUNC([PyThread_init_thread], [python3_has_threads="yes"], [python3_has_threads="no"])
if test "$python3_has_threads" = "no"; then
AS_IF([test "$with_python3" = "try"],
[AC_MSG_WARN([Your python3 lacks threads support, can not build mod_python3])],
[AC_MSG_ERROR([Your python3 lacks threads support, can not build mod_python3])]
)
else
AC_MSG_NOTICE([Your python3 seems OK, do not forget to enable mod_python3 in modules.conf])
AC_SUBST([PYTHON3_CFLAGS], [$PYTHON3_CFLAGS])
AC_SUBST([PYTHON3_LDFLAGS], [$PYTHON3_LDFLAGS])
fi
else
AS_IF([test "$with_python3" = "try"],
[AC_MSG_WARN([Could not find or use python3 distutils module: $python3_result])],
[AC_MSG_ERROR([Could not find or use python3 distutils module: $python3_result])]
)
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
unset python3_has_threads
unset python3_has_distutils
unset python3_result
else
AS_IF([test "$with_python3" = "try"],
[AC_MSG_WARN([Could not find python3, mod_python3 will not build, use --with-python3 to specify the location])],
[AC_MSG_ERROR([Could not find python3, use --with-python3 to specify the location])]
)
fi
else
AC_MSG_WARN([python3 support disabled, building mod_python3 will fail!])
fi
#
# SNMP checks for mod_snmp
#
@ -2012,6 +2133,7 @@ AC_CONFIG_FILES([Makefile
src/mod/languages/mod_managed/Makefile
src/mod/languages/mod_perl/Makefile
src/mod/languages/mod_python/Makefile
src/mod/languages/mod_python3/Makefile
src/mod/languages/mod_v8/Makefile
src/mod/languages/mod_yaml/Makefile
src/mod/languages/mod_basic/Makefile

6
debian/bootstrap.sh vendored
View File

@ -325,7 +325,7 @@ Build-Depends:
# configure options
libssl1.0-dev | libssl-dev, unixodbc-dev, libpq-dev,
libncurses5-dev, libjpeg62-turbo-dev | libjpeg-turbo8-dev | libjpeg62-dev | libjpeg8-dev,
python-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
python-dev, python3-dev, python-all-dev, python-support (>= 0.90) | dh-python, erlang-dev, libtpl-dev (>= 1.5),
# documentation
doxygen,
# for APR (not essential for build)
@ -683,7 +683,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
freeswitch-mod-java (= \${binary:Version}),
freeswitch-mod-lua (= \${binary:Version}),
freeswitch-mod-perl (= \${binary:Version}),
freeswitch-mod-python (= \${binary:Version}),
freeswitch-mod-python3 (= \${binary:Version}),
freeswitch-mod-yaml (= \${binary:Version}),
freeswitch-mod-console (= \${binary:Version}),
freeswitch-mod-logfile (= \${binary:Version}),
@ -922,7 +922,7 @@ Depends: \${misc:Depends}, freeswitch (= \${binary:Version}),
freeswitch-mod-java-dbg (= \${binary:Version}),
freeswitch-mod-lua-dbg (= \${binary:Version}),
freeswitch-mod-perl-dbg (= \${binary:Version}),
freeswitch-mod-python-dbg (= \${binary:Version}),
freeswitch-mod-python3-dbg (= \${binary:Version}),
freeswitch-mod-yaml-dbg (= \${binary:Version}),
freeswitch-mod-console-dbg (= \${binary:Version}),
freeswitch-mod-logfile-dbg (= \${binary:Version}),

View File

@ -671,6 +671,11 @@ Description: mod_python
Adds mod_python.
Build-Depends: python-dev
Module: languages/mod_python3
Description: mod_python3
Adds mod_python3.
Build-Depends: python3-dev
Module: languages/mod_v8
Description: mod_v8
Adds mod_v8.

View File

@ -0,0 +1 @@
/usr/lib/python*/*-packages/freeswitch.py

4
debian/rules vendored
View File

@ -73,7 +73,7 @@ override_dh_auto_clean:
./configure -C --enable-portable-binary --disable-dependency-tracking \
--host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) \
--prefix=/usr --localstatedir=/var --sysconfdir=/etc \
--with-gnu-ld --with-python --with-erlang --with-openssl \
--with-gnu-ld --with-python --with-python3 --with-erlang --with-openssl \
--enable-core-odbc-support --enable-zrtp
touch $@
@ -85,6 +85,7 @@ override_dh_auto_configure: .stamp-configure
make iksemel-dep
make -j$(NJOBS)
make -C libs/esl pymod
make -C libs/esl py3mod
make -C libs/esl perlmod
touch $@
@ -99,6 +100,7 @@ override_dh_strip:
override_dh_auto_install:
dh_auto_install
dh_auto_install -- -C libs/esl pymod-install
dh_auto_install -- -C libs/esl py3mod-install
dh_auto_install -- -C libs/esl perlmod-install
rm -f debian/tmp/usr/share/freeswitch/grammar/model/communicator/COPYING

View File

@ -54,6 +54,7 @@ reswig: swigclean
$(MAKE) -C php reswig
$(MAKE) -C lua reswig
$(MAKE) -C python reswig
$(MAKE) -C python3 reswig
$(MAKE) -C ruby reswig
$(MAKE) -C java reswig
$(MAKE) -C managed reswig
@ -63,6 +64,7 @@ swigclean: clean
$(MAKE) -C php swigclean
$(MAKE) -C lua swigclean
$(MAKE) -C python swigclean
$(MAKE) -C python3 swigclean
$(MAKE) -C ruby swigclean
$(MAKE) -C java swigclean
$(MAKE) -C managed swigclean
@ -77,7 +79,10 @@ luamod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" LUA_CFLAGS="$(LUA_CFLAGS)" LUA_LIBS="$(LUA_LIBS)" -C lua
pymod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python
$(MAKE) PYTHON=$(PYTHON) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python
py3mod: $(MYLIB)
$(MAKE) PYTHON3=$(PYTHON3) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C python3
tclmod: $(MYLIB)
$(MAKE) MYLIB="../$(MYLIB)" SOLINK="$(SOLINK)" CFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CFLAGS)" CXXFLAGS="-I$(switch_srcdir)/libs/esl/src/include $(SWITCH_AM_CXXFLAGS)" CXX_CFLAGS="$(CXX_CFLAGS)" -C tcl
@ -98,9 +103,12 @@ phpmod-install: phpmod
$(MAKE) -C php install
pymod-install: pymod
$(MAKE) -C python install
$(MAKE) PYTHON=$(PYTHON) -C python install
py3mod-install: py3mod
$(MAKE) PYTHON3=$(PYTHON3) -C python3 install
rubymod-install: rubymod
$(MAKE) -C ruby install
everymod: perlmod phpmod luamod pymod rubymod javamod managedmod
everymod: perlmod phpmod luamod pymod py3mod rubymod javamod managedmod

View File

@ -1,6 +1,6 @@
LOCAL_CFLAGS=`python ./python-config --includes`
LOCAL_LDFLAGS=`python ./python-config --ldflags`
SITE_DIR=$(DESTDIR)/`python -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)"`
LOCAL_CFLAGS=`$(PYTHON) ./python-config --includes`
LOCAL_LDFLAGS=`$(PYTHON) ./python-config --ldflags`
SITE_DIR=$(DESTDIR)/`$(PYTHON) -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)"`
all: _ESL.so

132
libs/esl/python3/ESL.py Normal file
View File

@ -0,0 +1,132 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.2
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.
from sys import version_info
if version_info >= (2,6,0):
def swig_import_helper():
from os.path import dirname
import imp
fp = None
try:
fp, pathname, description = imp.find_module('_ESL', [dirname(__file__)])
except ImportError:
import _ESL
return _ESL
if fp is not None:
try:
_mod = imp.load_module('_ESL', fp, pathname, description)
finally:
fp.close()
return _mod
_ESL = swig_import_helper()
del swig_import_helper
else:
import _ESL
del version_info
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
if (name == "thisown"): return self.this.own(value)
if (name == "this"):
if type(value).__name__ == 'SwigPyObject':
self.__dict__[name] = value
return
method = class_type.__swig_setmethods__.get(name,None)
if method: return method(self,value)
if (not static):
self.__dict__[name] = value
else:
raise AttributeError("You cannot add attributes to %s" % self)
def _swig_setattr(self,class_type,name,value):
return _swig_setattr_nondynamic(self,class_type,name,value,0)
def _swig_getattr(self,class_type,name):
if (name == "thisown"): return self.this.own()
method = class_type.__swig_getmethods__.get(name,None)
if method: return method(self)
raise AttributeError(name)
def _swig_repr(self):
try: strthis = "proxy of " + self.this.__repr__()
except: strthis = ""
return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
class ESLevent:
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, ESLevent, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, ESLevent, name)
__repr__ = _swig_repr
__swig_setmethods__["event"] = _ESL.ESLevent_event_set
__swig_getmethods__["event"] = _ESL.ESLevent_event_get
__swig_setmethods__["serialized_string"] = _ESL.ESLevent_serialized_string_set
__swig_getmethods__["serialized_string"] = _ESL.ESLevent_serialized_string_get
__swig_setmethods__["mine"] = _ESL.ESLevent_mine_set
__swig_getmethods__["mine"] = _ESL.ESLevent_mine_get
def __init__(self, *args):
this = _ESL.new_ESLevent(*args)
try: self.this.append(this)
except: self.this = this
__swig_destroy__ = _ESL.delete_ESLevent
__del__ = lambda self : None;
def serialize(self, format=None): return _ESL.ESLevent_serialize(self, format)
def setPriority(self, *args): return _ESL.ESLevent_setPriority(self, *args)
def getHeader(self, *args): return _ESL.ESLevent_getHeader(self, *args)
def getBody(self): return _ESL.ESLevent_getBody(self)
def getType(self): return _ESL.ESLevent_getType(self)
def addBody(self, *args): return _ESL.ESLevent_addBody(self, *args)
def addHeader(self, *args): return _ESL.ESLevent_addHeader(self, *args)
def pushHeader(self, *args): return _ESL.ESLevent_pushHeader(self, *args)
def unshiftHeader(self, *args): return _ESL.ESLevent_unshiftHeader(self, *args)
def delHeader(self, *args): return _ESL.ESLevent_delHeader(self, *args)
def firstHeader(self): return _ESL.ESLevent_firstHeader(self)
def nextHeader(self): return _ESL.ESLevent_nextHeader(self)
ESLevent_swigregister = _ESL.ESLevent_swigregister
ESLevent_swigregister(ESLevent)
class ESLconnection:
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, ESLconnection, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, ESLconnection, name)
__repr__ = _swig_repr
def __init__(self, *args):
this = _ESL.new_ESLconnection(*args)
try: self.this.append(this)
except: self.this = this
__swig_destroy__ = _ESL.delete_ESLconnection
__del__ = lambda self : None;
def socketDescriptor(self): return _ESL.ESLconnection_socketDescriptor(self)
def connected(self): return _ESL.ESLconnection_connected(self)
def getInfo(self): return _ESL.ESLconnection_getInfo(self)
def send(self, *args): return _ESL.ESLconnection_send(self, *args)
def sendRecv(self, *args): return _ESL.ESLconnection_sendRecv(self, *args)
def api(self, *args): return _ESL.ESLconnection_api(self, *args)
def bgapi(self, *args): return _ESL.ESLconnection_bgapi(self, *args)
def sendEvent(self, *args): return _ESL.ESLconnection_sendEvent(self, *args)
def sendMSG(self, *args): return _ESL.ESLconnection_sendMSG(self, *args)
def recvEvent(self): return _ESL.ESLconnection_recvEvent(self)
def recvEventTimed(self, *args): return _ESL.ESLconnection_recvEventTimed(self, *args)
def filter(self, *args): return _ESL.ESLconnection_filter(self, *args)
def events(self, *args): return _ESL.ESLconnection_events(self, *args)
def execute(self, *args): return _ESL.ESLconnection_execute(self, *args)
def executeAsync(self, *args): return _ESL.ESLconnection_executeAsync(self, *args)
def setAsyncExecute(self, *args): return _ESL.ESLconnection_setAsyncExecute(self, *args)
def setEventLock(self, *args): return _ESL.ESLconnection_setEventLock(self, *args)
def disconnect(self): return _ESL.ESLconnection_disconnect(self)
ESLconnection_swigregister = _ESL.ESLconnection_swigregister
ESLconnection_swigregister(ESLconnection)
def eslSetLogLevel(*args):
return _ESL.eslSetLogLevel(*args)
eslSetLogLevel = _ESL.eslSetLogLevel
# This file is compatible with both classic and new-style classes.

28
libs/esl/python3/Makefile Normal file
View File

@ -0,0 +1,28 @@
LOCAL_CFLAGS=`$(PYTHON3) ./python-config --includes`
LOCAL_LDFLAGS=`$(PYTHON3) ./python-config --ldflags`
SITE_DIR=$(DESTDIR)/`$(PYTHON3) -c "from distutils.sysconfig import get_python_lib; print (get_python_lib(1))"`
all: _ESL.so
esl_wrap.cpp:
swig3.0 -module ESL -classic -python -c++ -DMULTIPLICITY -threads -I../src/include -o esl_wrap.cpp ../ESL.i
esl_wrap.o: esl_wrap.cpp
$(CXX) $(CXX_CFLAGS) $(CXXFLAGS) $(LOCAL_CFLAGS) -c esl_wrap.cpp -o esl_wrap.o
_ESL.so: esl_wrap.o
$(CXX) $(SOLINK) esl_wrap.o $(MYLIB) $(LOCAL_LDFLAGS) -o _ESL.so -L. $(LIBS)
install: _ESL.so
mkdir -p $(SITE_DIR)
install -m 755 _ESL.so $(SITE_DIR)
install -m 755 ESL.py $(SITE_DIR)
clean:
rm -f *.o *.so *~
swigclean:
rm -f esl_wrap.* ESL.so
reswig: swigclean esl_wrap.cpp

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
import string
import sys
from ESL import *
con = ESLconnection("localhost","8021","ClueCon")
#are we connected?
if con.connected:
con.events("plain", "all");
while 1:
#my $e = $con->recvEventTimed(100);
e = con.recvEvent()
if e:
print e.serialize()

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python3
from __future__ import print_function
import sys
import os
import getopt
from distutils import sysconfig
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
'ldflags', 'help']
def exit_with_usage(code=1):
print("Usage: %s [%s]" % (sys.argv[0], '|'.join('--'+opt for opt in valid_opts)), file=sys.stderr)
sys.exit(code)
try:
opts, args = getopt.getopt(sys.argv[1:], '', valid_opts)
except getopt.error:
exit_with_usage()
if not opts:
exit_with_usage()
opt = opts[0][0]
pyver = sysconfig.get_config_var('LDVERSION')
if pyver == None:
pyver = sysconfig.get_config_var('VERSION')
getvar = sysconfig.get_config_var
if opt == '--help':
exit_with_usage(0)
elif opt == '--prefix':
print(sysconfig.PREFIX)
elif opt == '--exec-prefix':
print(sysconfig.EXEC_PREFIX)
elif opt in ('--includes', '--cflags'):
flags = ['-I' + sysconfig.get_python_inc(),
'-I' + sysconfig.get_python_inc(plat_specific=True)]
if opt == '--cflags':
flags.extend(getvar('CFLAGS').split())
print(' '.join(flags))
elif opt in ('--libs', '--ldflags'):
libs = getvar('LIBS').split() + getvar('SYSLIBS').split()
libs.append('-lpython'+pyver)
# add the prefix/lib/pythonX.Y/config dir, but only if there is no
# shared library in prefix/lib/.
if opt == '--ldflags' and not getvar('Py_ENABLE_SHARED'):
libs.insert(0, '-L' + getvar('LIBPL'))
print(' '.join(libs))

View File

@ -0,0 +1,29 @@
#!/usr/bin/env python
import SocketServer
from ESL import *
class ESLRequestHandler(SocketServer.BaseRequestHandler ):
def setup(self):
print self.client_address, 'connected!'
fd = self.request.fileno()
print fd
con = ESLconnection(fd)
print "Connected: "
print con.connected()
if con.connected():
info = con.getInfo()
uuid = info.getHeader("unique-id")
print uuid
con.execute("answer", "", uuid)
con.execute("playback", "/ram/swimp.raw", uuid);
#server host is a tuple ('host', port)
server = SocketServer.ThreadingTCPServer(('', 8040), ESLRequestHandler)
server.serve_forever()

View File

@ -0,0 +1,43 @@
#!/usr/bin/env python
import string
import sys
from optparse import OptionParser
from ESL import *
def main(argv):
try:
parser = OptionParser()
parser.add_option("-a", "--auth", dest="auth", default="ClueCon",
help="ESL password")
parser.add_option("-s", "--server", dest="server", default="127.0.0.1",
help="FreeSWITCH server IP address")
parser.add_option("-p", "--port", dest="port", default="8021",
help="FreeSWITCH server event socket port")
parser.add_option("-c", "--command", dest="command",
help="command to run, surround mutli word commands in \"\'s")
(options, args) = parser.parse_args()
con = ESLconnection(options.server, options.port, options.auth)
#are we connected?
if con.connected():
#run command
e = con.api(options.command)
print e.getBody()
else:
print "Not Connected"
sys.exit(2)
except:
print parser.get_usage()
if __name__ == "__main__":
main(sys.argv[1:])

View File

@ -0,0 +1,6 @@
## WARNING: new default module is mod_python3
`freeswitch-mod-python` debian package is NOT going to be installed by default.
`freeswitch-mod-python3` will be installed instead.
You should remove `freeswitch-mod-python3` package and install `freeswitch-mod-python` manually if you want.

View File

@ -0,0 +1,2 @@
mod_python_wrap.cpp -diff
freeswitch.py -diff

View File

@ -0,0 +1,30 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_python3
PYMOD=freeswitch
PYTHON3_SITE_DIR=@PYTHON3_SITE_DIR@
SWIGCFILE=../../../switch_swig.c
SWIGIFILE=../../../switch_swig.i
mod_LTLIBRARIES = mod_python3.la
mod_python3_la_SOURCES = mod_python3.c freeswitch_python.cpp mod_python_wrap.cpp
mod_python3_la_CFLAGS = $(SWITCH_AM_CFLAGS)
mod_python3_la_CPPFLAGS = @PYTHON3_CFLAGS@ -I$(switch_srcdir)/libs/libteletone/src/ $(SWITCH_AM_CPPFLAGS)
mod_python3_la_LIBADD = $(switch_builddir)/libfreeswitch.la
mod_python3_la_LDFLAGS = -avoid-version -module -no-undefined -shared @PYTHON3_LDFLAGS@
reswig: swigclean mod_python_wrap.cpp
swigclean: clean
rm -f mod_python_wrap.* freeswitch.py
mod_python_wrap.cpp: mod_python_extra.c hack.diff
swig3.0 -python -c++ -I../../../../src/include -oh mod_python_wrap.h -o mod_python_wrap.cpp mod_python.i
echo "#include \"mod_python_extra.c\"" >> mod_python_wrap.cpp
patch -s -p0 -i hack.diff
install-data-local:
mkdir -m755 -p $(DESTDIR)$(PYTHON3_SITE_DIR)
cp -f freeswitch.py $(DESTDIR)$(PYTHON3_SITE_DIR)

View File

@ -0,0 +1,6 @@
## WARNING: new default module is mod_python3
`freeswitch-mod-python` debian package is NOT going to be installed by default.
`freeswitch-mod-python3` will be installed instead.
You should remove `freeswitch-mod-python3` package and install `freeswitch-mod-python` manually if you want.

View File

@ -0,0 +1,702 @@
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.12
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.
from sys import version_info as _swig_python_version_info
if _swig_python_version_info >= (2, 7, 0):
def swig_import_helper():
import importlib
pkg = __name__.rpartition('.')[0]
mname = '.'.join((pkg, '_freeswitch')).lstrip('.')
try:
return importlib.import_module(mname)
except ImportError:
return importlib.import_module('_freeswitch')
_freeswitch = swig_import_helper()
del swig_import_helper
elif _swig_python_version_info >= (2, 6, 0):
def swig_import_helper():
from os.path import dirname
import imp
fp = None
try:
fp, pathname, description = imp.find_module('_freeswitch', [dirname(__file__)])
except ImportError:
import _freeswitch
return _freeswitch
try:
_mod = imp.load_module('_freeswitch', fp, pathname, description)
finally:
if fp is not None:
fp.close()
return _mod
_freeswitch = swig_import_helper()
del swig_import_helper
else:
import _freeswitch
del _swig_python_version_info
try:
_swig_property = property
except NameError:
pass # Python < 2.2 doesn't have 'property'.
try:
import builtins as __builtin__
except ImportError:
import __builtin__
def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
if (name == "thisown"):
return self.this.own(value)
if (name == "this"):
if type(value).__name__ == 'SwigPyObject':
self.__dict__[name] = value
return
method = class_type.__swig_setmethods__.get(name, None)
if method:
return method(self, value)
if (not static):
if _newclass:
object.__setattr__(self, name, value)
else:
self.__dict__[name] = value
else:
raise AttributeError("You cannot add attributes to %s" % self)
def _swig_setattr(self, class_type, name, value):
return _swig_setattr_nondynamic(self, class_type, name, value, 0)
def _swig_getattr(self, class_type, name):
if (name == "thisown"):
return self.this.own()
method = class_type.__swig_getmethods__.get(name, None)
if method:
return method(self)
raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
def _swig_repr(self):
try:
strthis = "proxy of " + self.this.__repr__()
except __builtin__.Exception:
strthis = ""
return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
try:
_object = object
_newclass = 1
except __builtin__.Exception:
class _object:
pass
_newclass = 0
def setGlobalVariable(var_name, var_val):
return _freeswitch.setGlobalVariable(var_name, var_val)
setGlobalVariable = _freeswitch.setGlobalVariable
def getGlobalVariable(var_name):
return _freeswitch.getGlobalVariable(var_name)
getGlobalVariable = _freeswitch.getGlobalVariable
def consoleLog(level_str, msg):
return _freeswitch.consoleLog(level_str, msg)
consoleLog = _freeswitch.consoleLog
def consoleLog2(level_str, file, func, line, msg):
return _freeswitch.consoleLog2(level_str, file, func, line, msg)
consoleLog2 = _freeswitch.consoleLog2
def consoleCleanLog(msg):
return _freeswitch.consoleCleanLog(msg)
consoleCleanLog = _freeswitch.consoleCleanLog
def running():
return _freeswitch.running()
running = _freeswitch.running
def email(to, arg2, headers=None, body=None, file=None, convert_cmd=None, convert_ext=None):
return _freeswitch.email(to, arg2, headers, body, file, convert_cmd, convert_ext)
email = _freeswitch.email
class IVRMenu(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, IVRMenu, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, IVRMenu, name)
__repr__ = _swig_repr
def __init__(self, main, name, greeting_sound, short_greeting_sound, invalid_sound, exit_sound, transfer_sound, confirm_macro, confirm_key, tts_engine, tts_voice, confirm_attempts, inter_timeout, digit_len, timeout, max_failures, max_timeouts):
this = _freeswitch.new_IVRMenu(main, name, greeting_sound, short_greeting_sound, invalid_sound, exit_sound, transfer_sound, confirm_macro, confirm_key, tts_engine, tts_voice, confirm_attempts, inter_timeout, digit_len, timeout, max_failures, max_timeouts)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_IVRMenu
__del__ = lambda self: None
def bindAction(self, action, arg, bind):
return _freeswitch.IVRMenu_bindAction(self, action, arg, bind)
def execute(self, session, name):
return _freeswitch.IVRMenu_execute(self, session, name)
IVRMenu_swigregister = _freeswitch.IVRMenu_swigregister
IVRMenu_swigregister(IVRMenu)
class API(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, API, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, API, name)
__repr__ = _swig_repr
def __init__(self, s=None):
this = _freeswitch.new_API(s)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_API
__del__ = lambda self: None
def execute(self, command, data=None):
return _freeswitch.API_execute(self, command, data)
def executeString(self, command):
return _freeswitch.API_executeString(self, command)
def getTime(self):
return _freeswitch.API_getTime(self)
API_swigregister = _freeswitch.API_swigregister
API_swigregister(API)
class input_callback_state_t(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, input_callback_state_t, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, input_callback_state_t, name)
__repr__ = _swig_repr
__swig_setmethods__["function"] = _freeswitch.input_callback_state_t_function_set
__swig_getmethods__["function"] = _freeswitch.input_callback_state_t_function_get
if _newclass:
function = _swig_property(_freeswitch.input_callback_state_t_function_get, _freeswitch.input_callback_state_t_function_set)
__swig_setmethods__["threadState"] = _freeswitch.input_callback_state_t_threadState_set
__swig_getmethods__["threadState"] = _freeswitch.input_callback_state_t_threadState_get
if _newclass:
threadState = _swig_property(_freeswitch.input_callback_state_t_threadState_get, _freeswitch.input_callback_state_t_threadState_set)
__swig_setmethods__["extra"] = _freeswitch.input_callback_state_t_extra_set
__swig_getmethods__["extra"] = _freeswitch.input_callback_state_t_extra_get
if _newclass:
extra = _swig_property(_freeswitch.input_callback_state_t_extra_get, _freeswitch.input_callback_state_t_extra_set)
__swig_setmethods__["funcargs"] = _freeswitch.input_callback_state_t_funcargs_set
__swig_getmethods__["funcargs"] = _freeswitch.input_callback_state_t_funcargs_get
if _newclass:
funcargs = _swig_property(_freeswitch.input_callback_state_t_funcargs_get, _freeswitch.input_callback_state_t_funcargs_set)
def __init__(self):
this = _freeswitch.new_input_callback_state_t()
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_input_callback_state_t
__del__ = lambda self: None
input_callback_state_t_swigregister = _freeswitch.input_callback_state_t_swigregister
input_callback_state_t_swigregister(input_callback_state_t)
S_HUP = _freeswitch.S_HUP
S_FREE = _freeswitch.S_FREE
S_RDLOCK = _freeswitch.S_RDLOCK
class DTMF(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, DTMF, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, DTMF, name)
__repr__ = _swig_repr
__swig_setmethods__["digit"] = _freeswitch.DTMF_digit_set
__swig_getmethods__["digit"] = _freeswitch.DTMF_digit_get
if _newclass:
digit = _swig_property(_freeswitch.DTMF_digit_get, _freeswitch.DTMF_digit_set)
__swig_setmethods__["duration"] = _freeswitch.DTMF_duration_set
__swig_getmethods__["duration"] = _freeswitch.DTMF_duration_get
if _newclass:
duration = _swig_property(_freeswitch.DTMF_duration_get, _freeswitch.DTMF_duration_set)
def __init__(self, *args):
this = _freeswitch.new_DTMF(*args)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_DTMF
__del__ = lambda self: None
DTMF_swigregister = _freeswitch.DTMF_swigregister
DTMF_swigregister(DTMF)
class Stream(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, Stream, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, Stream, name)
__repr__ = _swig_repr
def __init__(self, *args):
this = _freeswitch.new_Stream(*args)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_Stream
__del__ = lambda self: None
def read(self, len):
return _freeswitch.Stream_read(self, len)
def write(self, data):
return _freeswitch.Stream_write(self, data)
def raw_write(self, data, len):
return _freeswitch.Stream_raw_write(self, data, len)
def get_data(self):
return _freeswitch.Stream_get_data(self)
Stream_swigregister = _freeswitch.Stream_swigregister
Stream_swigregister(Stream)
class Event(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, Event, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, Event, name)
__repr__ = _swig_repr
__swig_setmethods__["event"] = _freeswitch.Event_event_set
__swig_getmethods__["event"] = _freeswitch.Event_event_get
if _newclass:
event = _swig_property(_freeswitch.Event_event_get, _freeswitch.Event_event_set)
__swig_setmethods__["serialized_string"] = _freeswitch.Event_serialized_string_set
__swig_getmethods__["serialized_string"] = _freeswitch.Event_serialized_string_get
if _newclass:
serialized_string = _swig_property(_freeswitch.Event_serialized_string_get, _freeswitch.Event_serialized_string_set)
__swig_setmethods__["mine"] = _freeswitch.Event_mine_set
__swig_getmethods__["mine"] = _freeswitch.Event_mine_get
if _newclass:
mine = _swig_property(_freeswitch.Event_mine_get, _freeswitch.Event_mine_set)
def __init__(self, *args):
this = _freeswitch.new_Event(*args)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_Event
__del__ = lambda self: None
def chat_execute(self, app, data=None):
return _freeswitch.Event_chat_execute(self, app, data)
def chat_send(self, dest_proto=None):
return _freeswitch.Event_chat_send(self, dest_proto)
def serialize(self, format=None):
return _freeswitch.Event_serialize(self, format)
def setPriority(self, *args):
return _freeswitch.Event_setPriority(self, *args)
def getHeader(self, header_name):
return _freeswitch.Event_getHeader(self, header_name)
def getBody(self):
return _freeswitch.Event_getBody(self)
def getType(self):
return _freeswitch.Event_getType(self)
def addBody(self, value):
return _freeswitch.Event_addBody(self, value)
def addHeader(self, header_name, value):
return _freeswitch.Event_addHeader(self, header_name, value)
def delHeader(self, header_name):
return _freeswitch.Event_delHeader(self, header_name)
def fire(self):
return _freeswitch.Event_fire(self)
def merge(self, to_merge):
return _freeswitch.Event_merge(self, to_merge)
Event_swigregister = _freeswitch.Event_swigregister
Event_swigregister(Event)
class EventConsumer(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, EventConsumer, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, EventConsumer, name)
__repr__ = _swig_repr
__swig_setmethods__["events"] = _freeswitch.EventConsumer_events_set
__swig_getmethods__["events"] = _freeswitch.EventConsumer_events_get
if _newclass:
events = _swig_property(_freeswitch.EventConsumer_events_get, _freeswitch.EventConsumer_events_set)
__swig_setmethods__["e_event_id"] = _freeswitch.EventConsumer_e_event_id_set
__swig_getmethods__["e_event_id"] = _freeswitch.EventConsumer_e_event_id_get
if _newclass:
e_event_id = _swig_property(_freeswitch.EventConsumer_e_event_id_get, _freeswitch.EventConsumer_e_event_id_set)
__swig_setmethods__["e_callback"] = _freeswitch.EventConsumer_e_callback_set
__swig_getmethods__["e_callback"] = _freeswitch.EventConsumer_e_callback_get
if _newclass:
e_callback = _swig_property(_freeswitch.EventConsumer_e_callback_get, _freeswitch.EventConsumer_e_callback_set)
__swig_setmethods__["e_subclass_name"] = _freeswitch.EventConsumer_e_subclass_name_set
__swig_getmethods__["e_subclass_name"] = _freeswitch.EventConsumer_e_subclass_name_get
if _newclass:
e_subclass_name = _swig_property(_freeswitch.EventConsumer_e_subclass_name_get, _freeswitch.EventConsumer_e_subclass_name_set)
__swig_setmethods__["e_cb_arg"] = _freeswitch.EventConsumer_e_cb_arg_set
__swig_getmethods__["e_cb_arg"] = _freeswitch.EventConsumer_e_cb_arg_get
if _newclass:
e_cb_arg = _swig_property(_freeswitch.EventConsumer_e_cb_arg_get, _freeswitch.EventConsumer_e_cb_arg_set)
__swig_setmethods__["enodes"] = _freeswitch.EventConsumer_enodes_set
__swig_getmethods__["enodes"] = _freeswitch.EventConsumer_enodes_get
if _newclass:
enodes = _swig_property(_freeswitch.EventConsumer_enodes_get, _freeswitch.EventConsumer_enodes_set)
__swig_setmethods__["node_index"] = _freeswitch.EventConsumer_node_index_set
__swig_getmethods__["node_index"] = _freeswitch.EventConsumer_node_index_get
if _newclass:
node_index = _swig_property(_freeswitch.EventConsumer_node_index_get, _freeswitch.EventConsumer_node_index_set)
def __init__(self, *args):
this = _freeswitch.new_EventConsumer(*args)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_EventConsumer
__del__ = lambda self: None
def bind(self, *args):
return _freeswitch.EventConsumer_bind(self, *args)
def pop(self, block=0, timeout=0):
return _freeswitch.EventConsumer_pop(self, block, timeout)
def cleanup(self):
return _freeswitch.EventConsumer_cleanup(self)
EventConsumer_swigregister = _freeswitch.EventConsumer_swigregister
EventConsumer_swigregister(EventConsumer)
class CoreSession(_object):
__swig_setmethods__ = {}
__setattr__ = lambda self, name, value: _swig_setattr(self, CoreSession, name, value)
__swig_getmethods__ = {}
__getattr__ = lambda self, name: _swig_getattr(self, CoreSession, name)
def __init__(self, *args, **kwargs):
raise AttributeError("No constructor defined - class is abstract")
__repr__ = _swig_repr
__swig_destroy__ = _freeswitch.delete_CoreSession
__del__ = lambda self: None
__swig_setmethods__["session"] = _freeswitch.CoreSession_session_set
__swig_getmethods__["session"] = _freeswitch.CoreSession_session_get
if _newclass:
session = _swig_property(_freeswitch.CoreSession_session_get, _freeswitch.CoreSession_session_set)
__swig_setmethods__["channel"] = _freeswitch.CoreSession_channel_set
__swig_getmethods__["channel"] = _freeswitch.CoreSession_channel_get
if _newclass:
channel = _swig_property(_freeswitch.CoreSession_channel_get, _freeswitch.CoreSession_channel_set)
__swig_setmethods__["flags"] = _freeswitch.CoreSession_flags_set
__swig_getmethods__["flags"] = _freeswitch.CoreSession_flags_get
if _newclass:
flags = _swig_property(_freeswitch.CoreSession_flags_get, _freeswitch.CoreSession_flags_set)
__swig_setmethods__["allocated"] = _freeswitch.CoreSession_allocated_set
__swig_getmethods__["allocated"] = _freeswitch.CoreSession_allocated_get
if _newclass:
allocated = _swig_property(_freeswitch.CoreSession_allocated_get, _freeswitch.CoreSession_allocated_set)
__swig_setmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_set
__swig_getmethods__["cb_state"] = _freeswitch.CoreSession_cb_state_get
if _newclass:
cb_state = _swig_property(_freeswitch.CoreSession_cb_state_get, _freeswitch.CoreSession_cb_state_set)
__swig_setmethods__["hook_state"] = _freeswitch.CoreSession_hook_state_set
__swig_getmethods__["hook_state"] = _freeswitch.CoreSession_hook_state_get
if _newclass:
hook_state = _swig_property(_freeswitch.CoreSession_hook_state_get, _freeswitch.CoreSession_hook_state_set)
__swig_setmethods__["cause"] = _freeswitch.CoreSession_cause_set
__swig_getmethods__["cause"] = _freeswitch.CoreSession_cause_get
if _newclass:
cause = _swig_property(_freeswitch.CoreSession_cause_get, _freeswitch.CoreSession_cause_set)
__swig_setmethods__["uuid"] = _freeswitch.CoreSession_uuid_set
__swig_getmethods__["uuid"] = _freeswitch.CoreSession_uuid_get
if _newclass:
uuid = _swig_property(_freeswitch.CoreSession_uuid_get, _freeswitch.CoreSession_uuid_set)
__swig_setmethods__["tts_name"] = _freeswitch.CoreSession_tts_name_set
__swig_getmethods__["tts_name"] = _freeswitch.CoreSession_tts_name_get
if _newclass:
tts_name = _swig_property(_freeswitch.CoreSession_tts_name_get, _freeswitch.CoreSession_tts_name_set)
__swig_setmethods__["voice_name"] = _freeswitch.CoreSession_voice_name_set
__swig_getmethods__["voice_name"] = _freeswitch.CoreSession_voice_name_get
if _newclass:
voice_name = _swig_property(_freeswitch.CoreSession_voice_name_get, _freeswitch.CoreSession_voice_name_set)
def insertFile(self, file, insert_file, sample_point):
return _freeswitch.CoreSession_insertFile(self, file, insert_file, sample_point)
def answer(self):
return _freeswitch.CoreSession_answer(self)
def _print(self, txt):
return _freeswitch.CoreSession__print(self, txt)
def preAnswer(self):
return _freeswitch.CoreSession_preAnswer(self)
def hangup(self, *args):
return _freeswitch.CoreSession_hangup(self, *args)
def hangupState(self):
return _freeswitch.CoreSession_hangupState(self)
def setVariable(self, var, val):
return _freeswitch.CoreSession_setVariable(self, var, val)
def setPrivate(self, var, val):
return _freeswitch.CoreSession_setPrivate(self, var, val)
def getPrivate(self, var):
return _freeswitch.CoreSession_getPrivate(self, var)
def getVariable(self, var):
return _freeswitch.CoreSession_getVariable(self, var)
def process_callback_result(self, result):
return _freeswitch.CoreSession_process_callback_result(self, result)
def say(self, tosay, module_name, say_type, say_method, say_gender=None):
return _freeswitch.CoreSession_say(self, tosay, module_name, say_type, say_method, say_gender)
def sayPhrase(self, *args):
return _freeswitch.CoreSession_sayPhrase(self, *args)
def hangupCause(self):
return _freeswitch.CoreSession_hangupCause(self)
def getState(self):
return _freeswitch.CoreSession_getState(self)
def recordFile(self, file_name, time_limit=0, silence_threshold=0, silence_hits=0):
return _freeswitch.CoreSession_recordFile(self, file_name, time_limit, silence_threshold, silence_hits)
def originate(self, a_leg_session, dest, timeout=60, handlers=None):
return _freeswitch.CoreSession_originate(self, a_leg_session, dest, timeout, handlers)
def destroy(self):
return _freeswitch.CoreSession_destroy(self)
def setDTMFCallback(self, cbfunc, funcargs):
return _freeswitch.CoreSession_setDTMFCallback(self, cbfunc, funcargs)
def speak(self, text):
return _freeswitch.CoreSession_speak(self, text)
def set_tts_parms(self, tts_name, voice_name):
return _freeswitch.CoreSession_set_tts_parms(self, tts_name, voice_name)
def set_tts_params(self, tts_name, voice_name):
return _freeswitch.CoreSession_set_tts_params(self, tts_name, voice_name)
def collectDigits(self, *args):
return _freeswitch.CoreSession_collectDigits(self, *args)
def getDigits(self, *args):
return _freeswitch.CoreSession_getDigits(self, *args)
def transfer(self, extension, dialplan=None, context=None):
return _freeswitch.CoreSession_transfer(self, extension, dialplan, context)
def read(self, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout=0):
return _freeswitch.CoreSession_read(self, min_digits, max_digits, prompt_audio_file, timeout, valid_terminators, digit_timeout)
def detectSpeech(self, arg0, arg1=None, arg2=None, arg3=None):
return _freeswitch.CoreSession_detectSpeech(self, arg0, arg1, arg2, arg3)
def playAndGetDigits(self, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name=None, digit_timeout=0, transfer_on_failure=None):
return _freeswitch.CoreSession_playAndGetDigits(self, min_digits, max_digits, max_tries, timeout, terminators, audio_files, bad_input_audio_files, digits_regex, var_name, digit_timeout, transfer_on_failure)
def playAndDetectSpeech(self, file, engine, grammar):
return _freeswitch.CoreSession_playAndDetectSpeech(self, file, engine, grammar)
def streamFile(self, file, starting_sample_count=0):
return _freeswitch.CoreSession_streamFile(self, file, starting_sample_count)
def sleep(self, ms, sync=0):
return _freeswitch.CoreSession_sleep(self, ms, sync)
def flushEvents(self):
return _freeswitch.CoreSession_flushEvents(self)
def flushDigits(self):
return _freeswitch.CoreSession_flushDigits(self)
def setAutoHangup(self, val):
return _freeswitch.CoreSession_setAutoHangup(self, val)
def setHangupHook(self, hangup_func):
return _freeswitch.CoreSession_setHangupHook(self, hangup_func)
def ready(self):
return _freeswitch.CoreSession_ready(self)
def bridged(self):
return _freeswitch.CoreSession_bridged(self)
def answered(self):
return _freeswitch.CoreSession_answered(self)
def mediaReady(self):
return _freeswitch.CoreSession_mediaReady(self)
def waitForAnswer(self, calling_session):
return _freeswitch.CoreSession_waitForAnswer(self, calling_session)
def execute(self, app, data=None):
return _freeswitch.CoreSession_execute(self, app, data)
def sendEvent(self, sendME):
return _freeswitch.CoreSession_sendEvent(self, sendME)
def setEventData(self, e):
return _freeswitch.CoreSession_setEventData(self, e)
def getXMLCDR(self):
return _freeswitch.CoreSession_getXMLCDR(self)
def begin_allow_threads(self):
return _freeswitch.CoreSession_begin_allow_threads(self)
def end_allow_threads(self):
return _freeswitch.CoreSession_end_allow_threads(self)
def get_uuid(self):
return _freeswitch.CoreSession_get_uuid(self)
def get_cb_args(self):
return _freeswitch.CoreSession_get_cb_args(self)
def check_hangup_hook(self):
return _freeswitch.CoreSession_check_hangup_hook(self)
def run_dtmf_callback(self, input, itype):
return _freeswitch.CoreSession_run_dtmf_callback(self, input, itype)
def consoleLog(self, level_str, msg):
return _freeswitch.CoreSession_consoleLog(self, level_str, msg)
def consoleLog2(self, level_str, file, func, line, msg):
return _freeswitch.CoreSession_consoleLog2(self, level_str, file, func, line, msg)
CoreSession_swigregister = _freeswitch.CoreSession_swigregister
CoreSession_swigregister(CoreSession)
def console_log(level_str, msg):
return _freeswitch.console_log(level_str, msg)
console_log = _freeswitch.console_log
def console_log2(level_str, file, func, line, msg):
return _freeswitch.console_log2(level_str, file, func, line, msg)
console_log2 = _freeswitch.console_log2
def console_clean_log(msg):
return _freeswitch.console_clean_log(msg)
console_clean_log = _freeswitch.console_clean_log
def msleep(ms):
return _freeswitch.msleep(ms)
msleep = _freeswitch.msleep
def bridge(session_a, session_b):
return _freeswitch.bridge(session_a, session_b)
bridge = _freeswitch.bridge
def hanguphook(session):
return _freeswitch.hanguphook(session)
hanguphook = _freeswitch.hanguphook
def dtmf_callback(session, input, itype, buf, buflen):
return _freeswitch.dtmf_callback(session, input, itype, buf, buflen)
dtmf_callback = _freeswitch.dtmf_callback
class Session(CoreSession):
__swig_setmethods__ = {}
for _s in [CoreSession]:
__swig_setmethods__.update(getattr(_s, '__swig_setmethods__', {}))
__setattr__ = lambda self, name, value: _swig_setattr(self, Session, name, value)
__swig_getmethods__ = {}
for _s in [CoreSession]:
__swig_getmethods__.update(getattr(_s, '__swig_getmethods__', {}))
__getattr__ = lambda self, name: _swig_getattr(self, Session, name)
__repr__ = _swig_repr
def __init__(self, *args):
this = _freeswitch.new_Session(*args)
try:
self.this.append(this)
except __builtin__.Exception:
self.this = this
__swig_destroy__ = _freeswitch.delete_Session
__del__ = lambda self: None
def begin_allow_threads(self):
return _freeswitch.Session_begin_allow_threads(self)
def end_allow_threads(self):
return _freeswitch.Session_end_allow_threads(self)
def check_hangup_hook(self):
return _freeswitch.Session_check_hangup_hook(self)
def destroy(self):
return _freeswitch.Session_destroy(self)
def run_dtmf_callback(self, input, itype):
return _freeswitch.Session_run_dtmf_callback(self, input, itype)
def setInputCallback(self, cbfunc, funcargs=None):
return _freeswitch.Session_setInputCallback(self, cbfunc, funcargs)
def unsetInputCallback(self):
return _freeswitch.Session_unsetInputCallback(self)
def setHangupHook(self, pyfunc, arg=None):
return _freeswitch.Session_setHangupHook(self, pyfunc, arg)
def ready(self):
return _freeswitch.Session_ready(self)
__swig_setmethods__["cb_function"] = _freeswitch.Session_cb_function_set
__swig_getmethods__["cb_function"] = _freeswitch.Session_cb_function_get
if _newclass:
cb_function = _swig_property(_freeswitch.Session_cb_function_get, _freeswitch.Session_cb_function_set)
__swig_setmethods__["cb_arg"] = _freeswitch.Session_cb_arg_set
__swig_getmethods__["cb_arg"] = _freeswitch.Session_cb_arg_get
if _newclass:
cb_arg = _swig_property(_freeswitch.Session_cb_arg_get, _freeswitch.Session_cb_arg_set)
__swig_setmethods__["hangup_func"] = _freeswitch.Session_hangup_func_set
__swig_getmethods__["hangup_func"] = _freeswitch.Session_hangup_func_get
if _newclass:
hangup_func = _swig_property(_freeswitch.Session_hangup_func_get, _freeswitch.Session_hangup_func_set)
__swig_setmethods__["hangup_func_arg"] = _freeswitch.Session_hangup_func_arg_set
__swig_getmethods__["hangup_func_arg"] = _freeswitch.Session_hangup_func_arg_get
if _newclass:
hangup_func_arg = _swig_property(_freeswitch.Session_hangup_func_arg_get, _freeswitch.Session_hangup_func_arg_set)
def setPython(self, state):
return _freeswitch.Session_setPython(self, state)
def setSelf(self, state):
return _freeswitch.Session_setSelf(self, state)
Session_swigregister = _freeswitch.Session_swigregister
Session_swigregister(Session)
# This file is compatible with both classic and new-style classes.

View File

@ -0,0 +1,342 @@
#include <switch.h>
#include "freeswitch_python.h"
using namespace PYTHON;
#define py_init_vars() cb_function = cb_arg = hangup_func = hangup_func_arg = NULL; hh = mark = 0; TS = NULL
#define PyString_AsString PyUnicode_AsUTF8
#define PyString_Check PyUnicode_Check
Session::Session():CoreSession()
{
py_init_vars();
}
Session::Session(char *nuuid, CoreSession *a_leg):CoreSession(nuuid, a_leg)
{
py_init_vars();
}
Session::Session(switch_core_session_t *new_session):CoreSession(new_session)
{
py_init_vars();
}
static switch_status_t python_hanguphook(switch_core_session_t *session_hungup);
void Session::destroy(void)
{
if (!allocated) {
return;
}
if (session) {
if (!channel) {
channel = switch_core_session_get_channel(session);
}
switch_channel_set_private(channel, "CoreSession", NULL);
switch_core_event_hook_remove_state_change(session, python_hanguphook);
}
if (hangup_func) {
Py_DECREF(hangup_func);
hangup_func = NULL;
}
if (hangup_func_arg) {
Py_DECREF(hangup_func_arg);
hangup_func_arg = NULL;
}
if (cb_function) {
Py_DECREF(cb_function);
cb_function = NULL;
}
if (cb_arg) {
Py_DECREF(cb_arg);
cb_arg = NULL;
}
CoreSession::destroy();
}
Session::~Session()
{
destroy();
}
bool Session::begin_allow_threads()
{
do_hangup_hook();
if (!TS) {
TS = PyEval_SaveThread();
if (channel) {
switch_channel_set_private(channel, "SwapInThreadState", TS);
}
return true;
}
return false;
}
bool Session::end_allow_threads()
{
if (!TS) {
return false;
}
PyEval_RestoreThread(TS);
TS = NULL;
if (channel) {
switch_channel_set_private(channel, "SwapInThreadState", NULL);
}
do_hangup_hook();
return true;
}
void Session::setPython(PyObject *state)
{
Py = state;
}
void Session::setSelf(PyObject *state)
{
Self = state;
}
PyObject *Session::getPython()
{
return Py;
}
bool Session::ready()
{
bool r;
sanity_check(false);
r = switch_channel_ready(channel) != 0;
/*! this is called every time ready is called as a workaround to
make it threadsafe. it sets a flag, and all the places where it
comes in and out of threadswap, check it. so the end result is
you still get the hangup hook executed pretty soon after you
hangup. */
do_hangup_hook();
return r;
}
void Session::check_hangup_hook()
{
if (hangup_func && (hook_state == CS_HANGUP || hook_state == CS_ROUTING)) {
hh++;
}
}
void Session::do_hangup_hook()
{
PyObject *result, *arglist;
const char *what = hook_state == CS_HANGUP ? "hangup" : "transfer";
if (hh && !mark) {
mark++;
if (hangup_func) {
if (!PyCallable_Check(hangup_func)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n");
return;
}
if (!Self) {
mod_python_conjure_session(NULL, session);
}
if (hangup_func_arg) {
arglist = Py_BuildValue("(OsO)", Self, what, hangup_func_arg);
} else {
arglist = Py_BuildValue("(Os)", Self, what);
}
if (!(result = PyEval_CallObject(hangup_func, arglist))) {
PyErr_Print();
}
Py_XDECREF(arglist);
Py_XDECREF(hangup_func_arg);
}
}
}
static switch_status_t python_hanguphook(switch_core_session_t *session_hungup)
{
switch_channel_t *channel = switch_core_session_get_channel(session_hungup);
CoreSession *coresession = NULL;
switch_channel_state_t state = switch_channel_get_state(channel);
if ((coresession = (CoreSession *) switch_channel_get_private(channel, "CoreSession"))) {
if (coresession->hook_state != state) {
coresession->hook_state = state;
coresession->check_hangup_hook();
}
}
return SWITCH_STATUS_SUCCESS;
}
void Session::setHangupHook(PyObject *pyfunc, PyObject *arg)
{
if (!PyCallable_Check(pyfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hangup hook is not a python function.\n");
return;
}
if (hangup_func) {
if (session) {
switch_core_event_hook_remove_state_change(session, python_hanguphook);
}
Py_XDECREF(hangup_func);
hangup_func = NULL;
}
if (hangup_func_arg) {
Py_XDECREF(hangup_func_arg);
hangup_func_arg = NULL;
}
hangup_func = pyfunc;
hangup_func_arg = arg;
Py_XINCREF(hangup_func);
if (hangup_func_arg) {
Py_XINCREF(hangup_func_arg);
}
switch_channel_set_private(channel, "CoreSession", this);
hook_state = switch_channel_get_state(channel);
switch_core_event_hook_add_state_change(session, python_hanguphook);
}
void Session::unsetInputCallback(void)
{
if (cb_function) {
Py_XDECREF(cb_function);
cb_function = NULL;
}
if (cb_arg) {
Py_XDECREF(cb_arg);
cb_arg = NULL;
}
args.input_callback = NULL;
ap = NULL;
}
void Session::setInputCallback(PyObject *cbfunc, PyObject *funcargs)
{
if (!PyCallable_Check(cbfunc)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Hangup hook is not a python function.\n");
return;
}
if (cb_function) {
Py_XDECREF(cb_function);
cb_function = NULL;
}
if (cb_arg) {
Py_XDECREF(cb_arg);
cb_arg = NULL;
}
cb_function = cbfunc;
cb_arg = funcargs;
args.buf = this;
switch_channel_set_private(channel, "CoreSession", this);
Py_XINCREF(cb_function);
if (cb_arg) {
Py_XINCREF(cb_arg);
}
args.input_callback = dtmf_callback;
ap = &args;
}
switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
{
PyObject *pyresult, *arglist, *io = NULL;
int ts = 0;
char *str = NULL, *what = "";
if (TS) {
ts++;
end_allow_threads();
}
if (!PyCallable_Check(cb_function)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "function not callable\n");
return SWITCH_STATUS_FALSE;
}
if (itype == SWITCH_INPUT_TYPE_DTMF) {
switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
io = mod_python_conjure_DTMF(dtmf->digit, dtmf->duration);
what = "dtmf";
} else if (itype == SWITCH_INPUT_TYPE_EVENT){
what = "event";
io = mod_python_conjure_event((switch_event_t *) input);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unsupported type!\n");
return SWITCH_STATUS_FALSE;
}
if (!Self) {
mod_python_conjure_session(NULL, session);
}
if (cb_arg) {
arglist = Py_BuildValue("(OsOO)", Self, what, io, cb_arg);
} else {
arglist = Py_BuildValue("(OsO)", Self, what, io);
}
if ((pyresult = PyEval_CallObject(cb_function, arglist))) {
str = (char *) PyString_AsString(pyresult);
} else {
PyErr_Print();
}
Py_XDECREF(arglist);
Py_XDECREF(io);
if (ts) {
begin_allow_threads();
}
if (str) {
return process_callback_result(str);
}
return SWITCH_STATUS_FALSE;
}

View File

@ -0,0 +1,49 @@
#ifndef FREESWITCH_PYTHON_H
#define FREESWITCH_PYTHON_H
extern "C" {
#include <Python.h>
#include "mod_python_extra.h"
}
#include <switch_cpp.h>
namespace PYTHON {
class Session:public CoreSession {
private:
virtual void do_hangup_hook();
PyObject *getPython();
PyObject *Py;
PyObject *Self;
int hh;
int mark;
PyThreadState *TS;
public:
Session();
Session(char *nuuid, CoreSession * a_leg = NULL);
Session(switch_core_session_t *session);
virtual ~ Session();
virtual bool begin_allow_threads();
virtual bool end_allow_threads();
virtual void check_hangup_hook();
virtual void destroy(void);
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
void setInputCallback(PyObject * cbfunc, PyObject * funcargs = NULL);
void unsetInputCallback(void);
void setHangupHook(PyObject * pyfunc, PyObject * arg = NULL);
bool ready();
PyObject *cb_function;
PyObject *cb_arg;
PyObject *hangup_func;
PyObject *hangup_func_arg;
/* keep a pointer to parent module, internal use only */
void setPython(PyObject * state);
/* keeps the PyObject * version of the Session so it can be used as args to the callback */
void setSelf(PyObject * state);
};
}
#endif

View File

@ -0,0 +1,117 @@
--- mod_python_wrap.cpp.old 2015-06-16 12:56:23.868000000 -0500
+++ mod_python_wrap.cpp 2015-06-16 12:56:32.268000000 -0500
@@ -3500,7 +3500,9 @@ SWIG_AsCharArray(PyObject * obj, char *val, size_t size)
if (csize <= size) {
if (val) {
if (csize) memcpy(val, cptr, csize*sizeof(char));
+#ifndef __clang_analyzer__
if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(char));
+#endif
}
if (alloc == SWIG_NEWOBJ) {
delete[] cptr;
@@ -4677,7 +4677,7 @@ SWIGINTERN PyObject *_wrap_DTMF_digit_set(PyObject *SWIGUNUSEDPARM(self), PyObje
char arg2 ;
void *argp1 = 0 ;
int res1 = 0 ;
- char val2 ;
+ char val2 = '\0';
int ecode2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
@@ -4787,7 +4787,7 @@ SWIGINTERN PyObject *_wrap_new_DTMF(PyObject *SWIGUNUSEDPARM(self), PyObject *ar
PyObject *resultobj = 0;
char arg1 ;
uint32_t arg2 = (uint32_t) SWITCH_DEFAULT_DTMF_DURATION ;
- char val1 ;
+ char val1 = '\0';
int ecode1 = 0 ;
void *argp2 ;
int res2 = 0 ;
@@ -6198,7 +6198,9 @@
}
arg3 = static_cast< int >(val3);
}
+ Py_BEGIN_ALLOW_THREADS;
result = (Event *)(arg1)->pop(arg2,arg3);
+ Py_END_ALLOW_THREADS;
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN | 0 );
return resultobj;
fail:
@@ -9264,20 +9266,20 @@
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_0(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
PYTHON::Session *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)":new_Session")) SWIG_fail;
result = (PYTHON::Session *)new PYTHON::Session();
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
return resultobj;
fail:
return NULL;
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_1(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
CoreSession *arg2 = (CoreSession *) 0 ;
@@ -9302,7 +9304,7 @@
}
arg2 = reinterpret_cast< CoreSession * >(argp2);
result = (PYTHON::Session *)new PYTHON::Session(arg1,arg2);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
return resultobj;
fail:
@@ -9311,7 +9313,7 @@
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_2(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
char *arg1 = (char *) 0 ;
int res1 ;
@@ -9327,7 +9329,7 @@
}
arg1 = reinterpret_cast< char * >(buf1);
result = (PYTHON::Session *)new PYTHON::Session(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
return resultobj;
fail:
@@ -9336,7 +9338,7 @@
}
-SWIGINTERN PyObject *_wrap_new_Session__SWIG_3(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_new_Session__SWIG_3(PyObject *self, PyObject *args) {
PyObject *resultobj = 0;
switch_core_session_t *arg1 = (switch_core_session_t *) 0 ;
void *argp1 = 0 ;
@@ -9351,7 +9353,7 @@
}
arg1 = reinterpret_cast< switch_core_session_t * >(argp1);
result = (PYTHON::Session *)new PYTHON::Session(arg1);
- resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 );
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_NEW | 0 ); result->setPython(self);
return resultobj;
fail:
return NULL;
@@ -10492,6 +10492,7 @@ SWIGINTERN PyObject *_wrap_Session_setSelf(PyObject *SWIGUNUSEDPARM(self), PyObj
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Session_setSelf" "', argument " "1"" of type '" "PYTHON::Session *""'");
}
arg1 = reinterpret_cast< PYTHON::Session * >(argp1);
+ if (!arg1) SWIG_exception_fail(SWIG_ValueError, "in method '" "Session_setSelf" "', argument " "1"" is NULL");
arg2 = obj1;
(arg1)->setSelf(arg2);
resultobj = SWIG_Py_Void();

View File

@ -0,0 +1,36 @@
%module freeswitch
%include "cstring.i"
%include ../../../../swig_common.i
/**
* tell swig to treat these variables as mutable so they
* can be used to return values.
* See http://www.swig.org/Doc1.3/Library.html
*/
%cstring_bounded_mutable(char *dtmf_buf, 128);
%cstring_bounded_mutable(char *terminator, 8);
%newobject EventConsumer::pop;
%newobject Session;
%newobject CoreSession;
%newobject Event;
%newobject Stream;
%newobject API::execute;
%newobject API::executeString;
%newobject CoreSession::playAndDetectSpeech;
/** insert the following includes into generated code so it compiles */
%{
#include "switch_cpp.h"
#include "freeswitch_python.h"
%}
%ignore SwitchToMempool;
/**
* tell swig to grok everything defined in these header files and
* build all sorts of c wrappers and python shadows of the c wrappers.
*/
%include switch_swigable_cpp.h
%include freeswitch_python.h

View File

@ -0,0 +1,674 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is
* Anthony Minessale II <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Brian Fertig <brian.fertig@convergencetek.com>
* Johny Kadarisman <jkr888@gmail.com>
* Traun Leyden <tleyden@branchcut.com>
* Heimo Stieg <heimo.stieg@nextiraone.eu>
*
* mod_python.c -- Python Module
*
*/
#include <Python.h>
#include <frameobject.h>
#ifndef _REENTRANT
#define _REENTRANT
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <switch.h>
#include "mod_python_extra.h"
#include <string.h>
#define PyString_AsString PyUnicode_AsUTF8
#define PyString_Check PyUnicode_Check
PyThreadState *mainThreadState = NULL;
PyMODINIT_FUNC PyInit__freeswitch(void);
int py_thread(const char *text);
static void set_max_recursion_depth(void);
static switch_api_interface_t python_run_interface;
static void print_python_error(const char * script);
SWITCH_MODULE_LOAD_FUNCTION(mod_python_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown);
SWITCH_MODULE_DEFINITION_EX(mod_python, mod_python_load, mod_python_shutdown, NULL, SMODF_GLOBAL_SYMBOLS);
static struct {
switch_memory_pool_t *pool;
char *xml_handler;
} globals;
struct switch_py_thread {
struct switch_py_thread *prev, *next;
char *cmd;
char *args;
switch_memory_pool_t *pool;
PyThreadState *tstate;
};
struct switch_py_thread *thread_pool_head = NULL;
static switch_mutex_t *THREAD_POOL_LOCK = NULL;
/**
* This function is similiar to PyErr_Print. It uses the freeswitch print/log mechanism instead of the python sys.stderr
*/
static void print_python_error(const char * script)
{
PyObject *pyType = NULL, *pyValue = NULL, *pyTraceback = NULL, *pyString = NULL;
PyObject *pyModule=NULL, *pyFunction = NULL, *pyResult = NULL;
char * buffer = (char*) malloc( 20 * 1024 * sizeof(char));
/* Variables for the traceback */
PyTracebackObject * pyTB = NULL/*, *pyTB2 = NULL*/;
char sTemp[256];
if (buffer == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not enough Memory to create the error buffer");
return;
}
/* just for security that we will always have a string terminater */
memset(buffer, 0, 20 * 1024 * sizeof(char) );
/*Get the errordata*/
PyErr_Fetch(&pyType, &pyValue, &pyTraceback);
PyErr_NormalizeException(&pyType, &pyValue, &pyTraceback);
/* Printing header*/
sprintf(buffer, "Python Error by calling script \"%s\": ", script );
if (pyType != NULL && (pyString=PyObject_Str(pyType))!=NULL && (PyString_Check(pyString))) {
strcat(buffer, PyString_AsString(pyString));
} else {
strcat(buffer, "<unknown exception type> ");
}
Py_XDECREF(pyString);
/*Print error message*/
if (pyValue != NULL && (pyString=PyObject_Str(pyValue))!=NULL && (PyString_Check(pyString))) {
strcat(buffer, "\nMessage: ");
strcat(buffer, PyString_AsString(pyString));
} else {
strcat(buffer, "\nMessage: <unknown exception date> ");
}
Py_XDECREF(pyString);
/* Print the traceback */
if (pyTraceback != NULL && PyTraceBack_Check(pyTraceback)) {
/*loading traceback module to create the exception data*/
pyModule = PyImport_ImportModule("traceback");
if (pyModule) {
strcat(buffer, "\nException: ");
pyFunction = PyObject_GetAttrString(pyModule, "format_exc");
if (pyFunction) {
pyResult = PyObject_CallObject(pyFunction, NULL);
if (pyResult && PyString_Check(pyResult)) {
strcat(buffer, PyString_AsString(pyResult));
} else {
strcat(buffer, "<exception not available>");
}
Py_XDECREF(pyFunction);
}
Py_XDECREF(pyModule);
}
/* Print traceback header */
strcat(buffer, "\nTraceback (most recent call last)");
pyTB = (PyTracebackObject*) pyTraceback;
/* Traceback */
do {
sprintf((char*)sTemp, "\n\tFile: \"%s\", line %i, in %s",
PyString_AsString(pyTB->tb_frame->f_code->co_filename),
pyTB->tb_lineno,
PyString_AsString(pyTB->tb_frame->f_code->co_name) );
strcat(buffer, (char*)sTemp);
pyTB=pyTB->tb_next;
} while(pyTB != NULL);
}
PyErr_Restore(pyType,pyValue,pyTraceback);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s\n", buffer);
/* free the resources, we dont need memory leaks here */
free(buffer);
}
static void eval_some_python(const char *funcname, char *args, switch_core_session_t *session, switch_stream_handle_t *stream, switch_event_t *params,
char **str, struct switch_py_thread *pt)
{
PyThreadState *tstate = NULL;
char *dupargs = NULL;
char *argv[2] = { 0 };
int argc;
char *script = NULL;
PyObject *module_o = NULL, *module = NULL, *sp = NULL, *stp = NULL, *eve = NULL;
PyObject *function = NULL;
PyObject *arg = NULL;
PyObject *result = NULL;
char *p;
if (str) {
*str = NULL;
}
if (args) {
dupargs = strdup(args);
} else {
return;
}
assert(dupargs != NULL);
if (!(argc = switch_separate_string(dupargs, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No module name specified!\n");
goto done;
}
script = strdup(switch_str_nil(argv[0]));
if ((p = strstr(script, "::"))) {
*p = '\0';
p += 2;
if (p) {
funcname = p;
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Invoking py module: %s\n", script);
tstate = PyThreadState_New(mainThreadState->interp);
if (!tstate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error acquiring tstate\n");
goto done;
}
/* Save state in thread struct so we can terminate it later if needed */
if (pt)
pt->tstate = tstate;
// swap in thread state
PyEval_AcquireThread(tstate);
if (session) {
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *add_path = switch_channel_get_variable(channel, "python_script_path");
if (!zstr(add_path)) {
char *buffer = (char*) malloc( 20 * 1024 * sizeof(char));
if (buffer == NULL ) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Not enough Memory to create the error buffer\n");
}
PyRun_SimpleString("import sys");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "LOADING path %s", add_path);
sprintf(buffer, "sys.path.append(\"%s\");", add_path );
PyRun_SimpleString(buffer);
switch_safe_free(buffer);
}
}
// import the module
module_o = PyImport_ImportModule((char *) script);
if (!module_o) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error importing module\n");
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
// reload the module
module = PyImport_ReloadModule(module_o);
if (!module) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error reloading module\n");
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
// get the handler function to be called
function = PyObject_GetAttrString(module, (char *) funcname);
if (!function) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Module does not define %s\n", funcname);
print_python_error(script);
PyErr_Clear();
goto done_swap_out;
}
PyRun_SimpleString("import freeswitch");
if (session) {
sp = mod_python_conjure_session(module, session);
}
if (params) {
eve = mod_python_conjure_event(params);
}
if (stream) {
stp = mod_python_conjure_stream(stream);
if (stream->param_event) {
Py_XDECREF(eve);
eve = mod_python_conjure_event(stream->param_event);
}
}
if (sp && eve && stp) {
arg = Py_BuildValue("(OOOs)", sp, stp, eve, switch_str_nil(argv[1]));
} else if (eve && stp) {
arg = Py_BuildValue("(sOOs)", "na", stp, eve, switch_str_nil(argv[1]));
} else if (eve) {
arg = Py_BuildValue("(Os)", eve, switch_str_nil(argv[1]));
} else if (sp) {
arg = Py_BuildValue("(Os)", sp, switch_str_nil(argv[1]));
} else {
arg = Py_BuildValue("(s)", switch_str_nil(argv[1]));
}
// invoke the handler
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call python script \n");
result = PyEval_CallObjectWithKeywords(function, arg, (PyObject *) NULL);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Finished calling python script \n");
// check the result and print out any errors
if (result) {
if (str) {
*str = strdup((char *) PyString_AsString(result));
}
} else if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
// Print error, but ignore SystemExit
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error calling python script\n");
print_python_error(script);
PyErr_Clear();
PyRun_SimpleString("python_makes_sense");
PyGC_Collect();
}
done_swap_out:
Py_XDECREF(result);
Py_XDECREF(arg);
Py_XDECREF(function);
Py_XDECREF(module);
Py_XDECREF(module_o);
Py_XDECREF(stp);
Py_XDECREF(eve);
Py_XDECREF(sp);
if (tstate) {
// thread state must be cleared explicitly or we'll get memory leaks
PyThreadState_Clear(tstate);
PyEval_ReleaseThread(tstate);
PyThreadState_Delete(tstate);
}
done:
switch_safe_free(dupargs);
switch_safe_free(script);
}
static switch_xml_t python_fetch(const char *section,
const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params, void *user_data)
{
switch_xml_t xml = NULL;
char *str = NULL;
if (!zstr(globals.xml_handler)) {
char *mycmd = strdup(globals.xml_handler);
switch_assert(mycmd);
eval_some_python("xml_fetch", mycmd, NULL, NULL, params, &str, NULL);
if (str) {
if (zstr(str)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Result\n");
} else if (!(xml = switch_xml_parse_str((char *) str, strlen(str)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Parsing XML Result!\n");
}
switch_safe_free(str);
}
free(mycmd);
}
return xml;
}
static switch_status_t do_config(void)
{
char *cf = "python.conf";
switch_xml_t cfg, xml, settings, param;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
return SWITCH_STATUS_TERM;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcmp(var, "xml-handler-script")) {
globals.xml_handler = switch_core_strdup(globals.pool, val);
} else if (!strcmp(var, "xml-handler-bindings")) {
if (!zstr(globals.xml_handler)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "binding '%s' to '%s'\n", globals.xml_handler, val);
switch_xml_bind_search_function(python_fetch, switch_xml_parse_section_string(val), NULL);
}
} else if (!strcmp(var, "startup-script")) {
if (val) {
py_thread(val);
}
}
}
}
switch_xml_free(xml);
return SWITCH_STATUS_SUCCESS;
}
/**
* As freeswitch runs with a smaller than normal stack size (240K instead of the usual value .. 1 or 2 MB),
* we must decrease the default python recursion limit accordingly. Otherwise, python can easily blow
* up the stack and the whole switch crashes. See modlang-134
*/
static void set_max_recursion_depth(void)
{
// assume that a stack frame is approximately 1K, so divide thread stack size (eg, 240K) by
// 1K to get the approx number of stack frames we can hold before blowing up.
int newMaxRecursionDepth = SWITCH_THREAD_STACKSIZE / 1024;
PyObject *sysModule = PyImport_ImportModule("sys");
PyObject *setRecursionLimit = PyObject_GetAttrString(sysModule, "setrecursionlimit");
PyObject *recLimit = Py_BuildValue("(i)", newMaxRecursionDepth);
PyObject *setrecursion_result = PyEval_CallObjectWithKeywords(setRecursionLimit, recLimit, (PyObject *) NULL);
if (setrecursion_result) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set python recursion limit to %d\n", newMaxRecursionDepth);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to set recursion limit to %d\n", newMaxRecursionDepth);
print_python_error("_freeswitch");
PyErr_Clear();
PyRun_SimpleString("python_makes_sense");
PyGC_Collect();
}
}
SWITCH_STANDARD_APP(python_function)
{
eval_some_python("handler", (char *) data, session, NULL, NULL, NULL, NULL);
}
static void *SWITCH_THREAD_FUNC py_thread_run(switch_thread_t *thread, void *obj)
{
switch_memory_pool_t *pool;
struct switch_py_thread *pt = (struct switch_py_thread *) obj;
/* Put thread in pool so we keep track of our threads */
switch_mutex_lock(THREAD_POOL_LOCK);
pt->next = thread_pool_head;
pt->prev = NULL;
if (pt->next)
pt->next->prev = pt;
thread_pool_head = pt;
switch_mutex_unlock(THREAD_POOL_LOCK);
/* Run the python script */
eval_some_python("runtime", pt->args, NULL, NULL, NULL, NULL, pt);
/* Thread is dead, remove from pool */
switch_mutex_lock(THREAD_POOL_LOCK);
if (pt->next)
pt->next->prev = pt->prev;
if (pt->prev)
pt->prev->next = pt->next;
if (thread_pool_head == pt)
thread_pool_head = pt->next;
switch_mutex_unlock(THREAD_POOL_LOCK);
pool = pt->pool;
switch_core_destroy_memory_pool(&pool);
return NULL;
}
SWITCH_STANDARD_API(api_python)
{
eval_some_python("fsapi", (char *) cmd, session, stream, NULL, NULL, NULL);
return SWITCH_STATUS_SUCCESS;
}
int py_thread(const char *text)
{
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
switch_memory_pool_t *pool;
struct switch_py_thread *pt;
switch_core_new_memory_pool(&pool);
assert(pool != NULL);
pt = switch_core_alloc(pool, sizeof(*pt));
assert(pt != NULL);
pt->pool = pool;
pt->args = switch_core_strdup(pt->pool, text);
switch_threadattr_create(&thd_attr, pt->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_thread_create(&thread, thd_attr, py_thread_run, pt, pt->pool);
return 0;
}
SWITCH_STANDARD_API(launch_python)
{
if (zstr(cmd)) {
stream->write_function(stream, "USAGE: %s\n", python_run_interface.syntax);
return SWITCH_STATUS_SUCCESS;
}
py_thread(cmd);
stream->write_function(stream, "OK\n");
return SWITCH_STATUS_SUCCESS;
}
SWITCH_STANDARD_CHAT_APP(python_chat_function)
{
eval_some_python("chat", (char *) data, NULL, NULL, message, NULL, NULL);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_python_load)
{
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
switch_chat_application_interface_t *chat_app_interface;
char *pp = getenv("PYTHONPATH");
if (pp) {
char *path = switch_mprintf("%s:%s", pp, SWITCH_GLOBAL_dirs.script_dir);
setenv("PYTHONPATH", path, 1);
free(path);
} else {
setenv("PYTHONPATH", SWITCH_GLOBAL_dirs.script_dir, 1);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Python Framework Loading...\n");
globals.pool = pool;
if (!Py_IsInitialized()) {
/* Add a built-in module, before Py_Initialize */
if (PyImport_AppendInittab("_freeswitch", PyInit__freeswitch) == -1) {
fprintf(stderr, "Error: could not extend in-built modules table\n");
}
// initialize python system
Py_Initialize();
// create GIL and a threadstate
PyEval_InitThreads();
// save threadstate since it's interp field will be needed
// to create new threadstates, and will be needed for shutdown
mainThreadState = PyThreadState_Get();
// set the maximum recursion depth
set_max_recursion_depth();
// swap out threadstate since the call threads will create
// their own and swap in their threadstate
PyThreadState_Swap(NULL);
// release GIL
PyEval_ReleaseLock();
}
switch_mutex_init(&THREAD_POOL_LOCK, SWITCH_MUTEX_NESTED, pool);
do_config();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
SWITCH_ADD_API(api_interface, "pyrun", "run a python script", launch_python, "python </path/to/script>");
SWITCH_ADD_API(api_interface, "python", "run a python script", api_python, "python </path/to/script>");
SWITCH_ADD_APP(app_interface, "python", "Launch python ivr", "Run a python ivr on a channel", python_function, "<script> [additional_vars [...]]",
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_CHAT_APP(chat_app_interface, "python", "execute a python script", "execute a python script", python_chat_function, "<script>", SCAF_NONE);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_NOUNLOAD;
}
/*
Called when the system shuts down*/
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_python_shutdown)
{
PyInterpreterState *mainInterpreterState;
PyThreadState *myThreadState;
int thread_cnt = 0;
struct switch_py_thread *pt = NULL;
struct switch_py_thread *nextpt;
int i;
/* Kill all remaining threads */
pt = thread_pool_head;
while (pt) {
thread_cnt++;
nextpt = pt->next;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Forcibly terminating script [%s]\n", pt->args);
/* Kill python script */
PyThreadState_Swap(pt->tstate);
PyThreadState_SetAsyncExc(pt->tstate->thread_id, PyExc_SystemExit);
pt = nextpt;
}
PyThreadState_Swap(mainThreadState);
PyEval_ReleaseLock();
switch_yield(1000000);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Had to kill %d threads\n", thread_cnt);
/* Give threads a few seconds to terminate.
Not using switch_thread_join() since if threads refuse to die
then freeswitch will hang */
for (i = 0; i < 10 && thread_pool_head; i++) {
switch_yield(1000000);
}
if (thread_pool_head) {
/* Not all threads died in time */
pt = thread_pool_head;
while (pt) {
nextpt = pt->next;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Script [%s] didn't exit in time\n", pt->args);
pt = nextpt;
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Forcing python shutdown. This might cause freeswitch to crash!\n");
}
mainInterpreterState = mainThreadState->interp;
myThreadState = PyThreadState_New(mainInterpreterState);
PyThreadState_Swap(myThreadState);
PyEval_ReleaseLock();
Py_Finalize();
PyEval_ReleaseLock();
return SWITCH_STATUS_UNLOAD;
}
/* Return the number of arguments of the application command line */
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/

View File

@ -0,0 +1,56 @@
SWITCH_BEGIN_EXTERN_C PyObject * mod_python_conjure_event(switch_event_t *event)
{
PyObject *obj;
Event *result = new Event(event, 0);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Event, SWIG_POINTER_OWN);
return obj;
}
PyObject *mod_python_conjure_stream(switch_stream_handle_t *stream)
{
PyObject *obj;
Stream *result = new Stream(stream);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Stream, SWIG_POINTER_OWN);
return obj;
}
PyObject *mod_python_conjure_session(PyObject * module, switch_core_session_t *session)
{
PyObject *obj;
PYTHON::Session * result = new PYTHON::Session(session);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_PYTHON__Session, SWIG_POINTER_OWN);
result->setPython(module);
result->setSelf(obj);
#if 0
if (module && name) {
PyDict_SetItem(PyModule_GetDict(module), Py_BuildValue("s", name), obj);
Py_DECREF(obj);
}
#endif
return obj;
}
PyObject *mod_python_conjure_DTMF(char digit, int32_t duration)
{
PyObject *obj;
DTMF *result = new DTMF(digit, duration);
obj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_DTMF, SWIG_POINTER_OWN);
return obj;
}
SWITCH_END_EXTERN_C

View File

@ -0,0 +1,9 @@
#ifndef MOD_PYTHON_EXTRA
#define MOD_PYTHON_EXTRA
SWITCH_BEGIN_EXTERN_C PyObject * mod_python_conjure_event(switch_event_t *event);
PyObject *mod_python_conjure_stream(switch_stream_handle_t *stream);
PyObject *mod_python_conjure_session(PyObject * module, switch_core_session_t *session);
PyObject *mod_python_conjure_DTMF(char digit, int32_t duration);
SWITCH_END_EXTERN_C
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
import os
from freeswitch import *
# HANGUP HOOK
#
# session is a session object
# what is "hangup" or "transfer"
# if you pass an extra arg to setInputCallback then append 'arg' to get that value
# def hangup_hook(session, what, arg):
def hangup_hook(session, what):
consoleLog("info","hangup hook for %s!!\n\n" % what)
return
# INPUT CALLBACK
#
# session is a session object
# what is "dtmf" or "event"
# obj is a dtmf object or an event object depending on the 'what' var.
# if you pass an extra arg to setInputCallback then append 'arg' to get that value
# def input_callback(session, what, obj, arg):
def input_callback(session, what, obj):
if (what == "dtmf"):
consoleLog("info", what + " " + obj.digit + "\n")
else:
consoleLog("info", what + " " + obj.serialize() + "\n")
return "pause"
# APPLICATION
#
# default name for apps is "handler" it can be overridden with <modname>::<function>
# session is a session object
# args is all the args passed after the module name
def handler(session, args):
session.answer()
session.setHangupHook(hangup_hook)
session.setInputCallback(input_callback)
session.execute("playback", session.getVariable("hold_music"))
# FSAPI CALL FROM CLI, DP HTTP etc
#
# default name for python FSAPI is "fsapi" it can be overridden with <modname>::<function>
# stream is a switch_stream, anything written with stream.write() is returned to the caller
# env is a switch_event
# args is all the args passed after the module name
# session is a session object when called from the dial plan or the string "na" when not.
def fsapi(session, stream, env, args):
stream.write("w00t!\n" + env.serialize())
# RUN A FUNCTION IN A THREAD
#
# default name for pyrun is "runtime" it can be overridden with <modname>::<function>
# args is all the args passed after the module name
def runtime(args):
print args + "\n"
# BIND TO AN XML LOOKUP
#
# default name for binding to an XML lookup is "xml_fetch" it can be overridden with <modname>::<function>
# params a switch_event with all the relevant data about what is being searched for in the XML registry.
#
def xml_fetch(params):
xml = '''
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="freeswitch/xml">
<section name="dialplan" description="RE Dial Plan For FreeSWITCH">
<context name="default">
<extension name="generated">
<condition>
<action application="answer"/>
<action application="playback" data="${hold_music}"/>
</condition>
</extension>
</context>
</section>
</document>
'''
return xml