diff --git a/gnucash/python/CMakeLists.txt b/gnucash/python/CMakeLists.txt index f617858c89..a6690ddf8e 100644 --- a/gnucash/python/CMakeLists.txt +++ b/gnucash/python/CMakeLists.txt @@ -1,3 +1,5 @@ +set(gncmod_python_SOURCES gncmod-python.c) + set(pycons_DATA pycons/__init__.py pycons/console.py @@ -9,6 +11,23 @@ set(pycons_DATA ) if (WITH_PYTHON) + + add_library(gncmod-python ${gncmod_python_SOURCES}) + # target_link_libraries(gncmod-python gnc-module gnc-core-utils-python gncmod-app-utils-python + target_link_libraries(gncmod-python gnc-module gnc-core-utils + ${PYTHON_LIBRARIES} ${GLIB_LIBS}) # ${PYTHON_EXTRA_LIBS} + target_include_directories(gncmod-python + PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libgnucash/core-utils ${CMAKE_SOURCE_DIR}/gnc-module ${PYTHON_INCLUDE_DIR}) + target_compile_options(gncmod-python PRIVATE -DG_LOG_DOMAIN=\"gnc.python\") +if (APPLE) + set_target_properties (gncmod-python PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/gnucash") +endif() + install(TARGETS gncmod-python + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + install(FILES ${pycons_DATA} DESTINATION ${CMAKE_INSTALL_DATADIR}/gnucash/python/pycons) install(FILES init.py DESTINATION ${CMAKE_INSTALL_DATADIR}/gnucash/python) @@ -17,6 +36,6 @@ if (WITH_PYTHON) endif(WITH_PYTHON) set_local_dist(pycons_DIST ${pycons_DATA}) -set_local_dist(python_DIST_local CMakeLists.txt init.py) +set_local_dist(python_DIST_local CMakeLists.txt gncmod-python.c init.py) set(python_DIST ${python_DIST_local} ${pycons_DIST} PARENT_SCOPE) diff --git a/gnucash/python/gncmod-python.c b/gnucash/python/gncmod-python.c new file mode 100644 index 0000000000..15f94ecbf4 --- /dev/null +++ b/gnucash/python/gncmod-python.c @@ -0,0 +1,133 @@ +/********************************************************************* + * gncmod-python.c + * Python in GnuCash?! Sweet. + * + * Copyright (c) 2011 Andy Clayton + *********************************************************************/ +/********************************************************************\ + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License as * + * published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License* + * along with this program; if not, contact: * + * * + * Free Software Foundation Voice: +1-617-542-5942 * + * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * + * Boston, MA 02110-1301, USA gnu@gnu.org * + * * +\********************************************************************/ + + +#include +#include +#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); +//extern PyObject* PyInit__sw_core_utils(void); +#else +//extern void init_sw_app_utils(void); +//extern void init_sw_core_utils(void); +#endif + +int +libgncmod_python_gnc_module_init(int refcount) +{ + /* There isn't yet a python module to init. + PyObject *pName, *pModule; + */ + FILE *fp; + gchar *pkgdatadir, *init_filename; +#if PY_VERSION_HEX >= 0x03000000 + wchar_t* argv = NULL; +#else + char* argv = ""; +#endif + Py_Initialize(); + PySys_SetArgv(0, &argv); + // I dont quite understand why these are loaded here + // - these are python modules so should be able to just import them + // in init.py +#if PY_VERSION_HEX >= 0x03000000 + //PyInit__sw_app_utils(); + //PyInit__sw_core_utils(); +#else + //init_sw_app_utils(); + //init_sw_core_utils(); +#endif + + /* There isn't yet a python module to init. + 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/gnucash/python/init.py b/gnucash/python/init.py index 4ec0febd30..ca96f12233 100644 --- a/gnucash/python/init.py +++ b/gnucash/python/init.py @@ -1,7 +1,7 @@ import sys -import _sw_app_utils +import gnucash._sw_app_utils as _sw_app_utils from gnucash import * -from _sw_core_utils import gnc_prefs_is_extra_enabled +from gnucash._sw_core_utils import gnc_prefs_is_extra_enabled from gi import require_version require_version('Gtk', '3.0') from gi.repository import Gtk diff --git a/gnucash/python/pycons/console.py b/gnucash/python/pycons/console.py index 6a070b8603..760c498c28 100644 --- a/gnucash/python/pycons/console.py +++ b/gnucash/python/pycons/console.py @@ -31,12 +31,14 @@ import sys import re import tempfile import readline +import gi +gi.require_version('Gtk', '3.0') from gi.repository import GObject from gi.repository import Gtk from gi.repository import Pango -from StringIO import StringIO -import shell -try: import ishell +import io +import pycons.shell as shell +try: import pycons.ishell as ishell except: pass ansi_colors = {'0;30': '#2E3436', @@ -79,8 +81,8 @@ class ConsoleOut: def writelines(self, l): for s in l: self.console.write (s, self.style) - def seek(self, a): raise IOError, (29, 'Illegal seek') - def tell(self): raise IOError, (29, 'Illegal seek') + def seek(self, a): raise IOError(29, 'Illegal seek') + def tell(self): raise IOError(29, 'Illegal seek') truncate = tell @@ -113,8 +115,8 @@ class ConsoleIn: def readlines(self): return [] def write(self, s): return None def writelines(self, l): return None - def seek(self, a): raise IOError, (29, 'Illegal seek') - def tell(self): raise IOError, (29, 'Illegal seek') + def seek(self, a): raise IOError(29, 'Illegal seek') + def tell(self): raise IOError(29, 'Illegal seek') truncate = tell @@ -179,7 +181,7 @@ class Console (Gtk.ScrolledWindow): # Console stuff self.argv = argv self.history_init(filename, size) - self.cout = StringIO() + self.cout = io.StringIO() self.cout.truncate(0) if shelltype=='ipython': self.shell = ishell.Shell(argv,locals(),globals(), diff --git a/gnucash/python/pycons/shell.py b/gnucash/python/pycons/shell.py index d50043eb95..dfdc0d8ba0 100644 --- a/gnucash/python/pycons/shell.py +++ b/gnucash/python/pycons/shell.py @@ -153,9 +153,9 @@ class Shell: console.write (buf, 'output') if len(buf) < 256: break # Command output - print(`r`) + print(repr(r)) except SyntaxError: - exec self.command in self.globals + exec(self.command in self.globals) except: if hasattr (sys, 'last_type') and sys.last_type == SystemExit: console.quit() diff --git a/po/POTFILES.in b/po/POTFILES.in index b8cc820fe7..c7924e8212 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -361,6 +361,7 @@ gnucash/import-export/qif-imp/qif-parse.scm gnucash/import-export/qif-imp/qif-to-gnc.scm gnucash/import-export/qif-imp/qif-utils.scm gnucash/import-export/qif-imp/string.scm +gnucash/python/gncmod-python.c gnucash/register/ledger-core/gncEntryLedger.c gnucash/register/ledger-core/gncEntryLedgerControl.c gnucash/register/ledger-core/gncEntryLedgerDisplay.c