[mod_python3, ESL py3mod] Add Python3 support.
This commit is contained in:
parent
3a66eb415f
commit
e44fd2ea38
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ../../../..
|
||||
|
|
|
@ -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"/>
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
||||
|
|
124
configure.ac
124
configure.ac
|
@ -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
|
||||
|
|
|
@ -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}),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
/usr/lib/python*/*-packages/freeswitch.py
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
@ -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
|
@ -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()
|
|
@ -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))
|
||||
|
|
@ -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()
|
||||
|
||||
|
|
@ -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:])
|
|
@ -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.
|
|
@ -0,0 +1,2 @@
|
|||
mod_python_wrap.cpp -diff
|
||||
freeswitch.py -diff
|
|
@ -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)
|
||||
|
|
@ -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.
|
|
@ -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.
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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();
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
*/
|
|
@ -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
|
|
@ -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
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue