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:
darthgandalf
2010-12-22 14:52:53 +00:00
parent c7c0d1714c
commit a564e25c13
11 changed files with 2440 additions and 96 deletions
Vendored
+216 -68
View File
@@ -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
View File
@@ -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
View File
@@ -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/
+489
View File
@@ -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")
+418
View File
@@ -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' }
}
}
+16
View File
@@ -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;
}
+332
View File
@@ -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@*/;
+66
View File
@@ -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
+176
View File
@@ -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);
}
%}
+221
View File
@@ -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;
}
};
+377
View File
@@ -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)