Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python intpreter to Eggdrop #1515

Merged
merged 77 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
abc369b
first commit
vanosg Feb 13, 2021
039cc46
Makefile for now
vanosg Feb 13, 2021
adfc903
Merge remote-tracking branch 'origin/develop' into feature/python
vanosg Feb 18, 2021
5884daa
more
vanosg Feb 18, 2021
abe4eed
moar
vanosg Feb 20, 2021
eca2239
file structure start
vanosg Feb 22, 2021
551050c
Python exports from C, new .pyexpr command
thommey Feb 23, 2021
5f5b6cf
Added flagmatching in Python
thommey Mar 14, 2021
cf18d3a
Only clean up python interpreter on module unload
thommey Mar 20, 2021
1eec526
starting to add exceptions, cmds
vanosg Apr 10, 2021
2ac6000
oh yeah this file too
vanosg Apr 10, 2021
88e3ca6
New update
thommey Jul 19, 2022
f367449
Merge branch 'develop' into feature/python
vanosg Jul 19, 2022
3e2d142
bind match for pubm, only matches text, not channel
thommey Jul 19, 2022
85fc338
Merge branch 'feature/python' of github.com:eggheads/eggdrop into fea…
vanosg Jul 20, 2022
2fb2dd8
update bind logic
vanosg Jul 20, 2022
e47d987
convert binds to list
vanosg Jul 20, 2022
e8a75c5
Better loading of eggdroppy at run
vanosg Jul 21, 2022
e812953
start to add pub, and...
vanosg Jul 29, 2022
de41356
testscript update
vanosg Jul 29, 2022
25dd905
remove old file
vanosg Jul 29, 2022
266b7bb
added join, changed bind class
vanosg Jul 31, 2022
63d5ed9
fix random leftovers
vanosg Jul 31, 2022
5aefb4d
new bind syntax, etc.
thommey Jul 31, 2022
04ed6bb
fix allbinds access
thommey Jul 31, 2022
9d91a55
fix stuff
thommey Jul 31, 2022
943992b
Documentation samples
vanosg Aug 1, 2022
3bad039
Merge branch 'feature/python' of github.com:eggheads/eggdrop into fea…
vanosg Aug 1, 2022
9d50a8a
Add ircsend, putmsg, puthelp, putserv, etc.
thommey Aug 1, 2022
3744bf5
Add missing file
thommey Aug 2, 2022
c2229db
start pybinds
vanosg Aug 4, 2022
ababec2
Add delete command for binds
vanosg Aug 5, 2022
9fdf80a
Python build update
thommey Aug 6, 2022
485ea7f
Run autotools
thommey Aug 6, 2022
93f8061
Actual binds through C/Tcl API, Tcl calling C calling Python
thommey Aug 7, 2022
6b92bd1
Use eggdrop internal binds and kwargs calling only
thommey Aug 8, 2022
4a4bdc1
Only one place defines bind types now
thommey Aug 8, 2022
69aed30
fix flags type in bind list
thommey Aug 8, 2022
3d3c0cf
Add ircuser dataclass to bind callbacks if applicable
thommey Aug 8, 2022
189287c
add all bind types
vanosg Aug 9, 2022
126a992
New .pyfile command to run a python file
thommey Oct 17, 2023
537240f
RunFile require last argument to close file
thommey Oct 17, 2023
c481c01
Fix Py_RunFile arguments
thommey Oct 17, 2023
9628074
Fix python example, add Tcl calling layer
thommey Oct 24, 2023
5f304c4
Remove unused vars
vanosg Oct 24, 2023
2145546
Change CFLAGS order so CFLAGS=-O0 can override Python defaults
thommey Nov 1, 2023
1d5d68e
Tcl dict/list conversions, move to eggdrop.tcl module
thommey Nov 1, 2023
2b6c0ec
start documentation
vanosg Nov 3, 2023
9f6a3a1
Add tclpython to Makefile.in
vanosg Nov 12, 2023
303e254
Finish Tcl pysource, update example.py
vanosg Nov 13, 2023
2732fcf
Move commands to pycmd
vanosg Nov 13, 2023
b1b1eb2
Finish initial outline format for doc
vanosg Nov 13, 2023
5dcdd67
Add python and tcl types to bind Tcl command
vanosg Nov 14, 2023
75408b2
Create example scripts
vanosg Nov 29, 2023
2898516
Add parse_tcl_list/dict to docs
vanosg Nov 29, 2023
ce82638
Move parse_tcl_list/dict to base eggdrop module, update docs
vanosg Nov 30, 2023
83c29e7
rename example dir, rm old example.py
vanosg Dec 1, 2023
7a4e573
Merge branch 'develop' into feature/python
vanosg Dec 1, 2023
d3b019f
Fix bad deconflict merge
vanosg Dec 1, 2023
ad1b30e
adjust .python interpreter
vanosg Dec 5, 2023
d38f092
Python: Expressions results to last .python idx
thommey Dec 10, 2023
00327a4
Tcl API improvements from Python
thommey Dec 10, 2023
c5210db
Fix None handling
thommey Dec 10, 2023
1dcb147
Fix bad Makefile.in merge
vanosg Dec 10, 2023
9de66e0
Merge branch 'develop' into feature/python
vanosg Dec 10, 2023
2fc428b
remove unused variable
vanosg Dec 11, 2023
9477c41
convert displayhook to PyObj
vanosg Dec 11, 2023
1c22fe3
Add traceback reporting
vanosg Dec 11, 2023
c5499d2
Add backtrace for pysource
vanosg Dec 12, 2023
a8f2c9c
Update config API; check minimum python
vanosg Dec 20, 2023
7b270e9
cleanup traceback reporting
vanosg Dec 20, 2023
e6e8db5
initialize res2
vanosg Dec 20, 2023
af7362f
remove DecodeLocale
vanosg Jan 2, 2024
0a22d0d
Update
thommey Jan 14, 2024
ecd5e7e
Do not overwrite existing scripts on make install
thommey Jan 14, 2024
e91cb55
Fix warning
thommey Jan 14, 2024
2b571ed
Remove obsolete scripts
thommey Jan 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ config.cache
eggdrop
EGGMOD.stamp
mod.xlibs
__pycache__
3 changes: 2 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,7 @@ install-doc: install-start
cd doc/ && $(MAKE_INSTALL) install

