diff --git a/configure.ac b/configure.ac index 1dc11b3ea2..51ac624ef3 100644 --- a/configure.ac +++ b/configure.ac @@ -1160,12 +1160,12 @@ fi AC_SUBST(LC_MESSAGES_ENUM) ###-------------------------------------------------------- -### Make Python bindings optional +### Make Python plugin and bindings optional ###-------------------------------------------------------- enable_python=false -AC_ARG_ENABLE(python-bindings, - [AS_HELP_STRING([--enable-python-bindings],[enable python bindings])], +AC_ARG_ENABLE(python, + [AS_HELP_STRING([--enable-python],[enable python plugin and bindings])], [case "${enableval}" in yes) enable_python=true ;; no) enable_python=false ;; @@ -1174,14 +1174,23 @@ AC_ARG_ENABLE(python-bindings, ) if test x${enable_python} = "xtrue" then - PYTHON_DIR=python-bindings + PYTHON_DIR=python + PYTHON_BINDINGS_DIR=python-bindings AM_PATH_PYTHON(2.4) AC_PYTHON_DEVEL(>= '2.4') SWIG_PYTHON fi AC_SUBST(PYTHON_DIR) +AC_SUBST(PYTHON_BINDINGS_DIR) AM_CONDITIONAL(WITH_PYTHON, [test x${enable_python} = xtrue]) +AC_ARG_ENABLE(python-bindings, + [AS_HELP_STRING([--enable-python-bindings],[obsolete: replaced by --enable-python])], + if test "x$enableval" != "xno" ; then + AC_MSG_ERROR([--enable-python-bindings is obsolete: The option has been renamed into --enable-python]) + fi) + + ###------------------------------------------------------------------------- ### Additional compiler warnings (or not) if we're running GCC ###------------------------------------------------------------------------- @@ -1378,6 +1387,7 @@ AC_CONFIG_FILES( src/optional/python-bindings/Makefile src/optional/python-bindings/tests/Makefile src/pixmaps/Makefile + src/python/Makefile src/quotes/Makefile src/register/Makefile src/register/ledger-core/Makefile @@ -1441,7 +1451,7 @@ if test x${AQBANKING_DIR} != x; then components="$components $AQBANKING_DIR" fi if test x${PYTHON_DIR} != x; then - components="$components python-bindings" + components="$components python" fi if test x${GTKMM_DIR} != x; then components="${components} ${GTKMM_DIR}" diff --git a/po/POTFILES.in b/po/POTFILES.in index 245b21ad76..e9c786246d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -445,6 +445,7 @@ src/plugins/bi_import/gncmod-bi_import.c src/plugins/bi_import/gnc-plugin-bi_import.c src/plugins/bi_import/gui.c src/plugins/bi_import/helpers.c +src/python/gncmod-python.c src/register/ledger-core/dialog-dup-trans.c src/register/ledger-core/gnc-ledger-display.c src/register/ledger-core/gncmod-ledger-core.c diff --git a/src/Makefile.am b/src/Makefile.am index b3c434c5e9..4bb7b0e5fc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,4 @@ +# These directories do not contain any gtk dependencies NONGUI_SUBDIRS = \ libqof \ debug \ @@ -9,17 +10,23 @@ NONGUI_SUBDIRS = \ engine \ backend \ scm \ - quotes - -GUI_SUBDIRS_1 = \ + quotes \ calculation \ - tax \ + tax + +# These directories should also not contain any gtk dependencies, but +# currently there is only single very little dependency in +# app-utils. It should go away in the long run, though. +ALMOST_NONGUI_SUBDIRS = \ app-utils \ + ${PYTHON_DIR} + +# These directories contain the code with gtk dependency +GUI_SUBDIRS = \ gnome-utils \ html \ - gnome-search - -GUI_SUBDIRS_2 = \ + gnome-search \ + report \ register \ gnome \ import-export \ @@ -28,13 +35,8 @@ GUI_SUBDIRS_2 = \ plugins \ bin -DIST_SUBDIRS = $(NONGUI_SUBDIRS) $(GUI_SUBDIRS_1) report $(GUI_SUBDIRS_2) - -if GNUCASH_ENABLE_GUI -SUBDIRS = . $(DIST_SUBDIRS) -else -SUBDIRS = . $(NONGUI_SUBDIRS) report -endif +SUBDIRS = $(NONGUI_SUBDIRS) $(ALMOST_NONGUI_SUBDIRS) $(GUI_SUBDIRS) +DIST_SUBDIRS = $(SUBDIRS) python noinst_HEADERS = \ swig-runtime.h diff --git a/src/bin/gnucash-bin.c b/src/bin/gnucash-bin.c index dd9bc54d77..847a62aa1a 100644 --- a/src/bin/gnucash-bin.c +++ b/src/bin/gnucash-bin.c @@ -581,6 +581,7 @@ load_gnucash_modules() { "gnucash/report/report-gnome", 0, FALSE }, { "gnucash/business-gnome", 0, TRUE }, { "gnucash/gtkmm", 0, TRUE }, + { "gnucash/python", 0, TRUE }, }; /* module initializations go here */ diff --git a/src/optional/Makefile.am b/src/optional/Makefile.am index 99f5bd6d23..3c5bae0d2b 100644 --- a/src/optional/Makefile.am +++ b/src/optional/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = ${PYTHON_DIR} ${GTKMM_DIR} +SUBDIRS = ${PYTHON_BINDINGS_DIR} ${GTKMM_DIR} DIST_SUBDIRS = python-bindings gtkmm diff --git a/src/python/Makefile.am b/src/python/Makefile.am new file mode 100644 index 0000000000..319b122eb2 --- /dev/null +++ b/src/python/Makefile.am @@ -0,0 +1,62 @@ +SUBDIRS = . +#test + +pkglib_LTLIBRARIES = libgncmod-python.la + +libgncmod_python_la_SOURCES = \ + gncmod-python.c + +libgncmod_python_la_LDFLAGS = -avoid-version \ + ${PYTHON_LDFLAGS} + +libgncmod_python_la_LIBADD = \ + ${top_builddir}/src/gnc-module/libgnc-module.la \ + ${top_builddir}/src/core-utils/libgnc-core-utils.la \ + ${top_builddir}/src/app-utils/libgncmod-app-utils-python.la \ + ${PYTHON_LIBS} \ + ${PYTHON_EXTRA_LIBS} \ + ${GLIB_LIBS} + +AM_CPPFLAGS = \ + -I${top_srcdir}/src \ + -I${top_srcdir}/src/core-utils \ + -I${top_srcdir}/src/gnc-module \ + ${PYTHON_CPPFLAGS} \ + ${GLIB_CFLAGS} + + +gncpymoddir = ${GNC_SHAREDIR}/python/ +gncpymod_DATA = \ + init.py + +if GNUCASH_SEPARATE_BUILDDIR +#For executing test cases +PY_FILE_LINKS = ${gncpymod_DATA} +endif + +.py-links: + $(RM) -rf gnucash + mkdir -p gnucash + mkdir -p gnucash/python +if GNUCASH_SEPARATE_BUILDDIR + for X in ${PY_FILE_LINKS} ; do \ + $(LN_S) -f ${srcdir}/$$X . ; \ + done +endif + ( cd gnucash/python; for A in $(gncpymod_DATA) ; do $(LN_S) -f ../../$$A . ; done ) +if ! OS_WIN32 +# Windows knows no "ln -s" but uses "cp": must copy every time (see bug #566567). + touch .py-links +endif + +clean-local: + $(RM) -rf gnucash + +noinst_DATA = .py-links + +EXTRA_DIST = ${gncpymod_DATA} + +CLEANFILES = .py-links +DISTCLEANFILES = ${PY_FILE_LINKS} + +INCLUDES = -DG_LOG_DOMAIN=\"gnc.python\" diff --git a/src/python/gncmod-python.c b/src/python/gncmod-python.c new file mode 100644 index 0000000000..cc79ce3286 --- /dev/null +++ b/src/python/gncmod-python.c @@ -0,0 +1,96 @@ +/********************************************************************* + * gncmod-python.c + * Python in GnuCash?! Sweet. + * + * Copyright (c) 2011 Andy Clayton + *********************************************************************/ + +#include +#include "config.h" +#include +#include + +#include "gnc-module.h" +#include "gnc-module-api.h" +#include "gnc-path.h" + +GNC_MODULE_API_DECL(libgncmod_python) + +/* version of the gnc module system interface we require */ +int libgncmod_python_gnc_module_system_interface = 0; + +/* module versioning uses libtool semantics. */ +int libgncmod_python_gnc_module_current = 0; +int libgncmod_python_gnc_module_revision = 0; +int libgncmod_python_gnc_module_age = 0; + + +char * +libgncmod_python_gnc_module_path(void) +{ + return g_strdup("gnucash/python"); +} + +char * +libgncmod_python_gnc_module_description(void) +{ + return g_strdup("An embedded Python interpreter"); +} + +#if PY_VERSION_HEX >= 0x03000000 +extern PyObject* PyInit__sw_app_utils(void); +#else +extern void init_sw_app_utils(void); +#endif + +int +libgncmod_python_gnc_module_init(int refcount) +{ + PyObject *pName, *pModule; + FILE *fp; + gchar *pkgdatadir, *init_filename; + + Py_Initialize(); +#if PY_VERSION_HEX >= 0x03000000 + PyInit__sw_app_utils(); +#else + init_sw_app_utils(); +#endif + + /* + pName = PyString_FromString("path/to/init.py"); + pModule = PyImport_Import(pName); + + if (!pModule) { + PyErr_Print(); + return FALSE; + } + + Py_DECREF(pName); + Py_DECREF(pModule); + */ + + pkgdatadir = gnc_path_get_pkgdatadir(); + init_filename = g_build_filename(pkgdatadir, "python/init.py", (char*)NULL); + g_debug("Looking for python init script at %s", (init_filename ? init_filename : "")); + fp = fopen(init_filename, "r+"); + if (fp) { + PyRun_SimpleFile(fp, init_filename); + fclose(fp); + + /* PyRun_InteractiveLoop(stdin, "foo"); */ + } else { + g_warning("Unable to initialize Python module (unable to open %s)", init_filename); + } + g_free(init_filename); + g_free(pkgdatadir); + + return TRUE; +} + +int +libgncmod_python_gnc_module_end(int refcount) +{ + Py_Finalize(); + return TRUE; +} diff --git a/src/python/init.py b/src/python/init.py new file mode 100644 index 0000000000..83214f0776 --- /dev/null +++ b/src/python/init.py @@ -0,0 +1,23 @@ +import sys +import _sw_app_utils +from gnucash import * + +print "Hello from python!" + +print "test", sys.modules.keys() +print "test2", dir(_sw_app_utils) + +root = _sw_app_utils.gnc_get_current_root_account() + +print "test", dir(root), root.__class__ +print "test2", dir(gnucash_core_c) + +acct = Account(instance = root) + +print "test3", dir(acct) +#print acct.GetName() +#print acct.GetBalance() +#print acct.GetSplitList() + +#print "test2", dir(gnucash.gnucash_core_c) +