mirror of
https://github.com/znc/znc.git
synced 2026-08-11 03:12:50 +02:00
Add modpython module which allows to write ZNC modules on python3.
Notice for distro maintainers: perl interpreter is required to compile modpython. git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@2196 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
@@ -556,6 +556,7 @@ PACKAGE_URL=''
|
||||
ac_unique_file="znc.cpp"
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
PERL
|
||||
DATADIR
|
||||
MODDIR
|
||||
LIBICONV
|
||||
@@ -568,8 +569,9 @@ MODLINK
|
||||
LIBZNCDIR
|
||||
LIBZNC
|
||||
MODFLAGS
|
||||
SWIG_BINARY
|
||||
PYTHONCFG_BINARY
|
||||
PERL_BINARY
|
||||
SWIG_BINARY
|
||||
openssl_LIBS
|
||||
openssl_CFLAGS
|
||||
c_ares_LIBS
|
||||
@@ -643,6 +645,7 @@ enable_debug
|
||||
enable_ipv6
|
||||
enable_openssl
|
||||
enable_perl
|
||||
enable_python
|
||||
enable_swig
|
||||
enable_sasl
|
||||
enable_optimization
|
||||
@@ -1292,12 +1295,18 @@ Optional Features:
|
||||
--disable-ipv6 disable ipv6 support
|
||||
--disable-openssl disable openssl
|
||||
--enable-perl enable perl
|
||||
--enable-python[=python3-config]
|
||||
enable python. By default python3-config is used,
|
||||
but you can use another name if your python3-config
|
||||
has another name.
|
||||
--disable-swig Disable automatic generation of source files needed
|
||||
for modperl. This value is ignored if perl is
|
||||
disabled or not found. If you disable swig, but
|
||||
still want to use modperl, please download the
|
||||
necessary files to modules/modperl. Check
|
||||
http://en.znc.in/wiki/Modperl for details.
|
||||
for modperl/modpython. This value is ignored if perl
|
||||
and python are disabled. If you disable swig, but
|
||||
still want to use these modules, please download the
|
||||
necessary files to modules/modperl and/or to
|
||||
modules/modpython. Check
|
||||
http://en.znc.in/wiki/Modperl and
|
||||
http://en.znc.in/wiki/Modpython for details.
|
||||
--enable-sasl enable sasl
|
||||
--disable-optimization Disable some compiler optimizations to decrease
|
||||
memory usage while compiling
|
||||
@@ -2926,6 +2935,13 @@ else
|
||||
PERL="no"
|
||||
fi
|
||||
|
||||
# Check whether --enable-python was given.
|
||||
if test "${enable_python+set}" = set; then :
|
||||
enableval=$enable_python; PYTHON="$enableval"
|
||||
else
|
||||
PYTHON="no"
|
||||
fi
|
||||
|
||||
# Check whether --enable-swig was given.
|
||||
if test "${enable_swig+set}" = set; then :
|
||||
enableval=$enable_swig; SWIG="$enableval"
|
||||
@@ -3675,9 +3691,76 @@ else
|
||||
# (dynamic_lookup might only work on 10.4 and later)
|
||||
fi
|
||||
|
||||
if test "x$PERL" != xno -o "x$PYTHON" != xno; then
|
||||
old_SWIG="$SWIG"
|
||||
if test "x$SWIG" != "xno"; then
|
||||
# Extract the first word of "swig", so it can be a program name with args.
|
||||
set dummy swig; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if test "${ac_cv_path_SWIG_BINARY+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $SWIG_BINARY in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_SWIG_BINARY="$SWIG_BINARY" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_SWIG_BINARY="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
SWIG_BINARY=$ac_cv_path_SWIG_BINARY
|
||||
if test -n "$SWIG_BINARY"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG_BINARY" >&5
|
||||
$as_echo "$SWIG_BINARY" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
test -z "$SWIG_BINARY" && SWIG=no
|
||||
fi
|
||||
if test "x$SWIG" = xno; then
|
||||
SWIG_BINARY=""
|
||||
if test "x$old_SWIG" = xno; then
|
||||
SWIG="no, need manual download for perl/python bindings"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: swig was disabled, so you should put needed sources to modules/
|
||||
Please check http://en.znc.in/wiki/Modperl or http://en.znc.in/wiki/Modpython for details." >&5
|
||||
$as_echo "$as_me: WARNING: swig was disabled, so you should put needed sources to modules/
|
||||
Please check http://en.znc.in/wiki/Modperl or http://en.znc.in/wiki/Modpython for details." >&2;}
|
||||
else
|
||||
as_fn_error $? "swig was not found. Try --disable-perl --disable-python, or download the necessary sources and use --disable-swig.
|
||||
Please check http://en.znc.in/wiki/Modperl or http://en.znc.in/wiki/Modpython for details." "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
SWIG=yes
|
||||
fi
|
||||
else
|
||||
if test "x$SWIG" = "xyes"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: swig is needed only for perl and python, but both are disabled. Disabling swig." >&5
|
||||
$as_echo "$as_me: WARNING: swig is needed only for perl and python, but both are disabled. Disabling swig." >&2;}
|
||||
fi
|
||||
SWIG=no
|
||||
fi
|
||||
|
||||
if test "x$PERL" != "xno"; then
|
||||
old_PERL="$PERL"
|
||||
old_SWIG="$SWIG"
|
||||
# Extract the first word of "perl", so it can be a program name with args.
|
||||
set dummy perl; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
@@ -3763,53 +3846,6 @@ else
|
||||
PERL="no"
|
||||
fi
|
||||
|
||||
if test "x$PERL" != "xno"; then
|
||||
if test "x$SWIG" != "xno"; then
|
||||
# Extract the first word of "swig", so it can be a program name with args.
|
||||
set dummy swig; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if test "${ac_cv_path_SWIG_BINARY+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $SWIG_BINARY in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_SWIG_BINARY="$SWIG_BINARY" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_SWIG_BINARY="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
SWIG_BINARY=$ac_cv_path_SWIG_BINARY
|
||||
if test -n "$SWIG_BINARY"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG_BINARY" >&5
|
||||
$as_echo "$SWIG_BINARY" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$SWIG_BINARY"; then
|
||||
SWIG="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
LDFLAGS="$my_saved_LDFLAGS"
|
||||
else
|
||||
PERL="no"
|
||||
@@ -3827,22 +3863,131 @@ $as_echo "$as_me: WARNING: perl was not found and thus disabled" >&2;}
|
||||
|
||||
PERL_BINARY=""
|
||||
else
|
||||
if test "x$SWIG" = "xno"; then
|
||||
SWIG_BINARY=""
|
||||
if test "x$old_SWIG" = "xno"; then
|
||||
PERL="yes, but with manual download"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: swig was disabled, so you should put needed sources for modperl to modules/modperl.
|
||||
Please check http://en.znc.in/wiki/Modperl for details." >&5
|
||||
$as_echo "$as_me: WARNING: swig was disabled, so you should put needed sources for modperl to modules/modperl.
|
||||
Please check http://en.znc.in/wiki/Modperl for details." >&2;}
|
||||
else
|
||||
as_fn_error $? "swig was not found. Try --disable-perl, or download the necessary sources and use --disable-swig.
|
||||
Please check http://en.znc.in/wiki/Modperl for details." "$LINENO" 5
|
||||
PERL="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$PYTHON" != "xno"; then
|
||||
# Default value for just --enable-python
|
||||
if test "x$PYTHON" = "xyes"; then
|
||||
PYTHON="python3-config"
|
||||
fi
|
||||
old_PYTHON="$PYTHON"
|
||||
# Extract the first word of ""$PYTHON"", so it can be a program name with args.
|
||||
set dummy "$PYTHON"; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if test "${ac_cv_path_PYTHONCFG_BINARY+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PYTHONCFG_BINARY in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PYTHONCFG_BINARY="$PYTHONCFG_BINARY" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_PYTHONCFG_BINARY="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PYTHONCFG_BINARY=$ac_cv_path_PYTHONCFG_BINARY
|
||||
if test -n "$PYTHONCFG_BINARY"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHONCFG_BINARY" >&5
|
||||
$as_echo "$PYTHONCFG_BINARY" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -n "$PYTHONCFG_BINARY"; then
|
||||
my_saved_LDFLAGS="$LDFLAGS"
|
||||
appendLD `$PYTHONCFG_BINARY --includes`
|
||||
appendLD `$PYTHONCFG_BINARY --ldflags`
|
||||
ac_fn_cxx_check_func "$LINENO" "Py_Initialize" "ac_cv_func_Py_Initialize"
|
||||
if test "x$ac_cv_func_Py_Initialize" = x""yes; then :
|
||||
|
||||
else
|
||||
PYTHON="no"
|
||||
fi
|
||||
|
||||
if test "x$PYTHON" != "xno"; then
|
||||
# Yes, modpython depends on perl.
|
||||
# Extract the first word of "perl", so it can be a program name with args.
|
||||
set dummy perl; ac_word=$2
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
|
||||
$as_echo_n "checking for $ac_word... " >&6; }
|
||||
if test "${ac_cv_path_PERL_BINARY+set}" = set; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
case $PERL_BINARY in
|
||||
[\\/]* | ?:[\\/]*)
|
||||
ac_cv_path_PERL_BINARY="$PERL_BINARY" # Let the user override the test with a path.
|
||||
;;
|
||||
*)
|
||||
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
|
||||
for as_dir in $PATH
|
||||
do
|
||||
IFS=$as_save_IFS
|
||||
test -z "$as_dir" && as_dir=.
|
||||
for ac_exec_ext in '' $ac_executable_extensions; do
|
||||
if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
|
||||
ac_cv_path_PERL_BINARY="$as_dir/$ac_word$ac_exec_ext"
|
||||
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
IFS=$as_save_IFS
|
||||
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
PERL_BINARY=$ac_cv_path_PERL_BINARY
|
||||
if test -n "$PERL_BINARY"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL_BINARY" >&5
|
||||
$as_echo "$PERL_BINARY" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
|
||||
|
||||
if test -z "$PERL_BINARY"; then
|
||||
as_fn_error $? "To compile modpython you need to be able to execute perl scripts. Try --disable-python or install perl." "$LINENO" 5
|
||||
fi
|
||||
else
|
||||
PERL="yes"
|
||||
SWIG="yes"
|
||||
fi
|
||||
LDFLAGS="$my_saved_LDFLAGS"
|
||||
else
|
||||
PYTHON="no"
|
||||
fi
|
||||
if test "x$PYTHON" = "xno"; then
|
||||
|
||||
# This looks better in the summary at the end
|
||||
PYTHON="not found"
|
||||
if test "x$old_PYTHON" != "xauto" ; then
|
||||
as_fn_error $? "python not found. Try --disable-python." "$LINENO" 5
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: python was not found and thus disabled" >&5
|
||||
$as_echo "$as_me: WARNING: python was not found and thus disabled" >&2;}
|
||||
fi
|
||||
|
||||
PYTHONCFG_BINARY=""
|
||||
else
|
||||
PYTHON="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -4085,6 +4230,7 @@ appendCXX "-D_DATADIR_=\\\"${DATADIR}\\\""
|
||||
|
||||
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files Makefile"
|
||||
|
||||
ac_config_files="$ac_config_files znc-config"
|
||||
@@ -5273,6 +5419,8 @@ echo "ipv6: $IPV6"
|
||||
echo "openssl: $SSL"
|
||||
echo "c-ares: $ARES"
|
||||
echo "perl: $PERL"
|
||||
echo "python: $PYTHON"
|
||||
echo "swig: $SWIG"
|
||||
if test x"$SASL" = "x" ; then
|
||||
echo "sasl: no"
|
||||
else
|
||||
|
||||
+70
-25
@@ -96,11 +96,17 @@ AC_ARG_ENABLE( [perl],
|
||||
AS_HELP_STRING([--enable-perl], [enable perl]),
|
||||
[PERL="$enableval"],
|
||||
[PERL="no"])
|
||||
AC_ARG_ENABLE( [python],
|
||||
AS_HELP_STRING([--enable-python[[[=python3-config]]]], [enable python.
|
||||
By default python3-config is used, but you can use
|
||||
another name if your python3-config has another name.]),
|
||||
[PYTHON="$enableval"],
|
||||
[PYTHON="no"])
|
||||
AC_ARG_ENABLE( [swig],
|
||||
AS_HELP_STRING([--disable-swig], [Disable automatic generation of source files needed for modperl.
|
||||
This value is ignored if perl is disabled or not found. If you disable swig,
|
||||
but still want to use modperl, please download the necessary files to modules/modperl.
|
||||
Check http://en.znc.in/wiki/Modperl for details.]),
|
||||
AS_HELP_STRING([--disable-swig], [Disable automatic generation of source files needed for modperl/modpython.
|
||||
This value is ignored if perl and python are disabled. If you disable swig,
|
||||
but still want to use these modules, please download the necessary files to modules/modperl and/or to modules/modpython.
|
||||
Check http://en.znc.in/wiki/Modperl and http://en.znc.in/wiki/Modpython for details.]),
|
||||
[SWIG="$enableval"],
|
||||
[SWIG="auto"])
|
||||
AC_ARG_ENABLE( [sasl],
|
||||
@@ -270,9 +276,34 @@ else
|
||||
# (dynamic_lookup might only work on 10.4 and later)
|
||||
fi
|
||||
|
||||
if test "x$PERL" != xno -o "x$PYTHON" != xno; then
|
||||
old_SWIG="$SWIG"
|
||||
if test "x$SWIG" != "xno"; then
|
||||
AC_PATH_PROG([SWIG_BINARY], [swig])
|
||||
test -z "$SWIG_BINARY" && SWIG=no
|
||||
fi
|
||||
if test "x$SWIG" = xno; then
|
||||
SWIG_BINARY=""
|
||||
if test "x$old_SWIG" = xno; then
|
||||
SWIG="no, need manual download for perl/python bindings"
|
||||
AC_MSG_WARN([swig was disabled, so you should put needed sources to modules/
|
||||
Please check http://en.znc.in/wiki/Modperl or http://en.znc.in/wiki/Modpython for details.])
|
||||
else
|
||||
AC_MSG_ERROR([swig was not found. Try --disable-perl --disable-python, or download the necessary sources and use --disable-swig.
|
||||
Please check http://en.znc.in/wiki/Modperl or http://en.znc.in/wiki/Modpython for details.])
|
||||
fi
|
||||
else
|
||||
SWIG=yes
|
||||
fi
|
||||
else
|
||||
if test "x$SWIG" = "xyes"; then
|
||||
AC_MSG_WARN([swig is needed only for perl and python, but both are disabled. Disabling swig.])
|
||||
fi
|
||||
SWIG=no
|
||||
fi
|
||||
|
||||
if test "x$PERL" != "xno"; then
|
||||
old_PERL="$PERL"
|
||||
old_SWIG="$SWIG"
|
||||
AC_PATH_PROG([PERL_BINARY], [perl], [])
|
||||
if test -n "$PERL_BINARY" && eval "$PERL_BINARY -e'use 5.010'"; then
|
||||
my_saved_LDFLAGS="$LDFLAGS"
|
||||
@@ -280,14 +311,6 @@ if test "x$PERL" != "xno"; then
|
||||
AC_CHECK_LIB(perl, perl_alloc,
|
||||
[: No, we do not want autoconf to do sth automatically],
|
||||
PERL="no")
|
||||
if test "x$PERL" != "xno"; then
|
||||
if test "x$SWIG" != "xno"; then
|
||||
AC_PATH_PROG([SWIG_BINARY], [swig], [])
|
||||
if test -z "$SWIG_BINARY"; then
|
||||
SWIG="no"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
LDFLAGS="$my_saved_LDFLAGS"
|
||||
else
|
||||
PERL="no"
|
||||
@@ -298,20 +321,40 @@ if test "x$PERL" != "xno"; then
|
||||
[perl was not found and thus disabled])
|
||||
PERL_BINARY=""
|
||||
else
|
||||
if test "x$SWIG" = "xno"; then
|
||||
SWIG_BINARY=""
|
||||
if test "x$old_SWIG" = "xno"; then
|
||||
PERL="yes, but with manual download"
|
||||
AC_MSG_WARN([swig was disabled, so you should put needed sources for modperl to modules/modperl.
|
||||
Please check http://en.znc.in/wiki/Modperl for details.])
|
||||
else
|
||||
AC_MSG_ERROR([swig was not found. Try --disable-perl, or download the necessary sources and use --disable-swig.
|
||||
Please check http://en.znc.in/wiki/Modperl for details.])
|
||||
PERL="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "x$PYTHON" != "xno"; then
|
||||
# Default value for just --enable-python
|
||||
if test "x$PYTHON" = "xyes"; then
|
||||
PYTHON="python3-config"
|
||||
fi
|
||||
old_PYTHON="$PYTHON"
|
||||
AC_PATH_PROG([PYTHONCFG_BINARY], ["$PYTHON"])
|
||||
if test -n "$PYTHONCFG_BINARY"; then
|
||||
my_saved_LDFLAGS="$LDFLAGS"
|
||||
appendLD `$PYTHONCFG_BINARY --includes`
|
||||
appendLD `$PYTHONCFG_BINARY --ldflags`
|
||||
AC_CHECK_FUNC([Py_Initialize], [], [PYTHON="no"])
|
||||
if test "x$PYTHON" != "xno"; then
|
||||
# Yes, modpython depends on perl.
|
||||
AC_PATH_PROG([PERL_BINARY], [perl])
|
||||
if test -z "$PERL_BINARY"; then
|
||||
AC_MSG_ERROR([To compile modpython you need to be able to execute perl scripts. Try --disable-python or install perl.])
|
||||
fi
|
||||
else
|
||||
PERL="yes"
|
||||
SWIG="yes"
|
||||
fi
|
||||
LDFLAGS="$my_saved_LDFLAGS"
|
||||
else
|
||||
PYTHON="no"
|
||||
fi
|
||||
if test "x$PYTHON" = "xno"; then
|
||||
ZNC_AUTO_FAIL([PYTHON],
|
||||
[python not found. Try --disable-python.],
|
||||
[python was not found and thus disabled])
|
||||
PYTHONCFG_BINARY=""
|
||||
else
|
||||
PYTHON="yes"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -435,6 +478,8 @@ echo "ipv6: $IPV6"
|
||||
echo "openssl: $SSL"
|
||||
echo "c-ares: $ARES"
|
||||
echo "perl: $PERL"
|
||||
echo "python: $PYTHON"
|
||||
echo "swig: $SWIG"
|
||||
if test x"$SASL" = "x" ; then
|
||||
echo "sasl: no"
|
||||
else
|
||||
|
||||
+59
-3
@@ -23,6 +23,7 @@ LDFLAGS := @LDFLAGS@
|
||||
# LIBS := @LIBS@
|
||||
PERL_ON := @PERL@
|
||||
PERL := @PERL_BINARY@
|
||||
PYCFG := @PYTHONCFG_BINARY@
|
||||
SWIG := @SWIG_BINARY@
|
||||
MODDIR := @MODDIR@
|
||||
DATADIR := @DATADIR@
|
||||
@@ -81,6 +82,16 @@ else
|
||||
FILES := $(shell echo $(FILES) | sed -e "s/modperl//")
|
||||
endif
|
||||
|
||||
ifneq "$(PYCFG)" ""
|
||||
PYTHONCOMMON := $(shell $(PYCFG) --includes) $(shell $(PYCFG) --ldflags)
|
||||
PYTHONCOMMON += -DSWIG_TYPE_TABLE=znc
|
||||
PYTHONCOMMON += -Wno-missing-field-initializers -Wno-unused
|
||||
modpythonFLAGS := $(PYTHONCOMMON) -I.
|
||||
PYTHONHOOK := modpython_install
|
||||
else
|
||||
FILES := $(shell echo $(FILES) | sed -e "s/modpython//")
|
||||
endif
|
||||
|
||||
ifeq "@SASL@" ""
|
||||
FILES := $(shell echo $(FILES) | sed -e "s:extra/saslauth::")
|
||||
endif
|
||||
@@ -101,14 +112,16 @@ modtclFLAGS := $(TCL_FLAGS)
|
||||
|
||||
TARGETS := $(addsuffix .so, $(FILES))
|
||||
|
||||
CLEAN := *.so extra/*.so modperl/ZNC.so modperl/modperl_wrap.cxx modperl/ZNC.pm
|
||||
CLEAN := *.so extra/*.so
|
||||
CLEAN += modperl/ZNC.so modperl/ZNC.pm modpython/functions.cpp modpython/compiler
|
||||
CLEAN += modpython/_znc_core.so modpython/_znc_core.cpp modpython/znc_core.py modpython/znc_core.pyc
|
||||
|
||||
.PHONY: all clean install install_metadirs create_install_dir uninstall
|
||||
.PHONY: modperl_install modtcl_install
|
||||
.PHONY: modperl_install modtcl_install modpython_install modpython_compilepyc
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
install: all create_install_dir install_metadirs $(PERLHOOK) $(TCLHOOK)
|
||||
install: all create_install_dir install_metadirs $(PERLHOOK) $(TCLHOOK) $(PYTHONHOOK)
|
||||
$(INSTALL_PROGRAM) $(TARGETS) $(DESTDIR)$(MODDIR)
|
||||
|
||||
create_install_dir:
|
||||
@@ -149,6 +162,23 @@ modperl/ZNC.cpp: modperl/modperl.i Makefile modperl/module.h modperl/CString.i
|
||||
$(Q)rm -rf $@.warn
|
||||
endif
|
||||
|
||||
modpython.so: modpython/_znc_core.so modpython/swigpyrun.h
|
||||
modpython/_znc_core.so: modpython/_znc_core.cpp Makefile modpython/functions.cpp
|
||||
$(E) Building ZNC python bindings library...
|
||||
$(Q)$(CXX) $(MODFLAGS) $(LDFLAGS) $(MODLINK) -I$(srcdir) $(PYTHONCOMMON) -o $@ $< -Wno-shadow
|
||||
ifneq "$(SWIG)" ""
|
||||
modpython/swigpyrun.h:
|
||||
@mkdir -p modpython
|
||||
$(Q)$(SWIG) -python -py3 -c++ -shadow -external-runtime $@
|
||||
modpython/_znc_core.cpp: modpython/modpython.i Makefile
|
||||
$(E) Generating ZNC API for python...
|
||||
@mkdir -p modpython
|
||||
$(Q)$(SWIG) -python -py3 -c++ -shadow -outdir modpython -I$(srcdir) -w362,315,401 -o $@ $<
|
||||
endif
|
||||
modpython/functions.cpp: modpython/functions.in
|
||||
@mkdir -p modpython
|
||||
$(Q)$(PY_PERL) $(srcdir)/modpython/codegen.pl $< $@
|
||||
|
||||
modperl_install: create_install_dir install_metadirs
|
||||
+for i in $(srcdir)/*.pm; do \
|
||||
test -r $$i && $(INSTALL_DATA) $$i $(DESTDIR)$(MODDIR); \
|
||||
@@ -165,6 +195,32 @@ modperl_install: create_install_dir install_metadirs
|
||||
$(INSTALL_DATA) modperl/ZNC.pm $(DESTDIR)$(MODDIR)/modperl
|
||||
$(INSTALL_DATA) $(srcdir)/modperl/startup.pl $(DESTDIR)$(MODDIR)/modperl
|
||||
|
||||
modpython/compiler: modpython/compiler.cpp
|
||||
$(CXX) $(PYTHONCOMMON) -o $@ $<
|
||||
|
||||
modpython_compilepyc: modpython/compiler
|
||||
+cp -p $(srcdir)/*.py ./
|
||||
+cp -p $(srcdir)/*.pyc ./
|
||||
+cp -p $(srcdir)/modpython/znc*.py modpython/
|
||||
$<
|
||||
|
||||
modpython_install: create_install_dir install_metadirs modpython_compilepyc
|
||||
+for i in *.pyc; do \
|
||||
test -r $$i && $(INSTALL_DATA) $$i $(DESTDIR)$(MODDIR); \
|
||||
done
|
||||
for a in $(srcdir)/*; do \
|
||||
if [ -d $$a ]; then \
|
||||
if [ -f $${a}.py ] || [ -f $${a}.pyc ]; then \
|
||||
cp -Rp $$a $(DESTDIR)$(DATADIR); \
|
||||
fi \
|
||||
fi \
|
||||
done
|
||||
rm -rf $(DESTDIR)$(DATADIR)/modpython
|
||||
mkdir -p $(DESTDIR)$(MODDIR)/modpython
|
||||
$(INSTALL_PROGRAM) modpython/_znc_core.so $(DESTDIR)$(MODDIR)/modpython
|
||||
$(INSTALL_DATA) modpython/znc_core.pyc $(DESTDIR)$(MODDIR)/modpython
|
||||
$(INSTALL_DATA) modpython/znc.pyc $(DESTDIR)$(MODDIR)/modpython
|
||||
|
||||
modtcl_install:
|
||||
mkdir -p $(DESTDIR)$(DATADIR)/modtcl/
|
||||
$(INSTALL_DATA) $(srcdir)/extra/modtcl.tcl $(srcdir)/extra/binds.tcl $(DESTDIR)$(DATADIR)/modtcl/
|
||||
|
||||
@@ -0,0 +1,489 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2010 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "Modules.h"
|
||||
#include "User.h"
|
||||
#include "Chan.h"
|
||||
#include "Nick.h"
|
||||
#include "znc.h"
|
||||
#include "IRCSock.h"
|
||||
|
||||
#include "modpython/swigpyrun.h"
|
||||
#include "modpython/module.h"
|
||||
|
||||
class CPyRetString {
|
||||
public:
|
||||
CString& s;
|
||||
CPyRetString(CString& S) : s(S) {}
|
||||
static PyObject* wrap(CString& S) {
|
||||
CPyRetString* x = new CPyRetString(S);
|
||||
return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetString*"), SWIG_POINTER_OWN);
|
||||
}
|
||||
};
|
||||
|
||||
class CModPython: public CGlobalModule {
|
||||
|
||||
PyObject* m_PyZNCModule;
|
||||
PyObject* m_PyFormatException;
|
||||
|
||||
public:
|
||||
|
||||
CString GetPyExceptionStr() {
|
||||
PyObject* ptype;
|
||||
PyObject* pvalue;
|
||||
PyObject* ptraceback;
|
||||
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
|
||||
CString result;
|
||||
if (!pvalue) {
|
||||
Py_INCREF(Py_None);
|
||||
pvalue = Py_None;
|
||||
}
|
||||
if (!ptraceback) {
|
||||
Py_INCREF(Py_None);
|
||||
ptraceback = Py_None;
|
||||
}
|
||||
PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
|
||||
PyObject* strlist = PyObject_CallFunctionObjArgs(m_PyFormatException, ptype, pvalue, ptraceback, NULL);
|
||||
Py_CLEAR(ptype);
|
||||
Py_CLEAR(pvalue);
|
||||
Py_CLEAR(ptraceback);
|
||||
if (!strlist) {
|
||||
return "Couldn't get exact error message";
|
||||
}
|
||||
|
||||
if (PySequence_Check(strlist)) {
|
||||
PyObject* strlist_fast = PySequence_Fast(strlist, "Shouldn't happen (1)");
|
||||
PyObject** items = PySequence_Fast_ITEMS(strlist_fast);
|
||||
Py_ssize_t L = PySequence_Fast_GET_SIZE(strlist_fast);
|
||||
for (Py_ssize_t i = 0; i < L; ++i) {
|
||||
PyObject* utf8 = PyUnicode_AsUTF8String(items[i]);
|
||||
result += PyBytes_AsString(utf8);
|
||||
Py_CLEAR(utf8);
|
||||
}
|
||||
Py_CLEAR(strlist_fast);
|
||||
} else {
|
||||
result = "Can't get exact error message";
|
||||
}
|
||||
|
||||
Py_CLEAR(strlist);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
GLOBALMODCONSTRUCTOR(CModPython) {
|
||||
Py_Initialize();
|
||||
m_PyFormatException = NULL;
|
||||
m_PyZNCModule = NULL;
|
||||
}
|
||||
|
||||
bool OnLoad(const CString& sArgsi, CString& sMessage) {
|
||||
CString sModPath, sTmp;
|
||||
if (!CModules::FindModPath("modpython/_znc_core.so", sModPath, sTmp)) {
|
||||
sMessage = "modpython/_znc_core.so not found.";
|
||||
return false;
|
||||
}
|
||||
sTmp = CDir::ChangeDir(sModPath, "..");
|
||||
|
||||
PyObject* pyModuleTraceback = PyImport_ImportModule("traceback");
|
||||
if (!pyModuleTraceback) {
|
||||
sMessage = "Couldn't import python module traceback";
|
||||
return false;
|
||||
}
|
||||
m_PyFormatException = PyObject_GetAttrString(pyModuleTraceback, "format_exception");
|
||||
if (!m_PyFormatException) {
|
||||
sMessage = "Couldn't get traceback.format_exception";
|
||||
Py_CLEAR(pyModuleTraceback);
|
||||
return false;
|
||||
}
|
||||
Py_CLEAR(pyModuleTraceback);
|
||||
|
||||
PyObject* pySysModule = PyImport_ImportModule("sys");
|
||||
if (!pySysModule) {
|
||||
sMessage = GetPyExceptionStr();
|
||||
return false;
|
||||
}
|
||||
PyObject* pySysPath = PyObject_GetAttrString(pySysModule, "path");
|
||||
if (!pySysPath) {
|
||||
sMessage = GetPyExceptionStr();
|
||||
Py_CLEAR(pySysModule);
|
||||
return false;
|
||||
}
|
||||
Py_CLEAR(pySysModule);
|
||||
PyObject* pyIgnored = PyObject_CallMethod(pySysPath, const_cast<char*>("append"), const_cast<char*>("s"), sTmp.c_str());
|
||||
if (!pyIgnored) {
|
||||
sMessage = GetPyExceptionStr();
|
||||
Py_CLEAR(pyIgnored);
|
||||
return false;
|
||||
}
|
||||
Py_CLEAR(pyIgnored);
|
||||
Py_CLEAR(pySysPath);
|
||||
|
||||
m_PyZNCModule = PyImport_ImportModule("znc");
|
||||
if (!m_PyZNCModule) {
|
||||
sMessage = GetPyExceptionStr();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual EModRet OnModuleLoading(const CString& sModName, const CString& sArgs,
|
||||
bool& bSuccess, CString& sRetMsg) {
|
||||
if (!GetUser()) {
|
||||
return CONTINUE;
|
||||
}
|
||||
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "load_module");
|
||||
if (!pyFunc) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
return HALT;
|
||||
}
|
||||
PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssNNN"),
|
||||
sModName.c_str(),
|
||||
sArgs.c_str(),
|
||||
SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0),
|
||||
CPyRetString::wrap(sRetMsg),
|
||||
SWIG_NewInstanceObj(reinterpret_cast<CGlobalModule*>(this), SWIG_TypeQuery("CGlobalModule*"), 0));
|
||||
if (!pyRes) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
Py_CLEAR(pyFunc);
|
||||
return HALT;
|
||||
}
|
||||
Py_CLEAR(pyFunc);
|
||||
long int ret = PyLong_AsLong(pyRes);
|
||||
if (PyErr_Occurred()) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
Py_CLEAR(pyRes);
|
||||
return HALT;
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
// Not found
|
||||
return CONTINUE;
|
||||
case 1:
|
||||
// Error
|
||||
bSuccess = false;
|
||||
return HALT;
|
||||
case 2:
|
||||
// Success
|
||||
bSuccess = true;
|
||||
return HALT;
|
||||
}
|
||||
bSuccess = false;
|
||||
sRetMsg += " unknown value returned by modperl.load_module";
|
||||
return HALT;
|
||||
}
|
||||
|
||||
virtual EModRet OnModuleUnloading(CModule* pModule, bool& bSuccess, CString& sRetMsg) {
|
||||
CPyModule* pMod = AsPyModule(pModule);
|
||||
if (pMod) {
|
||||
CString sModName = pMod->GetModName();
|
||||
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "unload_module");
|
||||
if (!pyFunc) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
return HALT;
|
||||
}
|
||||
PyObject* pyRes = PyObject_CallFunctionObjArgs(pyFunc, pMod->GetPyObj(), NULL);
|
||||
if (!pyRes) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
Py_CLEAR(pyFunc);
|
||||
return HALT;
|
||||
}
|
||||
Py_CLEAR(pyFunc);
|
||||
Py_CLEAR(pyRes);
|
||||
bSuccess = true;
|
||||
sRetMsg = "Module [" + sModName + "] unloaded";
|
||||
return HALT;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
virtual EModRet OnGetModInfo(CModInfo& ModInfo, const CString& sModule,
|
||||
bool& bSuccess, CString& sRetMsg) {
|
||||
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "get_mod_info");
|
||||
if (!pyFunc) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
return HALT;
|
||||
}
|
||||
PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("sNN"),
|
||||
sModule.c_str(),
|
||||
CPyRetString::wrap(sRetMsg),
|
||||
SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0));
|
||||
if (!pyRes) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
Py_CLEAR(pyFunc);
|
||||
return HALT;
|
||||
}
|
||||
Py_CLEAR(pyFunc);
|
||||
long int x = PyLong_AsLong(pyRes);
|
||||
if (PyErr_Occurred()) {
|
||||
sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython: " << sRetMsg);
|
||||
bSuccess = false;
|
||||
Py_CLEAR(pyRes);
|
||||
return HALT;
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
switch (x) {
|
||||
case 0:
|
||||
return CONTINUE;
|
||||
case 1:
|
||||
bSuccess = false;
|
||||
return HALT;
|
||||
case 2:
|
||||
bSuccess = true;
|
||||
return HALT;
|
||||
}
|
||||
bSuccess = false;
|
||||
sRetMsg = CString("Shouldn't happen. ") + __PRETTY_FUNCTION__ + " on " + __FILE__ + ":" + CString(__LINE__);
|
||||
DEBUG(sRetMsg);
|
||||
return HALT;
|
||||
}
|
||||
|
||||
void TryAddModInfo(const CString& sPath, const CString& sName, set<CModInfo>& ssMods, set<CString>& ssAlready) {
|
||||
if (ssAlready.count(sName)) {
|
||||
return;
|
||||
}
|
||||
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "get_mod_info_path");
|
||||
if (!pyFunc) {
|
||||
CString sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython tried to get info about [" << sPath << "] (1) but: " << sRetMsg);
|
||||
return;
|
||||
}
|
||||
CModInfo ModInfo;
|
||||
PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssN"),
|
||||
sPath.c_str(),
|
||||
sName.c_str(),
|
||||
SWIG_NewInstanceObj(&ModInfo, SWIG_TypeQuery("CModInfo*"), 0));
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython tried to get info about [" << sPath << "] (2) but: " << sRetMsg);
|
||||
Py_CLEAR(pyFunc);
|
||||
return;
|
||||
}
|
||||
Py_CLEAR(pyFunc);
|
||||
long int x = PyLong_AsLong(pyRes);
|
||||
if (PyErr_Occurred()) {
|
||||
CString sRetMsg = GetPyExceptionStr();
|
||||
DEBUG("modpython tried to get info about [" << sPath << "] (3) but: " << sRetMsg);
|
||||
Py_CLEAR(pyRes);
|
||||
return;
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
if (x) {
|
||||
ssMods.insert(ModInfo);
|
||||
ssAlready.insert(sName);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void OnGetAvailableMods(set<CModInfo>& ssMods, bool bGlobal) {
|
||||
if (bGlobal) {
|
||||
return;
|
||||
}
|
||||
|
||||
CDir Dir;
|
||||
CModules::ModDirList dirs = CModules::GetModDirs();
|
||||
|
||||
while (!dirs.empty()) {
|
||||
set<CString> already;
|
||||
|
||||
Dir.FillByWildcard(dirs.front().first, "*.py");
|
||||
for (unsigned int a = 0; a < Dir.size(); a++) {
|
||||
CFile& File = *Dir[a];
|
||||
CString sName = File.GetShortName();
|
||||
CString sPath = File.GetLongName();
|
||||
sPath.TrimSuffix(sName);
|
||||
sName.RightChomp(3);
|
||||
TryAddModInfo(sPath, sName, ssMods, already);
|
||||
}
|
||||
|
||||
Dir.FillByWildcard(dirs.front().first, "*.pyc");
|
||||
for (unsigned int a = 0; a < Dir.size(); a++) {
|
||||
CFile& File = *Dir[a];
|
||||
CString sName = File.GetShortName();
|
||||
CString sPath = File.GetLongName();
|
||||
sPath.TrimSuffix(sName);
|
||||
sName.RightChomp(4);
|
||||
TryAddModInfo(sPath, sName, ssMods, already);
|
||||
}
|
||||
|
||||
Dir.FillByWildcard(dirs.front().first, "*.so");
|
||||
for (unsigned int a = 0; a < Dir.size(); a++) {
|
||||
CFile& File = *Dir[a];
|
||||
CString sName = File.GetShortName();
|
||||
CString sPath = File.GetLongName();
|
||||
sPath.TrimSuffix(sName);
|
||||
sName.RightChomp(3);
|
||||
TryAddModInfo(sPath, sName, ssMods, already);
|
||||
}
|
||||
|
||||
dirs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~CModPython() {
|
||||
const map<CString, CUser*>& users = CZNC::Get().GetUserMap();
|
||||
for (map<CString, CUser*>::const_iterator i = users.begin(); i != users.end(); ++i) {
|
||||
CModules& M = i->second->GetModules();
|
||||
bool cont;
|
||||
do {
|
||||
cont = false;
|
||||
for (CModules::iterator it = M.begin(); it != M.end(); ++it) {
|
||||
CModule* m = *it;
|
||||
CPyModule* mod = AsPyModule(m);
|
||||
if (mod) {
|
||||
cont = true;
|
||||
bool bSuccess = false;
|
||||
CString sRetMsg;
|
||||
OnModuleUnloading(mod, bSuccess, sRetMsg);
|
||||
if (!bSuccess) {
|
||||
DEBUG("Error unloading python module in ~CModPython: " << sRetMsg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (cont);
|
||||
}
|
||||
Py_CLEAR(m_PyFormatException);
|
||||
Py_CLEAR(m_PyZNCModule);
|
||||
Py_Finalize();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CString CPyModule::GetPyExceptionStr() {
|
||||
return m_pModPython->GetPyExceptionStr();
|
||||
}
|
||||
|
||||
#include "modpython/functions.cpp"
|
||||
|
||||
VWebSubPages& CPyModule::GetSubPages() {
|
||||
VWebSubPages* result = _GetSubPages();
|
||||
if (!result) {
|
||||
return CModule::GetSubPages();
|
||||
}
|
||||
return *result;
|
||||
}
|
||||
|
||||
void CPyTimer::RunJob() {
|
||||
CPyModule* pMod = AsPyModule(GetModule());
|
||||
if (pMod) {
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("RunJob"), const_cast<char*>(""));
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = m_pModPython->GetPyExceptionStr();
|
||||
DEBUG("python timer failed: " << sRetMsg);
|
||||
Stop();
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
}
|
||||
}
|
||||
|
||||
CPyTimer::~CPyTimer() {
|
||||
CPyModule* pMod = AsPyModule(GetModule());
|
||||
if (pMod) {
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("OnShutdown"), const_cast<char*>(""));
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = m_pModPython->GetPyExceptionStr();
|
||||
DEBUG("python timer shutdown failed: " << sRetMsg);
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
Py_CLEAR(m_pyObj);
|
||||
}
|
||||
}
|
||||
|
||||
#define CHECKCLEARSOCK(Func)\
|
||||
if (!pyRes) {\
|
||||
CString sRetMsg = m_pModPython->GetPyExceptionStr();\
|
||||
DEBUG("python socket failed in " Func ": " << sRetMsg);\
|
||||
Close();\
|
||||
}\
|
||||
Py_CLEAR(pyRes)
|
||||
|
||||
#define CBSOCK(Func) void CPySocket::Func() {\
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("On" #Func), const_cast<char*>(""));\
|
||||
CHECKCLEARSOCK(#Func);\
|
||||
}
|
||||
CBSOCK(Connected);
|
||||
CBSOCK(Disconnected);
|
||||
CBSOCK(Timeout);
|
||||
CBSOCK(ConnectionRefused);
|
||||
|
||||
void CPySocket::ReadData(const char *data, size_t len) {
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("OnReadData"), const_cast<char*>("y#"), data, (int)len);
|
||||
CHECKCLEARSOCK("OnReadData");
|
||||
}
|
||||
|
||||
void CPySocket::ReadLine(const CString& sLine) {
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("OnReadLine"), const_cast<char*>("s"), sLine.c_str());
|
||||
CHECKCLEARSOCK("OnReadLine");
|
||||
}
|
||||
|
||||
Csock* CPySocket::GetSockObj(const CString& sHost, unsigned short uPort) {
|
||||
CPySocket* result = NULL;
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("_Accepted"), const_cast<char*>("sH"), sHost.c_str(), uPort);
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = m_pModPython->GetPyExceptionStr();
|
||||
DEBUG("python socket failed in OnAccepted: " << sRetMsg);
|
||||
Close();
|
||||
}
|
||||
int res = SWIG_ConvertPtr(pyRes, (void**)&result, SWIG_TypeQuery("CPySocket*"), 0);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
DEBUG("python socket was expected to return new socket from OnAccepted, but error=" << res);
|
||||
Close();
|
||||
result = NULL;
|
||||
}
|
||||
if (!result) {
|
||||
DEBUG("modpython: OnAccepted didn't return new socket");
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
return result;
|
||||
}
|
||||
|
||||
CPySocket::~CPySocket() {
|
||||
PyObject* pyRes = PyObject_CallMethod(m_pyObj, const_cast<char*>("OnShutdown"), const_cast<char*>(""));
|
||||
if (!pyRes) {
|
||||
CString sRetMsg = m_pModPython->GetPyExceptionStr();
|
||||
DEBUG("python socket failed in OnShutdown: " << sRetMsg);
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
Py_CLEAR(m_pyObj);
|
||||
}
|
||||
|
||||
PyObject* CPySocket::WriteBytes(PyObject* data) {
|
||||
if (!PyBytes_Check(data)) {
|
||||
PyErr_SetString(PyExc_TypeError, "socket.WriteBytes needs bytes as argument");
|
||||
return NULL;
|
||||
}
|
||||
char* buffer;
|
||||
Py_ssize_t length;
|
||||
if (-1 == PyBytes_AsStringAndSize(data, &buffer, &length)) {
|
||||
return NULL;
|
||||
}
|
||||
if (Write(buffer, length)) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
GLOBALMODULEDEFS(CModPython, "Loads python scripts as ZNC modules")
|
||||
@@ -0,0 +1,418 @@
|
||||
#!/usr/bin/env perl
|
||||
#
|
||||
# Copyright (C) 2004-2010 See the AUTHORS file for details.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 as published
|
||||
# by the Free Software Foundation.
|
||||
#
|
||||
# Parts of SWIG are used here.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IO::File;
|
||||
use feature 'switch', 'say';
|
||||
|
||||
open my $in, $ARGV[0] or die;
|
||||
open my $out, ">", $ARGV[1] or die;
|
||||
|
||||
print $out <<'EOF';
|
||||
/*
|
||||
* Copyright (C) 2004-2010 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* Parts of SWIG are used here.
|
||||
*/
|
||||
|
||||
/***************************************************************************
|
||||
* This file is generated automatically using codegen.pl from functions.in *
|
||||
* Don't change it manually. *
|
||||
***************************************************************************/
|
||||
|
||||
namespace {
|
||||
/* template<class T>
|
||||
struct pyobj_to_ptr {
|
||||
CString m_sType;
|
||||
SvToPtr(const CString& sType) {
|
||||
m_sType = sType;
|
||||
}
|
||||
bool operator()(PyObject* py, T** result) {
|
||||
T* x = NULL;
|
||||
int res = SWIG_ConvertPtr(sv, (void**)&x, SWIG_TypeQuery(m_sType.c_str()), 0);
|
||||
if (SWIG_IsOK(res)) {
|
||||
*result = x;
|
||||
return true;
|
||||
}
|
||||
DEBUG("modpython: ");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
CModule::EModRet SvToEModRet(PyObject* py, CModule::EModRet* result) {
|
||||
long int x = PyLong_AsLong();
|
||||
return static_cast<CModule::EModRet>(SvUV(sv));
|
||||
}*/
|
||||
|
||||
inline swig_type_info* SWIG_pchar_descriptor(void) {
|
||||
static int init = 0;
|
||||
static swig_type_info* info = 0;
|
||||
if (!init) {
|
||||
info = SWIG_TypeQuery("_p_char");
|
||||
init = 1;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
inline int SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) {
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
if (PyUnicode_Check(obj))
|
||||
#else
|
||||
if (PyString_Check(obj))
|
||||
#endif
|
||||
{
|
||||
char *cstr; Py_ssize_t len;
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
if (!alloc && cptr) {
|
||||
/* We can't allow converting without allocation, since the internal
|
||||
representation of string in Python 3 is UCS-2/UCS-4 but we require
|
||||
a UTF-8 representation.
|
||||
TODO(bhy) More detailed explanation */
|
||||
return SWIG_RuntimeError;
|
||||
}
|
||||
obj = PyUnicode_AsUTF8String(obj);
|
||||
PyBytes_AsStringAndSize(obj, &cstr, &len);
|
||||
if(alloc) *alloc = SWIG_NEWOBJ;
|
||||
#else
|
||||
PyString_AsStringAndSize(obj, &cstr, &len);
|
||||
#endif
|
||||
if (cptr) {
|
||||
if (alloc) {
|
||||
/*
|
||||
In python the user should not be able to modify the inner
|
||||
string representation. To warranty that, if you define
|
||||
SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
|
||||
buffer is always returned.
|
||||
|
||||
The default behavior is just to return the pointer value,
|
||||
so, be careful.
|
||||
*/
|
||||
#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
|
||||
if (*alloc != SWIG_OLDOBJ)
|
||||
#else
|
||||
if (*alloc == SWIG_NEWOBJ)
|
||||
#endif
|
||||
{
|
||||
*cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1));
|
||||
*alloc = SWIG_NEWOBJ;
|
||||
}
|
||||
else {
|
||||
*cptr = cstr;
|
||||
*alloc = SWIG_OLDOBJ;
|
||||
}
|
||||
} else {
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
assert(0); /* Should never reach here in Python 3 */
|
||||
#endif
|
||||
*cptr = SWIG_Python_str_AsChar(obj);
|
||||
}
|
||||
}
|
||||
if (psize) *psize = len + 1;
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
Py_XDECREF(obj);
|
||||
#endif
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
|
||||
if (pchar_descriptor) {
|
||||
void* vptr = 0;
|
||||
if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
|
||||
if (cptr) *cptr = (char *) vptr;
|
||||
if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
|
||||
if (alloc) *alloc = SWIG_OLDOBJ;
|
||||
return SWIG_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SWIG_TypeError;
|
||||
}
|
||||
|
||||
inline int SWIG_AsPtr_std_string (PyObject * obj, CString **val) {
|
||||
char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
|
||||
if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
|
||||
if (buf) {
|
||||
if (val) *val = new CString(buf, size - 1);
|
||||
if (alloc == SWIG_NEWOBJ) free((char*)buf);
|
||||
return SWIG_NEWOBJ;
|
||||
} else {
|
||||
if (val) *val = 0;
|
||||
return SWIG_OLDOBJ;
|
||||
}
|
||||
} else {
|
||||
static int init = 0;
|
||||
static swig_type_info* descriptor = 0;
|
||||
if (!init) {
|
||||
descriptor = SWIG_TypeQuery("CString" " *");
|
||||
init = 1;
|
||||
}
|
||||
if (descriptor) {
|
||||
CString *vptr;
|
||||
int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
|
||||
if (SWIG_IsOK(res) && val) *val = vptr;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
EOF
|
||||
=b
|
||||
bool OnFoo(const CString& x) {
|
||||
PyObject* pyName = Py_BuildValue("s", "OnFoo");
|
||||
if (!pyName) {
|
||||
CString s = GetPyExceptionStr();
|
||||
DEBUG("modpython: username/module/OnFoo: can't name method to call: " << s);
|
||||
return default;
|
||||
}
|
||||
PyObject* pyArg1 = Py_BuildValue("s", x.c_str());
|
||||
if (!pyArg1) {
|
||||
CString s = GetPyExceptionStr();
|
||||
DEBUG("modpython: username/module/OnFoo: can't convert parameter x to PyObject*: " << s);
|
||||
Py_CLEAR(pyName);
|
||||
return default;
|
||||
}
|
||||
PyObject* pyArg2 = ...;
|
||||
if (!pyArg2) {
|
||||
CString s = ...;
|
||||
DEBUG(...);
|
||||
Py_CLEAR(pyName);
|
||||
Py_CLEAR(pyArg1);
|
||||
return default;
|
||||
}
|
||||
PyObject* pyArg3 = ...;
|
||||
if (!pyArg3) {
|
||||
CString s = ...;
|
||||
DEBUG(...);
|
||||
Py_CLEAR(pyName);
|
||||
Py_CLEAR(pyArg1);
|
||||
Py_CLEAR(pyArg2);
|
||||
return default;
|
||||
}
|
||||
PyObject* pyRes = PyObject_CallMethodObjArgs(m_pyObj, pyName, pyArg1, pyArg2, pyArg3, NULL);
|
||||
if (!pyRes) {
|
||||
CString s = ...;
|
||||
DEBUG("modpython: username/module/OnFoo failed: " << s);
|
||||
Py_CLEAR(pyName);
|
||||
Py_CLEAR(pyArg1);
|
||||
Py_CLEAR(pyArg2);
|
||||
Py_CLEAR(pyArg3);
|
||||
return default;
|
||||
}
|
||||
Py_CLEAR(pyName);
|
||||
Py_CLEAR(pyArg1);
|
||||
Py_CLEAR(pyArg2);
|
||||
Py_CLEAR(pyArg3);
|
||||
bool res = PyLong_AsLong(pyRes);
|
||||
if (PyErr_Occured()) {
|
||||
CString s = GetPyExceptionStr();
|
||||
DEBUG("modpython: username/module/OnFoo returned unexpected value: " << s);
|
||||
Py_CLEAR(pyRes);
|
||||
return default;
|
||||
}
|
||||
Py_CLEAR(pyRes);
|
||||
return res;
|
||||
}
|
||||
=cut
|
||||
|
||||
while (<$in>) {
|
||||
my ($type, $name, $args, $default) = /(\S+)\s+(\w+)\((.*)\)(?:=(\w+))?/ or next;
|
||||
$type =~ s/(EModRet)/CModule::$1/;
|
||||
$type =~ s/^\s*(.*?)\s*$/$1/;
|
||||
unless (defined $default) {
|
||||
given ($type) {
|
||||
when ('bool') { $default = 'true' }
|
||||
when ('CModule::EModRet') { $default = 'CONTINUE' }
|
||||
when ('CString') { $default = '""' }
|
||||
when (/\*$/) { $default = "($type)NULL" }
|
||||
}
|
||||
}
|
||||
my @arg = map {
|
||||
my ($t, $v) = /^\s*(.*\W)\s*(\w+)\s*$/;
|
||||
$t =~ s/^\s*(.*?)\s*$/$1/;
|
||||
my ($tb, $tm) = $t =~ /^(.*?)\s*?(\*|&)?$/;
|
||||
{type=>$t, var=>$v, base=>$tb, mod=>$tm//'', pyvar=>"pyArg_$v", error=>"can't convert parameter '$v' to PyObject"}
|
||||
} split /,/, $args;
|
||||
|
||||
unshift @arg, {type=>'$func$', var=>"", base=>"", mod=>"", pyvar=>"pyName", error=>"can't convert string '$name' to PyObject"};
|
||||
|
||||
my $cleanup = '';
|
||||
$default = '' if $type eq 'void';
|
||||
|
||||
say $out "$type CPyModule::$name($args) {";
|
||||
for my $a (@arg) {
|
||||
print $out "\tPyObject* $a->{pyvar} = ";
|
||||
given ($a->{type}) {
|
||||
when ('$func$') {
|
||||
say $out "Py_BuildValue(\"s\", \"$name\");";
|
||||
}
|
||||
when (/vector\s*<\s*.*\*\s*>/) {
|
||||
say $out "PyList_New(0);";
|
||||
}
|
||||
when (/CString/) {
|
||||
if ($a->{base} eq 'CString' && $a->{mod} eq '&') {
|
||||
say $out "CPyRetString::wrap($a->{var});";
|
||||
} else {
|
||||
say $out "Py_BuildValue(\"s\", $a->{var}.c_str());";
|
||||
}
|
||||
}
|
||||
when (/\*$/) {
|
||||
(my $t = $a->{type}) =~ s/^const//;
|
||||
say $out "SWIG_NewInstanceObj(const_cast<$t>($a->{var}), SWIG_TypeQuery(\"$t\"), 0);";
|
||||
}
|
||||
when (/&$/) {
|
||||
(my $b = $a->{base}) =~ s/^const//;
|
||||
say $out "SWIG_NewInstanceObj(const_cast<$b*>(&$a->{var}), SWIG_TypeQuery(\"$b*\"), 0);";
|
||||
}
|
||||
when ('bool') {
|
||||
say $out "Py_BuildValue(\"l\", (long int)$a->{var});";
|
||||
}
|
||||
default {
|
||||
my %letter = (
|
||||
'int' => 'i',
|
||||
'char' => 'b',
|
||||
'short int' => 'h',
|
||||
'long int' => 'l',
|
||||
'unsigned char' => 'B',
|
||||
'unsigned short' => 'H',
|
||||
'unsigned int' => 'I',
|
||||
'unsigned long' => 'k',
|
||||
'long long' => 'L',
|
||||
'unsigned long long' => 'K',
|
||||
'ssize_t' => 'n',
|
||||
'double' => 'd',
|
||||
'float' => 'f',
|
||||
);
|
||||
if (exists $letter{$a->{type}}) {
|
||||
say $out "Py_BuildValue(\"$letter{$a->{type}}\", $a->{var});"
|
||||
} else {
|
||||
say $out "...;";
|
||||
}
|
||||
}
|
||||
}
|
||||
say $out "\tif (!$a->{pyvar}) {";
|
||||
say $out "\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name: $a->{error}: \" << sPyErr);";
|
||||
print $out $cleanup;
|
||||
say $out "\t\treturn $default;";
|
||||
say $out "\t}";
|
||||
|
||||
$cleanup .= "\t\tPy_CLEAR($a->{pyvar});\n";
|
||||
|
||||
if ($a->{type} =~ /(vector\s*<\s*(.*)\*\s*>)/) {
|
||||
my ($vec, $sub) = ($1, $2);
|
||||
(my $cleanup1 = $cleanup) =~ s/\t\t/\t\t\t/g;
|
||||
my $dot = '.';
|
||||
$dot = '->' if $a->{mod} eq '*';
|
||||
say $out "\tfor (${vec}::const_iterator i = $a->{var}${dot}begin(); i != $a->{var}${dot}end(); ++i) {";
|
||||
say $out "\t\tPyObject* pyVecEl = SWIG_NewInstanceObj(*i, SWIG_TypeQuery(\"$sub*\"), 0);";
|
||||
say $out "\t\tif (!pyVecEl) {";
|
||||
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '.
|
||||
"\"/$name: can't convert element of vector '$a->{var}' to PyObject: \" << sPyErr);";
|
||||
print $out $cleanup1;
|
||||
say $out "\t\t\treturn $default;";
|
||||
say $out "\t\t}";
|
||||
say $out "\t\tif (PyList_Append($a->{pyvar}, pyVecEl)) {";
|
||||
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '.
|
||||
"\"/$name: can't add element of vector '$a->{var}' to PyObject: \" << sPyErr);";
|
||||
say $out "\t\t\tPy_CLEAR(pyVecEl);";
|
||||
print $out $cleanup1;
|
||||
say $out "\t\t\treturn $default;";
|
||||
say $out "\t\t}";
|
||||
say $out "\t\tPy_CLEAR(pyVecEl);";
|
||||
say $out "\t}";
|
||||
}
|
||||
}
|
||||
|
||||
print $out "\tPyObject* pyRes = PyObject_CallMethodObjArgs(m_pyObj";
|
||||
print $out ", $_->{pyvar}" for @arg;
|
||||
say $out ", NULL);";
|
||||
say $out "\tif (!pyRes) {";
|
||||
say $out "\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name failed: \" << sPyErr);";
|
||||
print $out $cleanup;
|
||||
say $out "\t\treturn $default;";
|
||||
say $out "\t}";
|
||||
|
||||
$cleanup =~ s/\t\t/\t/g;
|
||||
|
||||
print $out $cleanup;
|
||||
|
||||
if ($type ne 'void') {
|
||||
say $out "\t$type result;";
|
||||
say $out "\tif (pyRes == Py_None) {";
|
||||
say $out "\t\tresult = $default;";
|
||||
say $out "\t} else {";
|
||||
given ($type) {
|
||||
when (/^(.*)\*$/) {
|
||||
say $out "\t\tint res = SWIG_ConvertPtr(pyRes, (void**)&result, SWIG_TypeQuery(\"$type\"), 0);";
|
||||
say $out "\t\tif (!SWIG_IsOK(res)) {";
|
||||
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but error=\" << res);";
|
||||
say $out "\t\t\tresult = $default;";
|
||||
say $out "\t\t}";
|
||||
}
|
||||
when ('CString') {
|
||||
say $out "\t\tCString* p = NULL;";
|
||||
say $out "\t\tint res = SWIG_AsPtr_std_string(pyRes, &p);";
|
||||
say $out "\t\tif (!SWIG_IsOK(res)) {";
|
||||
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but error=\" << res);";
|
||||
say $out "\t\t\tresult = $default;";
|
||||
say $out "\t\t} else if (!p) {";
|
||||
say $out "\t\t\tDEBUG(\"modpython: \" << GetUser()->GetUserName() << \"/\" << GetModName() << \"/$name was expected to return '$type' but returned NULL\");";
|
||||
say $out "\t\t\tresult = $default;";
|
||||
say $out "\t\t} else result = *p;";
|
||||
say $out "\t\tif (SWIG_IsNewObj(res)) free((char*)p); // Don't ask me, that's how SWIG works...";
|
||||
}
|
||||
when ('CModule::EModRet') {
|
||||
say $out "\t\tlong int x = PyLong_AsLong(pyRes);";
|
||||
say $out "\t\tif (PyErr_Occurred()) {";
|
||||
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name was expected to return EModRet but: \" << sPyErr);";
|
||||
say $out "\t\t\tresult = $default;";
|
||||
say $out "\t\t} else { result = (CModule::EModRet)x; }";
|
||||
}
|
||||
when ('bool') {
|
||||
say $out "\t\tint x = PyObject_IsTrue(pyRes);";
|
||||
say $out "\t\tif (-1 == x) {";
|
||||
say $out "\t\t\tCString sPyErr = m_pModPython->GetPyExceptionStr();";
|
||||
say $out "\t\t\tDEBUG".'("modpython: " << GetUser()->GetUserName() << "/" << GetModName() << '."\"/$name was expected to return EModRet but: \" << sPyErr);";
|
||||
say $out "\t\t\tresult = $default;";
|
||||
say $out "\t\t} else result = x ? true : false;";
|
||||
}
|
||||
default {
|
||||
say $out "\t\tI don't know how to convert PyObject to $type :(";
|
||||
}
|
||||
}
|
||||
say $out "\t}";
|
||||
say $out "\tPy_CLEAR(pyRes);";
|
||||
say $out "\treturn result;";
|
||||
} else {
|
||||
say $out "\tPy_CLEAR(pyRes);";
|
||||
}
|
||||
say $out "}\n";
|
||||
}
|
||||
|
||||
sub getres {
|
||||
my $type = shift;
|
||||
given ($type) {
|
||||
when (/^(.*)\*$/) { return "pyobj_to_ptr<$1>(\"$type\")" }
|
||||
when ('CString') { return 'PString' }
|
||||
when ('CModule::EModRet') { return 'SvToEModRet' }
|
||||
when (/unsigned/) { return 'SvUV' }
|
||||
default { return 'SvIV' }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2010 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
int main() {
|
||||
Py_Initialize();
|
||||
int res = PyRun_SimpleString("import compileall; print('Optimizing python files for later use...'); compileall.compile_dir('.')");
|
||||
Py_Finalize();
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
SWIG-generated sources are used here.
|
||||
*/
|
||||
|
||||
//
|
||||
// String
|
||||
//
|
||||
|
||||
%{
|
||||
#include <string>
|
||||
%}
|
||||
|
||||
%feature("naturalvar") CString;
|
||||
class CString;
|
||||
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,74,%typemaps_std_string@*/
|
||||
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,4,%std_string_asptr@*/
|
||||
%fragment("SWIG_" "AsPtr" "_" {CString},"header",fragment="SWIG_AsCharPtrAndSize") {
|
||||
SWIGINTERN int
|
||||
SWIG_AsPtr_std_string (PyObject * obj, CString **val)
|
||||
{
|
||||
char* buf = 0 ; size_t size = 0; int alloc = SWIG_OLDOBJ;
|
||||
if (SWIG_IsOK((SWIG_AsCharPtrAndSize(obj, &buf, &size, &alloc)))) {
|
||||
if (buf) {
|
||||
if (val) *val = new CString(buf, size - 1);
|
||||
if (alloc == SWIG_NEWOBJ) free((char*)buf);
|
||||
return SWIG_NEWOBJ;
|
||||
} else {
|
||||
if (val) *val = 0;
|
||||
return SWIG_OLDOBJ;
|
||||
}
|
||||
} else {
|
||||
static int init = 0;
|
||||
static swig_type_info* descriptor = 0;
|
||||
if (!init) {
|
||||
descriptor = SWIG_TypeQuery("CString" " *");
|
||||
init = 1;
|
||||
}
|
||||
if (descriptor) {
|
||||
CString *vptr;
|
||||
int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
|
||||
if (SWIG_IsOK(res) && val) *val = vptr;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
/*@SWIG@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,52,%std_string_asval@*/
|
||||
%fragment("SWIG_" "AsVal" "_" {CString},"header", fragment="SWIG_" "AsPtr" "_" {CString}) {
|
||||
SWIGINTERN int
|
||||
SWIG_AsVal_std_string (PyObject * obj, CString *val)
|
||||
{
|
||||
CString* v = (CString *) 0;
|
||||
int res = SWIG_AsPtr_std_string (obj, &v);
|
||||
if (!SWIG_IsOK(res)) return res;
|
||||
if (v) {
|
||||
if (val) *val = *v;
|
||||
if (SWIG_IsNewObj(res)) {
|
||||
free((char*)v);
|
||||
res = SWIG_DelNewMask(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
/*@SWIG@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/std_strings.swg,38,%std_string_from@*/
|
||||
%fragment("SWIG_" "From" "_" {CString},"header",fragment="SWIG_FromCharPtrAndSize") {
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_From_std_string (const CString& s)
|
||||
{
|
||||
if (s.size()) {
|
||||
return SWIG_FromCharPtrAndSize(s.data(), s.size());
|
||||
} else {
|
||||
return SWIG_FromCharPtrAndSize(s.c_str(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*@SWIG@*/
|
||||
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,204,%typemaps_asptrfromn@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,193,%typemaps_asptrfrom@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,163,%typemaps_asptr@*/
|
||||
%fragment("SWIG_" "AsVal" "_" {CString},"header",fragment="SWIG_" "AsPtr" "_" {CString}) {
|
||||
SWIGINTERNINLINE int
|
||||
SWIG_AsVal_std_string (PyObject * obj, CString *val)
|
||||
{
|
||||
CString *v = (CString *)0;
|
||||
int res = SWIG_AsPtr_std_string (obj, &v);
|
||||
if (!SWIG_IsOK(res)) return res;
|
||||
if (v) {
|
||||
if (val) *val = *v;
|
||||
if (SWIG_IsNewObj(res)) {
|
||||
free((char*)v);
|
||||
res = SWIG_DelNewMask(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
return SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,31,%ptr_in_typemap@*/
|
||||
%typemap(in,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
|
||||
CString *ptr = (CString *)0;
|
||||
int res = SWIG_AsPtr_std_string($input, &ptr);
|
||||
if (!SWIG_IsOK(res) || !ptr) {
|
||||
SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
|
||||
}
|
||||
$1 = *ptr;
|
||||
if (SWIG_IsNewObj(res)) free((char*)ptr);
|
||||
}
|
||||
%typemap(freearg) CString "";
|
||||
%typemap(in,fragment="SWIG_" "AsPtr" "_" {CString}) const CString & (int res = SWIG_OLDOBJ) {
|
||||
CString *ptr = (CString *)0;
|
||||
res = SWIG_AsPtr_std_string($input, &ptr);
|
||||
if (!SWIG_IsOK(res)) { SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); }
|
||||
if (!ptr) { SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'"); }
|
||||
$1 = ptr;
|
||||
}
|
||||
%typemap(freearg,noblock=1) const CString & {
|
||||
if (SWIG_IsNewObj(res$argnum)) free((char*)$1);
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,56,%ptr_varin_typemap@*/
|
||||
%typemap(varin,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
|
||||
CString *ptr = (CString *)0;
|
||||
int res = SWIG_AsPtr_std_string($input, &ptr);
|
||||
if (!SWIG_IsOK(res) || !ptr) {
|
||||
SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in variable '""$name""' of type '""$type""'");
|
||||
}
|
||||
$1 = *ptr;
|
||||
if (SWIG_IsNewObj(res)) free((char*)ptr);
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,71,%ptr_directorout_typemap@*/
|
||||
%typemap(directorargout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString *DIRECTOROUT ($*ltype temp) {
|
||||
CString *swig_optr = 0;
|
||||
int swig_ores = $input ? SWIG_AsPtr_std_string($input, &swig_optr) : 0;
|
||||
if (!SWIG_IsOK(swig_ores) || !swig_optr) {
|
||||
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError((swig_optr ? swig_ores : SWIG_TypeError))), "in output value of type '""$type""'");
|
||||
}
|
||||
temp = *swig_optr;
|
||||
$result = &temp;
|
||||
if (SWIG_IsNewObj(swig_ores)) free((char*)swig_optr);
|
||||
}
|
||||
|
||||
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString {
|
||||
CString *swig_optr = 0;
|
||||
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
|
||||
if (!SWIG_IsOK(swig_ores) || !swig_optr) {
|
||||
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError((swig_optr ? swig_ores : SWIG_TypeError))), "in output value of type '""$type""'");
|
||||
}
|
||||
$result = *swig_optr;
|
||||
if (SWIG_IsNewObj(swig_ores)) free((char*)swig_optr);
|
||||
}
|
||||
|
||||
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString},warning= "473:Returning a pointer or reference in a director method is not recommended." ) CString* {
|
||||
CString *swig_optr = 0;
|
||||
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
|
||||
if (!SWIG_IsOK(swig_ores)) {
|
||||
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_ores)), "in output value of type '""$type""'");
|
||||
}
|
||||
$result = swig_optr;
|
||||
if (SWIG_IsNewObj(swig_ores)) {
|
||||
swig_acquire_ownership(swig_optr);
|
||||
}
|
||||
}
|
||||
%typemap(directorfree,noblock=1) CString*
|
||||
{
|
||||
if (director) {
|
||||
director->swig_release_ownership(SWIG_as_voidptr($input));
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(directorout,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString},warning= "473:Returning a pointer or reference in a director method is not recommended." ) CString& {
|
||||
CString *swig_optr = 0;
|
||||
int swig_ores = SWIG_AsPtr_std_string($input, &swig_optr);
|
||||
if (!SWIG_IsOK(swig_ores)) {
|
||||
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ArgError(swig_ores)), "in output value of type '""$type""'");
|
||||
} else {
|
||||
if (!swig_optr) {
|
||||
Swig::DirectorTypeMismatchException::raise(SWIG_ErrorType(SWIG_ValueError), "invalid null reference " "in output value of type '""$type""'");
|
||||
}
|
||||
}
|
||||
$result = swig_optr;
|
||||
if (SWIG_IsNewObj(swig_ores)) {
|
||||
swig_acquire_ownership(swig_optr);
|
||||
}
|
||||
}
|
||||
%typemap(directorfree,noblock=1) CString&
|
||||
{
|
||||
if (director) {
|
||||
director->swig_release_ownership(SWIG_as_voidptr($input));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%typemap(directorout,fragment="SWIG_" "AsPtr" "_" {CString}) CString &DIRECTOROUT = CString
|
||||
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/ptrtypes.swg,146,%ptr_typecheck_typemap@*/
|
||||
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString * {
|
||||
int res = SWIG_AsPtr_std_string($input, (CString**)(0));
|
||||
$1 = SWIG_CheckState(res);
|
||||
}
|
||||
|
||||
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString, const CString& {
|
||||
int res = SWIG_AsPtr_std_string($input, (CString**)(0));
|
||||
$1 = SWIG_CheckState(res);
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,254,%ptr_input_typemap@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,117,%_ptr_input_typemap@*/
|
||||
%typemap(in,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString *INPUT(int res = 0) {
|
||||
res = SWIG_AsPtr_std_string($input, &$1);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
|
||||
}
|
||||
res = SWIG_AddTmpMask(res);
|
||||
}
|
||||
%typemap(in,noblock=1,fragment="SWIG_" "AsPtr" "_" {CString}) CString &INPUT(int res = 0) {
|
||||
res = SWIG_AsPtr_std_string($input, &$1);
|
||||
if (!SWIG_IsOK(res)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
|
||||
}
|
||||
if (!$1) {
|
||||
SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "$symname" "', argument " "$argnum"" of type '" "$type""'");
|
||||
}
|
||||
res = SWIG_AddTmpMask(res);
|
||||
}
|
||||
%typemap(freearg,noblock=1,match="in") CString *INPUT, CString &INPUT {
|
||||
if (SWIG_IsNewObj(res$argnum)) free((char*)$1);
|
||||
}
|
||||
%typemap(typecheck,noblock=1,precedence=135,fragment="SWIG_" "AsPtr" "_" {CString}) CString *INPUT, CString &INPUT {
|
||||
int res = SWIG_AsPtr_std_string($input, (CString**)0);
|
||||
$1 = SWIG_CheckState(res);
|
||||
}
|
||||
/*@SWIG@*/
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,184,%typemaps_from@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,55,%value_out_typemap@*/
|
||||
%typemap(out,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString {
|
||||
$result = SWIG_From_std_string((CString)($1));
|
||||
}
|
||||
%typemap(out,noblock=1,fragment="SWIG_" "From" "_" {CString}) const CString& {
|
||||
$result = SWIG_From_std_string((CString)(*$1));
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,79,%value_varout_typemap@*/
|
||||
%typemap(varout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString& {
|
||||
$result = SWIG_From_std_string((CString)($1));
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,87,%value_constcode_typemap@*/
|
||||
%typemap(constcode,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString {
|
||||
SWIG_Python_SetConstant(d, "$symname",SWIG_From_std_string((CString)($value)));
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,98,%value_directorin_typemap@*/
|
||||
%typemap(directorin,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *DIRECTORIN {
|
||||
$input = SWIG_From_std_string((CString)(*$1_name));
|
||||
}
|
||||
%typemap(directorin,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString, const CString& {
|
||||
$input = SWIG_From_std_string((CString)($1_name));
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/valtypes.swg,154,%value_throws_typemap@*/
|
||||
%typemap(throws,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString {
|
||||
SWIG_Python_Raise(SWIG_From_std_string((CString)($1)), "$type", 0); SWIG_fail;
|
||||
}
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,258,%value_output_typemap@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,175,%_value_output_typemap@*/
|
||||
%typemap(in,numinputs=0,noblock=1)
|
||||
CString *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
|
||||
CString &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
|
||||
$1 = &temp;
|
||||
}
|
||||
%typemap(argout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *OUTPUT, CString &OUTPUT {
|
||||
if (SWIG_IsTmpObj(res$argnum)) {
|
||||
$result = SWIG_Python_AppendOutput($result, SWIG_From_std_string((*$1)));
|
||||
} else {
|
||||
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
|
||||
$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
|
||||
}
|
||||
}
|
||||
/*@SWIG@*/
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,258,%value_output_typemap@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,175,%_value_output_typemap@*/
|
||||
%typemap(in,numinputs=0,noblock=1)
|
||||
CString *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
|
||||
CString &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
|
||||
$1 = &temp;
|
||||
}
|
||||
%typemap(argout,noblock=1,fragment="SWIG_" "From" "_" {CString}) CString *OUTPUT, CString &OUTPUT {
|
||||
if (SWIG_IsTmpObj(res$argnum)) {
|
||||
$result = SWIG_Python_AppendOutput($result, SWIG_From_std_string((*$1)));
|
||||
} else {
|
||||
int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | 0 ) : 0 ;
|
||||
$result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
|
||||
}
|
||||
}
|
||||
/*@SWIG@*/
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,240,%_ptr_inout_typemap@*/
|
||||
/*@SWIG:/usr/share/swig1.3/typemaps/inoutlist.swg,230,%_value_inout_typemap@*/
|
||||
%typemap(in) CString *INOUT = CString *INPUT;
|
||||
%typemap(in) CString &INOUT = CString &INPUT;
|
||||
%typemap(typecheck) CString *INOUT = CString *INPUT;
|
||||
%typemap(typecheck) CString &INOUT = CString &INPUT;
|
||||
%typemap(argout) CString *INOUT = CString *OUTPUT;
|
||||
%typemap(argout) CString &INOUT = CString &OUTPUT;
|
||||
/*@SWIG@*/
|
||||
%typemap(typecheck) CString *INOUT = CString *INPUT;
|
||||
%typemap(typecheck) CString &INOUT = CString &INPUT;
|
||||
%typemap(freearg) CString *INOUT = CString *INPUT;
|
||||
%typemap(freearg) CString &INOUT = CString &INPUT;
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG@*/;
|
||||
/*@SWIG@*/;
|
||||
|
||||
/*@SWIG@*/;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
bool OnBoot()=true
|
||||
bool WebRequiresLogin()=true
|
||||
bool WebRequiresAdmin()=false
|
||||
CString GetWebMenuTitle()
|
||||
bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName)=false
|
||||
bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl)=false
|
||||
VWebSubPages* _GetSubPages()
|
||||
void OnPreRehash()
|
||||
void OnPostRehash()
|
||||
void OnIRCDisconnected()
|
||||
void OnIRCConnected()
|
||||
EModRet OnIRCConnecting(CIRCSock *pIRCSock)
|
||||
EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName)
|
||||
EModRet OnBroadcast(CString& sMessage)
|
||||
EModRet OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan)
|
||||
void OnWriteUserConfig(CFile& Config)
|
||||
void OnWriteChanConfig(CFile& Config, CChan& Chan)
|
||||
EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize)
|
||||
void OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange)
|
||||
void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
|
||||
void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
|
||||
void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
|
||||
void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange)
|
||||
void OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange)
|
||||
void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs)
|
||||
EModRet OnRaw(CString& sLine)
|
||||
EModRet OnStatusCommand(CString& sCommand)
|
||||
void OnModCommand(const CString& sCommand)
|
||||
void OnModNotice(const CString& sMessage)
|
||||
void OnModCTCP(const CString& sMessage)
|
||||
void OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans)
|
||||
void OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans)
|
||||
void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage)
|
||||
void OnJoin(const CNick& Nick, CChan& Channel)
|
||||
void OnPart(const CNick& Nick, CChan& Channel)
|
||||
EModRet OnChanBufferStarting(CChan& Chan, CClient& Client)
|
||||
EModRet OnChanBufferEnding(CChan& Chan, CClient& Client)
|
||||
EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine)
|
||||
EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine)
|
||||
void OnClientLogin()
|
||||
void OnClientDisconnect()
|
||||
EModRet OnUserRaw(CString& sLine)
|
||||
EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage)
|
||||
EModRet OnUserCTCP(CString& sTarget, CString& sMessage)
|
||||
EModRet OnUserAction(CString& sTarget, CString& sMessage)
|
||||
EModRet OnUserMsg(CString& sTarget, CString& sMessage)
|
||||
EModRet OnUserNotice(CString& sTarget, CString& sMessage)
|
||||
EModRet OnUserJoin(CString& sChannel, CString& sKey)
|
||||
EModRet OnUserPart(CString& sChannel, CString& sMessage)
|
||||
EModRet OnUserTopic(CString& sChannel, CString& sTopic)
|
||||
EModRet OnUserTopicRequest(CString& sChannel)
|
||||
EModRet OnCTCPReply(CNick& Nick, CString& sMessage)
|
||||
EModRet OnPrivCTCP(CNick& Nick, CString& sMessage)
|
||||
EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage)
|
||||
EModRet OnPrivAction(CNick& Nick, CString& sMessage)
|
||||
EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage)
|
||||
EModRet OnPrivMsg(CNick& Nick, CString& sMessage)
|
||||
EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage)
|
||||
EModRet OnPrivNotice(CNick& Nick, CString& sMessage)
|
||||
EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage)
|
||||
EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic)
|
||||
bool OnServerCapAvailable(const CString& sCap)=false
|
||||
void OnServerCapResult(const CString& sCap, bool bSuccess)
|
||||
EModRet OnTimerAutoJoin(CChan& Channel)
|
||||
bool OnEmbeddedWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl)=false
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2010 See the AUTHORS file for details.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
%module znc_core %{
|
||||
#include <utility>
|
||||
#include "../Utils.h"
|
||||
#include "../Socket.h"
|
||||
#include "../Modules.h"
|
||||
#include "../Nick.h"
|
||||
#include "../Chan.h"
|
||||
#include "../User.h"
|
||||
#include "../Client.h"
|
||||
#include "../IRCSock.h"
|
||||
#include "../Listener.h"
|
||||
#include "../HTTPSock.h"
|
||||
#include "../Template.h"
|
||||
#include "../WebModules.h"
|
||||
#include "../znc.h"
|
||||
#include "../Server.h"
|
||||
#include "../ZNCString.h"
|
||||
#include "../DCCBounce.h"
|
||||
#include "../DCCSock.h"
|
||||
#include "../FileUtils.h"
|
||||
#include "modpython/module.h"
|
||||
|
||||
class CPyRetString {
|
||||
public:
|
||||
CString& s;
|
||||
CPyRetString(CString& S) : s(S) {}
|
||||
static PyObject* wrap(CString& S) {
|
||||
CPyRetString* x = new CPyRetString(S);
|
||||
return SWIG_NewInstanceObj(x, SWIG_TypeQuery("CPyRetString*"), SWIG_POINTER_OWN);
|
||||
}
|
||||
};
|
||||
|
||||
#define stat struct stat
|
||||
using std::allocator;
|
||||
%}
|
||||
|
||||
%include <pyabc.i>
|
||||
%include <typemaps.i>
|
||||
%include <stl.i>
|
||||
%include <std_list.i>
|
||||
|
||||
namespace std {
|
||||
template<class K> class set {
|
||||
public:
|
||||
set();
|
||||
set(const set<K>&);
|
||||
};
|
||||
}
|
||||
|
||||
%include "modpython/cstring.i"
|
||||
%template(_stringlist) std::list<CString>;
|
||||
/*%typemap(out) std::list<CString> {
|
||||
std::list<CString>::const_iterator i;
|
||||
unsigned int j;
|
||||
int len = $1.size();
|
||||
SV **svs = new SV*[len];
|
||||
for (i=$1.begin(), j=0; i!=$1.end(); i++, j++) {
|
||||
svs[j] = sv_newmortal();
|
||||
SwigSvFromString(svs[j], *i);
|
||||
}
|
||||
AV *myav = av_make(len, svs);
|
||||
delete[] svs;
|
||||
$result = newRV_noinc((SV*) myav);
|
||||
sv_2mortal($result);
|
||||
argvi++;
|
||||
}*/
|
||||
|
||||
%typemap(out) CModules::ModDirList %{
|
||||
$result = PyList_New($1.size());
|
||||
if ($result) {
|
||||
for (size_t i = 0; !$1.empty(); $1.pop(), ++i) {
|
||||
PyList_SetItem($result, i, Py_BuildValue("ss", $1.front().first.c_str(), $1.front().second.c_str()));
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
%typemap(in) CString& {
|
||||
String* p;
|
||||
int res = SWIG_IsOK(SWIG_ConvertPtr($input, (void**)&p, SWIG_TypeQuery("String*"), 0));
|
||||
if (SWIG_IsOK(res)) {
|
||||
$1 = &p->s;
|
||||
} else {
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "need znc.String object as argument $argnum $1_name");
|
||||
}
|
||||
}
|
||||
|
||||
#define u_short unsigned short
|
||||
#define u_int unsigned int
|
||||
#include "../ZNCString.h"
|
||||
%include "../defines.h"
|
||||
%include "../Utils.h"
|
||||
%include "../Csocket.h"
|
||||
%template(ZNCSocketManager) TSocketManager<CZNCSock>;
|
||||
%include "../Socket.h"
|
||||
%include "../DCCBounce.h"
|
||||
%include "../DCCSock.h"
|
||||
%include "../FileUtils.h"
|
||||
%include "../Modules.h"
|
||||
%include "../Nick.h"
|
||||
%include "../Chan.h"
|
||||
%include "../User.h"
|
||||
%include "../Client.h"
|
||||
%include "../IRCSock.h"
|
||||
%include "../Listener.h"
|
||||
%include "../HTTPSock.h"
|
||||
%include "../Template.h"
|
||||
%include "../WebModules.h"
|
||||
%include "../znc.h"
|
||||
%include "../Server.h"
|
||||
|
||||
%include "modpython/module.h"
|
||||
|
||||
/* Really it's CString& inside, but SWIG shouldn't know that :) */
|
||||
class CPyRetString {
|
||||
CPyRetString();
|
||||
public:
|
||||
CString s;
|
||||
};
|
||||
|
||||
%extend CModule {
|
||||
MCString_iter BeginNV_() {
|
||||
return MCString_iter($self->BeginNV());
|
||||
}
|
||||
bool ExistsNV(const CString& sName) {
|
||||
return $self->EndNV() != $self->FindNV(sName);
|
||||
}
|
||||
}
|
||||
|
||||
%extend CModules {
|
||||
void push_back(CModule* p) {
|
||||
$self->push_back(p);
|
||||
}
|
||||
bool removeModule(CModule* p) {
|
||||
for (CModules::iterator i = $self->begin(); $self->end() != i; ++i) {
|
||||
if (*i == p) {
|
||||
$self->erase(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Web */
|
||||
|
||||
%template(StrPair) pair<CString, CString>;
|
||||
%template(VPair) vector<pair<CString, CString> >;
|
||||
typedef vector<pair<CString, CString> > VPair;
|
||||
%template(VWebSubPages) vector<TWebSubPage>;
|
||||
|
||||
%inline %{
|
||||
void VPair_Add2Str_(VPair* self, const CString& a, const CString& b) {
|
||||
self->push_back(std::make_pair(a, b));
|
||||
}
|
||||
%}
|
||||
|
||||
%extend CTemplate {
|
||||
void set(const CString& key, const CString& value) {
|
||||
(*$self)[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
%inline %{
|
||||
TWebSubPage CreateWebSubPage_(const CString& sName, const CString& sTitle, const VPair& vParams, unsigned int uFlags) {
|
||||
return new CWebSubPage(sName, sTitle, vParams, uFlags);
|
||||
}
|
||||
%}
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
#pragma once
|
||||
|
||||
class String {
|
||||
public:
|
||||
CString s;
|
||||
};
|
||||
|
||||
class CModPython;
|
||||
|
||||
class CPyModule : public CModule {
|
||||
PyObject* m_pyObj;
|
||||
CModPython* m_pModPython;
|
||||
VWebSubPages* _GetSubPages();
|
||||
public:
|
||||
CPyModule(CUser* pUser, const CString& sModName, const CString& sDataPath,
|
||||
PyObject* pyObj, CGlobalModule* pModPython)
|
||||
: CModule(NULL, pUser, sModName, sDataPath) {
|
||||
m_pyObj = pyObj;
|
||||
Py_INCREF(pyObj);
|
||||
m_pModPython = reinterpret_cast<CModPython*>(pModPython);
|
||||
}
|
||||
PyObject* GetPyObj() { // borrows
|
||||
return m_pyObj;
|
||||
}
|
||||
PyObject* GetNewPyObj() {
|
||||
Py_INCREF(m_pyObj);
|
||||
return m_pyObj;
|
||||
}
|
||||
void DeletePyModule() {
|
||||
Py_CLEAR(m_pyObj);
|
||||
delete this;
|
||||
}
|
||||
CString GetPyExceptionStr();
|
||||
CModPython* GetModPython() {
|
||||
return m_pModPython;
|
||||
}
|
||||
|
||||
virtual bool OnBoot();
|
||||
virtual bool WebRequiresLogin();
|
||||
virtual bool WebRequiresAdmin();
|
||||
virtual CString GetWebMenuTitle();
|
||||
virtual bool OnWebPreRequest(CWebSock& WebSock, const CString& sPageName);
|
||||
virtual bool OnWebRequest(CWebSock& WebSock, const CString& sPageName, CTemplate& Tmpl);
|
||||
virtual VWebSubPages& GetSubPages();
|
||||
virtual void OnPreRehash();
|
||||
virtual void OnPostRehash();
|
||||
virtual void OnIRCDisconnected();
|
||||
virtual void OnIRCConnected();
|
||||
virtual EModRet OnIRCConnecting(CIRCSock *pIRCSock);
|
||||
virtual EModRet OnIRCRegistration(CString& sPass, CString& sNick, CString& sIdent, CString& sRealName);
|
||||
virtual EModRet OnBroadcast(CString& sMessage);
|
||||
virtual EModRet OnConfigLine(const CString& sName, const CString& sValue, CUser* pUser, CChan* pChan);
|
||||
virtual void OnWriteUserConfig(CFile& Config);
|
||||
virtual void OnWriteChanConfig(CFile& Config, CChan& Chan);
|
||||
virtual EModRet OnDCCUserSend(const CNick& RemoteNick, unsigned long uLongIP, unsigned short uPort, const CString& sFile, unsigned long uFileSize);
|
||||
virtual void OnChanPermission(const CNick& OpNick, const CNick& Nick, CChan& Channel, unsigned char uMode, bool bAdded, bool bNoChange);
|
||||
virtual void OnOp(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
|
||||
virtual void OnDeop(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
|
||||
virtual void OnVoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
|
||||
virtual void OnDevoice(const CNick& OpNick, const CNick& Nick, CChan& Channel, bool bNoChange);
|
||||
virtual void OnMode(const CNick& OpNick, CChan& Channel, char uMode, const CString& sArg, bool bAdded, bool bNoChange);
|
||||
virtual void OnRawMode(const CNick& OpNick, CChan& Channel, const CString& sModes, const CString& sArgs);
|
||||
virtual EModRet OnRaw(CString& sLine);
|
||||
virtual EModRet OnStatusCommand(CString& sCommand);
|
||||
virtual void OnModCommand(const CString& sCommand);
|
||||
virtual void OnModNotice(const CString& sMessage);
|
||||
virtual void OnModCTCP(const CString& sMessage);
|
||||
virtual void OnQuit(const CNick& Nick, const CString& sMessage, const vector<CChan*>& vChans);
|
||||
virtual void OnNick(const CNick& Nick, const CString& sNewNick, const vector<CChan*>& vChans);
|
||||
virtual void OnKick(const CNick& OpNick, const CString& sKickedNick, CChan& Channel, const CString& sMessage);
|
||||
virtual void OnJoin(const CNick& Nick, CChan& Channel);
|
||||
virtual void OnPart(const CNick& Nick, CChan& Channel);
|
||||
virtual EModRet OnChanBufferStarting(CChan& Chan, CClient& Client);
|
||||
virtual EModRet OnChanBufferEnding(CChan& Chan, CClient& Client);
|
||||
virtual EModRet OnChanBufferPlayLine(CChan& Chan, CClient& Client, CString& sLine);
|
||||
virtual EModRet OnPrivBufferPlayLine(CClient& Client, CString& sLine);
|
||||
virtual void OnClientLogin();
|
||||
virtual void OnClientDisconnect();
|
||||
virtual EModRet OnUserRaw(CString& sLine);
|
||||
virtual EModRet OnUserCTCPReply(CString& sTarget, CString& sMessage);
|
||||
virtual EModRet OnUserCTCP(CString& sTarget, CString& sMessage);
|
||||
virtual EModRet OnUserAction(CString& sTarget, CString& sMessage);
|
||||
virtual EModRet OnUserMsg(CString& sTarget, CString& sMessage);
|
||||
virtual EModRet OnUserNotice(CString& sTarget, CString& sMessage);
|
||||
virtual EModRet OnUserJoin(CString& sChannel, CString& sKey);
|
||||
virtual EModRet OnUserPart(CString& sChannel, CString& sMessage);
|
||||
virtual EModRet OnUserTopic(CString& sChannel, CString& sTopic);
|
||||
virtual EModRet OnUserTopicRequest(CString& sChannel);
|
||||
virtual EModRet OnCTCPReply(CNick& Nick, CString& sMessage);
|
||||
virtual EModRet OnPrivCTCP(CNick& Nick, CString& sMessage);
|
||||
virtual EModRet OnChanCTCP(CNick& Nick, CChan& Channel, CString& sMessage);
|
||||
virtual EModRet OnPrivAction(CNick& Nick, CString& sMessage);
|
||||
virtual EModRet OnChanAction(CNick& Nick, CChan& Channel, CString& sMessage);
|
||||
virtual EModRet OnPrivMsg(CNick& Nick, CString& sMessage);
|
||||
virtual EModRet OnChanMsg(CNick& Nick, CChan& Channel, CString& sMessage);
|
||||
virtual EModRet OnPrivNotice(CNick& Nick, CString& sMessage);
|
||||
virtual EModRet OnChanNotice(CNick& Nick, CChan& Channel, CString& sMessage);
|
||||
virtual EModRet OnTopic(CNick& Nick, CChan& Channel, CString& sTopic);
|
||||
virtual bool OnServerCapAvailable(const CString& sCap);
|
||||
virtual void OnServerCapResult(const CString& sCap, bool bSuccess);
|
||||
virtual EModRet OnTimerAutoJoin(CChan& Channel);
|
||||
bool OnEmbeddedWebRequest(CWebSock&, const CString&, CTemplate&);
|
||||
};
|
||||
|
||||
static inline CPyModule* AsPyModule(CModule* p) {
|
||||
return dynamic_cast<CPyModule*>(p);
|
||||
}
|
||||
|
||||
inline CPyModule* CreatePyModule(CUser* pUser, const CString& sModName, const CString& sDataPath, PyObject* pyObj, CGlobalModule* pModPython) {
|
||||
return new CPyModule(pUser, sModName, sDataPath, pyObj, pModPython);
|
||||
}
|
||||
|
||||
class CPyTimer : public CTimer {
|
||||
PyObject* m_pyObj;
|
||||
CModPython* m_pModPython;
|
||||
public:
|
||||
CPyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription, PyObject* pyObj)
|
||||
: CTimer (pModule, uInterval, uCycles, sLabel, sDescription), m_pyObj(pyObj) {
|
||||
Py_INCREF(pyObj);
|
||||
pModule->AddTimer(this);
|
||||
m_pModPython = pModule->GetModPython();
|
||||
}
|
||||
virtual void RunJob();
|
||||
PyObject* GetPyObj() { return m_pyObj; }
|
||||
PyObject* GetNewPyObj() {
|
||||
Py_INCREF(m_pyObj);
|
||||
return m_pyObj;
|
||||
}
|
||||
~CPyTimer();
|
||||
};
|
||||
|
||||
inline CPyTimer* CreatePyTimer(CPyModule* pModule, unsigned int uInterval, unsigned int uCycles,
|
||||
const CString& sLabel, const CString& sDescription, PyObject* pyObj) {
|
||||
return new CPyTimer(pModule, uInterval, uCycles, sLabel, sDescription, pyObj);
|
||||
}
|
||||
|
||||
class CPySocket : public CSocket {
|
||||
PyObject* m_pyObj;
|
||||
CModPython* m_pModPython;
|
||||
public:
|
||||
CPySocket(CPyModule* pModule, PyObject* pyObj) : CSocket(pModule), m_pyObj(pyObj) {
|
||||
Py_INCREF(pyObj);
|
||||
m_pModPython = pModule->GetModPython();
|
||||
}
|
||||
PyObject* GetPyObj() { return m_pyObj; }
|
||||
PyObject* GetNewPyObj() {
|
||||
Py_INCREF(m_pyObj);
|
||||
return m_pyObj;
|
||||
}
|
||||
~CPySocket();
|
||||
virtual void Connected();
|
||||
virtual void Disconnected();
|
||||
virtual void Timeout();
|
||||
virtual void ConnectionRefused();
|
||||
virtual void ReadData(const char *data, size_t len);
|
||||
virtual void ReadLine(const CString& sLine);
|
||||
virtual Csock* GetSockObj(const CString& sHost, unsigned short uPort);
|
||||
PyObject* WriteBytes(PyObject* data);
|
||||
};
|
||||
|
||||
inline CPySocket* CreatePySocket(CPyModule* pModule, PyObject* pyObj) {
|
||||
return new CPySocket(pModule, pyObj);
|
||||
}
|
||||
|
||||
inline bool HaveIPv6_() {
|
||||
#ifdef HAVE_IPV6
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool HaveSSL_() {
|
||||
#ifdef HAVE_LIBSSL
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool HaveCAres_() {
|
||||
#ifdef HAVE_C_ARES
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
inline int GetSOMAXCONN() {
|
||||
return SOMAXCONN;
|
||||
}
|
||||
|
||||
inline int GetVersionMajor() {
|
||||
return VERSION_MAJOR;
|
||||
}
|
||||
|
||||
inline int GetVersionMinor() {
|
||||
return VERSION_MINOR;
|
||||
}
|
||||
|
||||
inline double GetVersion() {
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
inline CString GetVersionExtra() {
|
||||
return VERSION_EXTRA;
|
||||
}
|
||||
|
||||
class MCString_iter {
|
||||
public:
|
||||
MCString_iter() {}
|
||||
MCString::iterator x;
|
||||
MCString_iter(MCString::iterator z) : x(z) {}
|
||||
void plusplus() {
|
||||
++x;
|
||||
}
|
||||
CString get() {
|
||||
return x->first;
|
||||
}
|
||||
bool is_end(CModule* m) {
|
||||
return m->EndNV() == x;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
from znc_core import *
|
||||
import imp
|
||||
import re
|
||||
import traceback
|
||||
import collections
|
||||
|
||||
class Socket:
|
||||
def _Accepted(self, host, port):
|
||||
psock = self.OnAccepted(host, port)
|
||||
print(psock)
|
||||
try:
|
||||
return psock._csock
|
||||
except AttributeError:
|
||||
return None
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._csock.GetModule()).GetNewPyObj()
|
||||
def Listen(self, addrtype='all', port=None, bindhost='', ssl=False, maxconns=GetSOMAXCONN(), timeout=0):
|
||||
addr = ADDR_ALL
|
||||
addrtype = addrtype.lower()
|
||||
if addrtype == 'ipv4':
|
||||
addr = ADDR_IPV4ONLY
|
||||
elif addrtype == 'ipv6':
|
||||
addr = ADDR_IPV6ONLY
|
||||
elif addrtype != 'all':
|
||||
raise ValueError("Specified addrtype [{0}] isn't supported".format(addrtype))
|
||||
if port is None:
|
||||
return self.GetModule().GetManager().ListenRand(
|
||||
"python socket for {0}".format(self.GetModule().GetModName()),
|
||||
bindhost,
|
||||
ssl,
|
||||
maxconns,
|
||||
self._csock,
|
||||
timeout,
|
||||
addr
|
||||
)
|
||||
if self.GetModule().GetManager().ListenHost(
|
||||
port,
|
||||
'python socket for {0}'.format(self.GetModule().GetModName()),
|
||||
bindhost,
|
||||
ssl,
|
||||
maxconns,
|
||||
self._csock,
|
||||
timeout,
|
||||
addr):
|
||||
return port
|
||||
return 0
|
||||
def Connect(self, host, port, timeout=60, ssl=False, bindhost=''):
|
||||
return self.GetModule().GetManager().Connect(
|
||||
host,
|
||||
port,
|
||||
'python conn socket for {0}'.format(self.GetModule().GetModName()),
|
||||
timeout,
|
||||
ssl,
|
||||
bindhost,
|
||||
self._csock)
|
||||
def Write(self, data):
|
||||
if (isinstance(data, str)):
|
||||
return self._csock.Write(data)
|
||||
raise TypeError('socket.Write needs str. If you want binary data, use WriteBytes')
|
||||
|
||||
def Init(self, *a, **b): pass
|
||||
def OnConnected(self): pass
|
||||
def OnDisconnected(self): pass
|
||||
def OnTimeout(self): pass
|
||||
def OnConnectionRefused(self): pass
|
||||
def OnReadData(self, bytess): pass
|
||||
def OnReadLine(self, line): pass
|
||||
def OnAccepted(self, host, port): pass
|
||||
def OnShutdown(self): pass
|
||||
|
||||
class Timer:
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._ctimer.GetModule()).GetNewPyObj()
|
||||
def RunJob(self): pass
|
||||
def OnShutdown(self): pass
|
||||
|
||||
class ModuleNVIter(collections.Iterator):
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
self.it = cmod.BeginNV_()
|
||||
def __next__(self):
|
||||
if self.it.is_end(self._cmod):
|
||||
raise StopIteration
|
||||
res = self.it.get()
|
||||
self.it.plusplus()
|
||||
return res
|
||||
|
||||
class ModuleNV(collections.MutableMapping):
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
def __setitem__(self, key, value):
|
||||
self._cmod.SetNV(key, value)
|
||||
def __getitem__(self, key):
|
||||
if not self._cmod.ExistsNV(key):
|
||||
raise KeyError
|
||||
return self._cmod.GetNV(key)
|
||||
def __contains__(self, key):
|
||||
return self._cmod.ExistsNV(key)
|
||||
def __delitem__(self, key):
|
||||
self._cmod.DelNV(key)
|
||||
def keys(self):
|
||||
return ModuleNVIter(self._cmod)
|
||||
__iter__ = keys
|
||||
def __len__(self):
|
||||
raise NotImplemented
|
||||
|
||||
class Module:
|
||||
def OnLoad(self, sArgs, sMessage):
|
||||
return True
|
||||
def _GetSubPages(self):
|
||||
return self.GetSubPages()
|
||||
def CreateSocket(self, socketclass, *the, **rest):
|
||||
socket = socketclass()
|
||||
socket._csock = CreatePySocket(self._cmod, socket)
|
||||
socket.Init(*the, **rest)
|
||||
return socket
|
||||
def CreateTimer(self, timer, interval=10, cycles=1, label='pytimer', description='Some python timer'):
|
||||
t = timer()
|
||||
t._ctimer = CreatePyTimer(self._cmod, interval, cycles, label, description, t)
|
||||
return t
|
||||
def GetNV(self):
|
||||
return self._nv
|
||||
def GetSubPages(self): pass
|
||||
def OnShutdown(self): pass
|
||||
def OnBoot(self): pass
|
||||
def WebRequiresLogin(self): pass
|
||||
def WebRequiresAdmin(self): pass
|
||||
def GetWebMenuTitle(self): pass
|
||||
def OnWebPreRequest(self, WebSock, sPageName): pass
|
||||
def OnWebRequest(self, WebSock, sPageName, Tmpl): pass
|
||||
def OnPreRehash(self): pass
|
||||
def OnPostRehash(self): pass
|
||||
def OnIRCDisconnected(self): pass
|
||||
def OnIRCConnected(self): pass
|
||||
def OnIRCConnecting(self, IRCSock): pass
|
||||
def OnIRCRegistration(self, sPass, sNick, sIdent, sRealName): pass
|
||||
def OnBroadcast(self, sMessage): pass
|
||||
def OnConfigLine(self, sName, sValue, pUser, pChan): pass
|
||||
def OnWriteUserConfig(self, Config): pass
|
||||
def OnWriteChanConfig(self, Config, Chan): pass
|
||||
def OnDCCUserSend(self, RemoteNick, uLongIP, uPort, sFile, uFileSize): pass
|
||||
def OnChanPermission(self, OpNick, Nick, Channel, uMode, bAdded, bNoChange): pass
|
||||
def OnOp(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnDeop(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnVoice(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnDevoice(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnMode(self, OpNick, Channel, uMode, sArg, bAdded, bNoChange): pass
|
||||
def OnRawMode(self, OpNick, Channel, sModes, sArgs): pass
|
||||
def OnRaw(self, sLine): pass
|
||||
def OnStatusCommand(self, sCommand): pass
|
||||
def OnModCommand(self, sCommand): pass
|
||||
def OnModNotice(self, sMessage): pass
|
||||
def OnModCTCP(self, sMessage): pass
|
||||
def OnQuit(self, Nick, sMessage, vChans): pass
|
||||
def OnNick(self, Nick, sNewNick, vChans): pass
|
||||
def OnKick(self, OpNick, sKickedNick, Channel, sMessage): pass
|
||||
def OnJoin(self, Nick, Channel): pass
|
||||
def OnPart(self, Nick, Channel): pass
|
||||
def OnChanBufferStarting(self, Chan, Client): pass
|
||||
def OnChanBufferEnding(self, Chan, Client): pass
|
||||
def OnChanBufferPlayLine(self, Chan, Client, sLine): pass
|
||||
def OnPrivBufferPlayLine(self, Client, sLine): pass
|
||||
def OnClientLogin(self): pass
|
||||
def OnClientDisconnect(self): pass
|
||||
def OnUserRaw(self, sLine): pass
|
||||
def OnUserCTCPReply(self, sTarget, sMessage): pass
|
||||
def OnUserCTCP(self, sTarget, sMessage): pass
|
||||
def OnUserAction(self, sTarget, sMessage): pass
|
||||
def OnUserMsg(self, sTarget, sMessage): pass
|
||||
def OnUserNotice(self, sTarget, sMessage): pass
|
||||
def OnUserJoin(self, sChannel, sKey): pass
|
||||
def OnUserPart(self, sChannel, sMessage): pass
|
||||
def OnUserTopic(self, sChannel, sTopic): pass
|
||||
def OnUserTopicRequest(self, sChannel): pass
|
||||
def OnCTCPReply(self, Nick, sMessage): pass
|
||||
def OnPrivCTCP(self, Nick, sMessage): pass
|
||||
def OnChanCTCP(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivAction(self, Nick, sMessage): pass
|
||||
def OnChanAction(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivMsg(self, Nick, sMessage): pass
|
||||
def OnChanMsg(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivNotice(self, Nick, sMessage): pass
|
||||
def OnChanNotice(self, Nick, Channel, sMessage): pass
|
||||
def OnTopic(self, Nick, Channel, sTopic): pass
|
||||
def OnServerCapAvailable(self, sCap): pass
|
||||
def OnServerCapResult(self, sCap, bSuccess): pass
|
||||
def OnTimerAutoJoin(self, Channel): pass
|
||||
def OnEmbeddedWebRequest(self, WebSock, sPageName, Tmpl): pass
|
||||
|
||||
def make_inherit(cl, parent, attr):
|
||||
def make_caller(parent, name, attr):
|
||||
return lambda self, *a: parent.__dict__[name](self.__dict__[attr], *a)
|
||||
while True:
|
||||
for x in parent.__dict__:
|
||||
if x[:1] != '_' and x not in cl.__dict__:
|
||||
setattr(cl, x, make_caller(parent, x, attr))
|
||||
if '_s' in parent.__dict__:
|
||||
parent = parent._s
|
||||
else:
|
||||
break
|
||||
make_inherit(Socket, CPySocket, '_csock')
|
||||
make_inherit(Module, CPyModule, '_cmod')
|
||||
make_inherit(Timer, CPyTimer, '_ctimer')
|
||||
|
||||
def find_open(modname):
|
||||
'''Returns (pymodule, datapath)'''
|
||||
for d in CModules.GetModDirs():
|
||||
# d == (libdir, datadir)
|
||||
try:
|
||||
x = imp.find_module(modname, [d[0]])
|
||||
except ImportError:
|
||||
# no such file in dir d
|
||||
continue
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
# the same
|
||||
continue
|
||||
if x[2][0] == '.so':
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
# found needed .so but can't load it...
|
||||
# maybe it's normal (non-python) znc module?
|
||||
# another option here could be to "continue"
|
||||
# search of python module in other moddirs.
|
||||
# but... we respect C++ modules ;)
|
||||
return (None, None)
|
||||
finally:
|
||||
x[0].close()
|
||||
else:
|
||||
# this is not .so, so it can be only python module .py or .pyc
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
finally:
|
||||
x[0].close()
|
||||
return (pymodule, d[1])
|
||||
else:
|
||||
# nothing found
|
||||
return (None, None)
|
||||
|
||||
def load_module(modname, args, user, retmsg, modpython):
|
||||
'''Returns 0 if not found, 1 on loading error, 2 on success'''
|
||||
if re.search(r'[^a-zA-Z0-9_]', modname) is not None:
|
||||
retmsg.s = 'Module names can only contain letters, numbers and underscores, [{0}] is invalid.'.format(modname)
|
||||
return 1
|
||||
pymodule, datapath = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
module = cl()
|
||||
module._cmod = CreatePyModule(user, modname, datapath, module, modpython)
|
||||
module._nv = ModuleNV(module._cmod)
|
||||
descr = None
|
||||
if '__doc__' in cl.__dict__:
|
||||
descr = cl.__doc__
|
||||
if descr is None:
|
||||
descr = '< Placeholder for a description >'
|
||||
module.SetDescription(descr)
|
||||
module.SetArgs(args)
|
||||
module.SetModPath(pymodule.__file__)
|
||||
user.GetModules().push_back(module._cmod)
|
||||
try:
|
||||
loaded = True
|
||||
if not module.OnLoad(args, retmsg):
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Module [{0}] aborted.'.format(modname)
|
||||
else:
|
||||
retmsg.s = 'Module [{0}] aborted: {1}'.format(modname, retmsg.s)
|
||||
loaded = False
|
||||
except BaseException:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception: {0}'.format(traceback.format_exc())
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception: {1}'.format(retmsg.s, traceback.format_exc())
|
||||
loaded = False
|
||||
except:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception.'
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception.'.format(retmsg.s)
|
||||
loaded = False
|
||||
|
||||
if loaded:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = "Loaded module [{0}] [{1}]".format(modname, pymodule.__file__)
|
||||
else:
|
||||
retmsg.s = "Loaded module [{0}] [{2}] [{1}]".format(modname, pymodule.__file__, retmsg.s)
|
||||
return 2
|
||||
print(retmsg.s)
|
||||
|
||||
unload_module(module)
|
||||
return 1
|
||||
|
||||
def unload_module(module):
|
||||
module.OnShutdown()
|
||||
cmod = module._cmod
|
||||
del module._cmod
|
||||
cmod.GetUser().GetModules().removeModule(cmod)
|
||||
cmod.DeletePyModule()
|
||||
del cmod
|
||||
|
||||
def get_mod_info(modname, retmsg, modinfo):
|
||||
'''0-not found, 1-error, 2-success'''
|
||||
pymodule, = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
descr = None
|
||||
if '__doc__' in cl.__dict__:
|
||||
descr = cl.__doc__
|
||||
if descr is None:
|
||||
descr = '< Placeholder for a description >'
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(descr)
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 2
|
||||
|
||||
def get_mod_info_path(path, modname, modinfo):
|
||||
try:
|
||||
x = imp.find_module(modname, [path])
|
||||
except ImportError:
|
||||
return 0
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
return 0
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
return 0
|
||||
finally:
|
||||
x[0].close()
|
||||
if modname not in pymodule.__dict__:
|
||||
return 0
|
||||
cl = pymodule.__dict__[modname]
|
||||
descr = None
|
||||
if '__doc__' in cl.__dict__:
|
||||
descr = cl.__doc__
|
||||
if descr is None:
|
||||
descr = '< Placeholder for a description >'
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(descr)
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 1
|
||||
|
||||
CONTINUE = CModule.CONTINUE
|
||||
HALT = CModule.HALT
|
||||
HALTMODS = CModule.HALTMODS
|
||||
HALTCORE = CModule.HALTCORE
|
||||
UNLOAD = CModule.UNLOAD
|
||||
|
||||
HaveSSL = HaveSSL_()
|
||||
HaveCAres = HaveCAres_()
|
||||
HaveIPv6 = HaveIPv6_()
|
||||
Version = GetVersion()
|
||||
VersionMajor = GetVersionMajor()
|
||||
VersionMinor = GetVersionMinor()
|
||||
VersionExtra = GetVersionExtra()
|
||||
|
||||
def CreateWebSubPage(name, title='', params=dict(), admin=False):
|
||||
vpair = VPair()
|
||||
for k, v in params.items():
|
||||
VPair_Add2Str_(vpair, k, v)
|
||||
flags = 0
|
||||
if admin:
|
||||
flags |= CWebSubPage.F_ADMIN
|
||||
return CreateWebSubPage_(name, title, vpair, flags)
|
||||
|
||||
Reference in New Issue
Block a user