install-scripts: install-start
+@cd scripts/ && $(MAKE_INSTALL) install
+@cd scripts/ && $(MAKE_INSTALL) install; \
cd ../src/mod && $(MAKE_INSTALL) install-scripts

#safety hash
3 changes: 3 additions & 0 deletions aclocal.m4
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ dnl
dnl Load tcl macros
builtin(include,m4/tcl.m4)

dnl Load python macros
builtin(include,m4/python.m4)

dnl Load gnu autoconf archive macros
builtin(include,m4/ax_create_stdint_h.m4)
builtin(include,m4/ax_lib_socket_nsl.m4)
Expand Down
48 changes: 48 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,8 @@ EGG_CROSS_COMPILING
MOD_UPDIR
DEST
EGGVERSION
egg_with_python_config
egg_enable_python
SSL_LIBS
SSL_INCLUDES
DEBCFLGS
Expand Down Expand Up @@ -801,6 +803,8 @@ enable_tls
with_sslinc
with_ssllib
enable_tdns
enable_python
with_python_config
'
ac_precious_vars='build_alias
host_alias
Expand Down Expand Up @@ -1458,6 +1462,9 @@ Optional Features and Packages:
--with-sslinc=PATH Path to OpenSSL headers
--with-ssllib=PATH Path to OpenSSL libraries
--disable-tdns disable threaded DNS core
--enable-python enable Python support (autodetect)
--disable-python disable Python support
--with-python-config=PATH Path to python-config

Some influential environment variables:
CC C compiler command
Expand Down Expand Up @@ -10603,6 +10610,47 @@ printf "%s\n" "#define EGG_TDNS 1" >>confdefs.h
fi


# Check for Python

{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile the Python module" >&5
$as_echo_n "checking whether to compile the Python module... " >&6; }
# Check whether --enable-python was given.
if test "${enable_python+set}" = set; then :
enableval=$enable_python; egg_enable_python="$enableval"
fi

# Check whether --enable-python was given.
if test "${enable_python+set}" = set; then :
enableval=$enable_python; egg_enable_python="$enableval"
else
egg_enable_python="autodetect"
fi


{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $egg_enable_python" >&5
$as_echo "$egg_enable_python" >&6; }




# Check whether --with-python-config was given.
if test "${with_python_config+set}" = set; then :
withval=$with_python_config;
if test "x$enable_python" != "xno"; then
if test -d "$withval" || test -x "$withval"; then
egg_with_python_config="$withval"
else
egg_with_python_config="no"
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&5
$as_echo "$as_me: WARNING: Invalid path to python-config. $withval is not a directory and not an executable." >&2;}
fi
fi

fi





# Substitute Makefile variables.

Expand Down
4 changes: 4 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ EGG_TLS_DETECT
# Threaded DNS core
EGG_TDNS_ENABLE

# Check for Python
EGG_PYTHON_ENABLE
EGG_PYTHON_WITHCONFIG


# Substitute Makefile variables.
EGG_SUBST_EGGVERSION
Expand Down
149 changes: 149 additions & 0 deletions doc/sphinx_source/modules/mod/python.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
Last revised: November 03, 2023

.. _python:

============
Python Module
============

This module adds a Python interpreter to Eggdrop, allowing you to run Python scripts.

--------------
Loading Python
--------------

Put this line into your Eggdrop configuration file to load the python module::

loadmodule python

To load a python script from your config file, place the .py file in the scripts/ folder and add the following line to your config::

pysource scripts/myscript.py

------------------
Partyline Commands
------------------

^^^^^^^^^^^^^^^^^^^
python <expression>
^^^^^^^^^^^^^^^^^^^

You can run a python command from the partyline with the .python command, such as::

.python 1 + 1
Python: 2
.python from eggdrop.tcl import putmsg; putmsg('#chan', 'Hello world!')
Python: None

^^^^^^^^^^^^^
.binds python
^^^^^^^^^^^^^

The python module extends the core ``.binds`` partyline command by adding a ``python`` mask. This command will list all binds for python scripts.

------------
Tcl Commands
------------

^^^^^^^^^^^^^^^^^^^^^^^
pysource <path/to/file>
^^^^^^^^^^^^^^^^^^^^^^^

The ``pysource`` command is analgous to the Tcl ``source`` command, except that it loads a Python script into Eggdrop instead of a Tcl script.

-----------------------
Eggdrop Python Commands
-----------------------

The Python module is built to use the existing core Tcl commands integrated into Eggdrop via the ``eggdrop.tcl`` module. To call an existing Tcl command from Python, you can either load the entire catalog by running ``import eggdrop.tcl``, or be more specific by ``from eggdrop.tcl import putserv, putlog, chanlist``, etc.

Arguments to the Tcl functions are automatically converted as follows:

* ``None`` is converted to an empty Tcl object (the empty string, ``""``)
* ``List`` and ``Tuple`` is converted to a ``Tcl list``
* ``Dict`` is converted to a ``Tcl dictionary``
* Everything else is converted to a string using the str() method

Return values from Tcl functions must be manually converted:

* ``""`` the empty string is automatically converted to None
* everything else is returned as string
* ``Tcl list`` as string can be converted to a Python ``List`` using ``parse_tcl_list``
* ``Tcl dictionary`` as string can be converted to a Python ``Dict`` using ``parse_tcl_list``

Additionally, a few extra python commands have been created for use without these conversions:

^^^^^^^^^^^^^^^^
bind <arguments>
^^^^^^^^^^^^^^^^

The python version of the bind command is used to create a bind that triggers a python function. The python bind takes the same arguments as the Tcl binds, for more information on bind argument syntax please see tcl_binds_. The eggdrop.tcl.bind command should not be used as it will attempt to call a Tcl proc.

^^^^^^^^^^^^^^^^^^^^^^^
parse_tcl_list <string>
^^^^^^^^^^^^^^^^^^^^^^^

When a python script calls a Tcl command that returns a list via the eggdrop.tcl module, the return value will be a Tcl-formatted list- also simply known as a string. The ``parse_tcl_list`` command will convert the Tcl-formatted list into a Python list, which can then freely be used within the Python script.

^^^^^^^^^^^^^^^^^^^^^^^
parse_tcl_dict <string>
^^^^^^^^^^^^^^^^^^^^^^^

When a python script calls a Tcl command that returns a dict via the eggdrop.tcl module, the return value will be a Tcl-formatted dict- also simply known as a string. The ``parse_tcl_dict`` command will c
onvert the Tcl-formatted dict into a Python list, which can then freely be used within the Python script.

----------------
Config variables
----------------

There are also some variables you can set in your config file:

set allow-resync 0
When two bots get disconnected, this setting allows them to create a
resync buffer which saves all changes done to the userfile during
the disconnect. When they reconnect, they will not have to transfer
the complete user file, but, instead, just send the resync buffer.

--------------------------------
Writing an Eggdrop Python script
--------------------------------

This is how to write a python script for Eggdrop.

You can view examples of Python scripts in the exampleScripts folder included with this module.

.. glossary::
bestfriend.py
This example script demonstrates how to use the parse_tcl_list() python command to convert a list returned by a Tcl command into a list that is usable by Python.
greet.py
This is a very basic script that demonstrates how a Python script with binds can be run by Eggdrop.
imdb.py
This script shows how to use an existing third-party module to extend a Python script, in this case retrieving information from imdb.com.
listtls.py
This script demonstrates how to use parse-tcl_list() and parse_tcl_dict() to convert a list of dicts provided by Tcl into something that is usuable by Python.
urltitle.py
This script shows how to use an existing third-party module to extend a Python script, in this case using an http parser to collect title information from a provided web page.


^^^^^^^^^^^^^^
Header section
^^^^^^^^^^^^^^

An Eggdrop python script requires you to import X Y and Z, in this format.

^^^^^^^^^^^^
Code Section
^^^^^^^^^^^^

Normal python code works here. To run a command from the Eggdrop Tcl library, use this format.

Use this format all over.

-------------------------------------
Writing a module for use with Eggdrop
-------------------------------------

This is how you import a module for use with an egg python script.


Copyright (C) 2000 - 2023 Eggheads Development Team
3 changes: 3 additions & 0 deletions doc/sphinx_source/using/tcl-commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2228,6 +2228,8 @@ unbind <type> <flags> <keyword/mask> <proc-name>
binds [type/mask]
^^^^^^^^^^^^^^^^^

Description: By default, lists Tcl binds registered with the Eggdrop. You can specify 'all' to view all binds, 'tcl' to view Tcl binds, and 'python' to view Python binds. Alternately, you can specify a bind type (pub, msg, etc) to view all binds that match that type of bind, or a mask that is matched against the command associated with the bind.

Returns: a list of Tcl binds, each item in the list is a sublist of five elements:
{<type> <flags> <name> <hits> <proc>}

Expand Down Expand Up @@ -2898,6 +2900,7 @@ Removing a bind
To remove a bind, use the 'unbind' command. For example, to remove the
bind for the "stop" msg command, use 'unbind msg - stop msg:stop'.

.. _tcl_binds:

^^^^^^^^^^
Flag Masks
Expand Down
53 changes: 53 additions & 0 deletions m4/python.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
dnl python.m4 -- Autoconf macros to compile python.mod
dnl
dnl Copyright (c) 2022 - 2022 Eggheads Development Team
dnl
dnl This program is free software; you can redistribute it and/or
dnl modify it under the terms of the GNU General Public License
dnl as published by the Free Software Foundation; either version 2
dnl of the License, or (at your option) any later version.
dnl
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
dnl

dnl EGG_PYTHON_ENABLE
dnl
AC_DEFUN([EGG_PYTHON_ENABLE],
[
AC_MSG_CHECKING([whether to compile the Python module])
AC_ARG_ENABLE(python,
[ --enable-python enable Python support (autodetect)],
[egg_enable_python="$enableval"])
AC_ARG_ENABLE(python,
[ --disable-python disable Python support], [egg_enable_python="$enableval"],
[egg_enable_python="autodetect"])
AC_MSG_RESULT([$egg_enable_python])
AC_SUBST(egg_enable_python)
])


dnl EGG_PYTHON_WITHCONFIG
dnl
AC_DEFUN(EGG_PYTHON_WITHCONFIG,
[
AC_ARG_WITH(python-config, [ --with-python-config=PATH Path to python-config], [
if test "x$enable_python" != "xno"; then
if test -d "$withval" || test -x "$withval"; then
egg_with_python_config="$withval"
else
egg_with_python_config="no"
AC_MSG_WARN([Invalid path to python-config. $withval is not a directory and not an executable.])
fi
fi
])
AC_SUBST(egg_with_python_config)
])

2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ extern sigjmp_buf alarmret;
time_t now;
static int argc;
static char **argv;
char *argv0;

/*
* Please use the PATCH macro instead of directly altering the version
Expand Down Expand Up @@ -1034,6 +1035,7 @@ int main(int arg_c, char **arg_v)

argc = arg_c;
argv = arg_v;
argv0 = argv[0];

/* Version info! */
#ifdef EGG_PATCH
Expand Down
14 changes: 13 additions & 1 deletion src/mod/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ distclean:
fi; \
done

install: install-help install-language
install: install-help install-language install-scripts

install-help:
@echo "Copying module help files." && \
Expand Down Expand Up @@ -169,4 +169,16 @@ install-language:
fi; \
done;

install-scripts:
@for i in $(mods); do \
if test ! "x`echo $(srcdir)/$$i/scripts/*`" = "x$(srcdir)/$$i/scripts/*"; then \
echo "Installing example $$i scripts"; \
for s in $(srcdir)/$$i/scripts/*; do \
if test ! -f "$(DEST)/scripts/`basename "$$s"`"; then \
$(INSTALL_DATA) $$s $(DEST)/scripts/; \
fi; \
done; \
fi; \
done;

#safety hash
6 changes: 4 additions & 2 deletions src/mod/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -528,8 +528,10 @@ typedef void (*chanout_butfunc)(int, int, const char *, ...) ATTRIBUTE_FORMAT(pr
#define get_user_by_account ((struct userrec * (*)(char *))global[317])
#define delaccount_by_handle ((int(*)(char *,char *))global[318])
#define check_tcl_event_arg ((void (*) (const char *,const char *))global[319])
/*320 - 323 */

/* 320 - 323 */
#define bind_bind_entry ((int(*)(tcl_bind_list_t *, const char *, const char *, const char *))global[320])
#define unbind_bind_entry ((int(*)(tcl_bind_list_t *, const char *, const char *, const char *))global[321])
#define argv0 ((char *)global[322])



Expand Down
Loading