mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Python bindings for the gnucash API.
Submitted by Mark Jenkins on 2008-03-25 to gnucash-devel. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@17263 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
0c9ce6d1f2
commit
4fa2e87962
2
AUTHORS
2
AUTHORS
@ -150,6 +150,7 @@ Ron Forrester <rjf@aracnet.com> for gnome patches
|
||||
Dave Freese <DFreese@osc.uscg.mil> for leap-year fix
|
||||
Todd T. Fries <todd@flare.fries.net> OpenBSD fix
|
||||
John Goerzen <jgoerzen@complete.org> file i/o fix for 64-bit architectures
|
||||
Jeff Green <jmgreen7@gmail.com> Python bindings
|
||||
Hans de Graaff <hans@degraaff.org> XML patches
|
||||
Daniel Hagerty <hag@linnaean.org> patch to balance sheet report
|
||||
Mitsuo Hamada <mhamada@redhat.com> messages Japanese translations
|
||||
@ -166,6 +167,7 @@ Péter Hosszú <hosszu@web.de> Hungarian translation
|
||||
Edward J. Huff <ejhuff@huff20may77.us> Date handling in reports, quarterly option
|
||||
Tomokazu Iwashita <iwashita@center.nitech.ac.jp> Japanese translation of xea
|
||||
David Jafferian <david.jafferian@east.sun.com> Delete account query code.
|
||||
Mark Jenkins <mark@parit.ca> Python bindings
|
||||
Miquel Jordana Vilamitjana <jjvmjv@mundomail.net> Spanish translation of manual
|
||||
Prakash Kailasa <PrakashK@bigfoot.com> for gnome build fixes
|
||||
Alexey Kakunin <small@arcadia.spb.ru> quickfill patch for Cyrillic
|
||||
|
26
configure.in
26
configure.in
@ -1329,6 +1329,28 @@ else
|
||||
fi
|
||||
AC_SUBST(LC_MESSAGES_ENUM)
|
||||
|
||||
###--------------------------------------------------------
|
||||
### Make Python bindings optional
|
||||
###--------------------------------------------------------
|
||||
enable_python=false
|
||||
|
||||
AC_ARG_ENABLE(python-bindings,
|
||||
[ --enable-python-bindings enable python bindings],
|
||||
[case "${enableval}" in
|
||||
yes) enable_python=true ;;
|
||||
no) enable_python=false ;;
|
||||
*) enable_python=true ;;
|
||||
esac]
|
||||
)
|
||||
if test x${enable_python} = "xtrue"
|
||||
then
|
||||
PYTHON_DIR=python-bindings
|
||||
AM_PATH_PYTHON(2.4)
|
||||
AC_PYTHON_DEVEL(>= '2.4')
|
||||
SWIG_PYTHON
|
||||
fi
|
||||
AC_SUBST(PYTHON_DIR)
|
||||
|
||||
###-------------------------------------------------------------------------
|
||||
### Additional compiler warnings (or not) if we're running GCC
|
||||
###-------------------------------------------------------------------------
|
||||
@ -1520,6 +1542,7 @@ AC_CONFIG_FILES(po/Makefile.in
|
||||
src/import-export/hbci/schemas/Makefile
|
||||
src/import-export/hbci/test/Makefile
|
||||
src/optional/Makefile
|
||||
src/optional/python-bindings/Makefile
|
||||
src/optional/xsl/Makefile
|
||||
src/pixmaps/Makefile
|
||||
src/quotes/Makefile
|
||||
@ -1585,6 +1608,9 @@ fi
|
||||
if test x${HBCI_DIR} != x; then
|
||||
components="$components hbci"
|
||||
fi
|
||||
if test x${PYTHON_DIR} != x; then
|
||||
components="$components python-bindings"
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([
|
||||
Options detected/selected
|
||||
|
64
macros/ac_python_devel.m4
Normal file
64
macros/ac_python_devel.m4
Normal file
@ -0,0 +1,64 @@
|
||||
dnl @synopsis AC_PYTHON_DEVEL
|
||||
dnl
|
||||
dnl Checks for Python and tries to get the include path to 'Python.h'.
|
||||
dnl It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output
|
||||
dnl variable.
|
||||
dnl
|
||||
dnl @category InstalledPackages
|
||||
dnl @author Sebastian Huber <sebastian-huber@web.de>
|
||||
dnl @author Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
dnl @author Rafael Laboissiere <laboissiere@psy.mpg.de>
|
||||
dnl @author Andrew Collier <colliera@nu.ac.za>
|
||||
dnl @version 2004-07-14
|
||||
dnl @license GPLWithACException
|
||||
|
||||
AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
#
|
||||
# should allow for checking of python version here...
|
||||
#
|
||||
AC_REQUIRE([AM_PATH_PYTHON])
|
||||
|
||||
# Check for Python include path
|
||||
AC_MSG_CHECKING([for Python include path])
|
||||
python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
|
||||
for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do
|
||||
python_path=`find $i -type f -name Python.h -print | sed "1q"`
|
||||
if test -n "$python_path" ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
python_path=`echo $python_path | sed "s,/Python.h$,,"`
|
||||
AC_MSG_RESULT([$python_path])
|
||||
if test -z "$python_path" ; then
|
||||
AC_MSG_ERROR([cannot find Python include path])
|
||||
fi
|
||||
AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path])
|
||||
|
||||
# Check for Python library path
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
python_path=`echo $PYTHON | sed "s,/bin.*$,,"`
|
||||
for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do
|
||||
python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print | sed "1q"`
|
||||
if test -n "$python_path" ; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
python_path=`echo $python_path | sed "s,/libpython.*$,,"`
|
||||
AC_MSG_RESULT([$python_path])
|
||||
if test -z "$python_path" ; then
|
||||
AC_MSG_ERROR([cannot find Python library path])
|
||||
fi
|
||||
AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"])
|
||||
#
|
||||
python_site=`echo $python_path | sed "s/config/site-packages/"`
|
||||
AC_SUBST([PYTHON_SITE_PKG],[$python_site])
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS')+' '+conf('LIBS')"
|
||||
AC_MSG_RESULT($PYTHON_EXTRA_LIBS)`
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
])
|
@ -1 +1,2 @@
|
||||
SUBDIRS = xsl
|
||||
SUBDIRS = xsl ${PYTHON_DIR}
|
||||
DIST_SUBDIRS = xsl python-bindings
|
||||
|
25
src/optional/python-bindings/Makefile.am
Normal file
25
src/optional/python-bindings/Makefile.am
Normal file
@ -0,0 +1,25 @@
|
||||
BUILT_SOURCES = gnucash_core.c
|
||||
SWIG_SOURCES = gnucash_core.i
|
||||
|
||||
pkgpython_PYTHON = __init__.py function_class.py \
|
||||
gnucash_core.py gnucash_core_c.py
|
||||
|
||||
pkgpyexec_LTLIBRARIES = _gnucash_core_c.la
|
||||
_gnucash_core_c_la_SOURCES = $(BUILT_SOURCES) $(SWIG_SOURCES)
|
||||
_gnucash_core_c_la_CPPFLAGS = $(PYTHON_CPPFLAGS) \
|
||||
-I$(top_srcdir)/src $(QOF_CFLAGS) \
|
||||
$(GLIB_CFLAGS) $(GUILE_INCS) \
|
||||
-I$(top_srcdir)/src/engine
|
||||
|
||||
# Suppress all warnings for now, but we really only need to -Wno-implicit
|
||||
AM_CFLAGS = -w
|
||||
|
||||
_gnucash_core_c_la_LDFLAGS = -avoid-version -module
|
||||
_gnucash_core_c_la_LIBADD = ${QOF_LIBS} ${GUILE_LIBS} ${GLIB_LIBS} \
|
||||
${top_builddir}/src/gnc-module/libgnc-module.la \
|
||||
${top_builddir}/src/engine/libgncmod-engine.la
|
||||
|
||||
gnucash_core.c : $(SWIG_SOURCES)
|
||||
$(SWIG) $(SWIG_PYTHON_OPT) -Wall -Werror \
|
||||
-I$(top_srcdir)/src -I$(top_srcdir)/src/engine \
|
||||
$(QOF_CFLAGS) -o $@ $<
|
6
src/optional/python-bindings/__init__.py
Normal file
6
src/optional/python-bindings/__init__.py
Normal file
@ -0,0 +1,6 @@
|
||||
# import all the symbols from gnucash_core, so basic gnucash stuff can be
|
||||
# loaded with:
|
||||
# >>> from gnucash import thingy
|
||||
# instead of
|
||||
# >>> from gnucash.gnucash_core import thingy
|
||||
from gnucash_core import *
|
13
src/optional/python-bindings/example_scripts/simple_book.py
Normal file
13
src/optional/python-bindings/example_scripts/simple_book.py
Normal file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python
|
||||
from gnucash import Book
|
||||
|
||||
book = Book()
|
||||
|
||||
#Call some methods that produce output to show that Book works
|
||||
print "New book:"
|
||||
book.print_dirty()
|
||||
book.mark_saved()
|
||||
print "\nBook marked saved:"
|
||||
book.print_dirty()
|
||||
|
||||
book.destroy()
|
@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from gnucash import \
|
||||
Session, GnuCashBackendException, \
|
||||
ERR_BACKEND_LOCKED, ERR_FILEIO_FILE_NOT_FOUND
|
||||
|
||||
FILE_1 = "/tmp/not_there.xac"
|
||||
FILE_2 = "/tmp/example_file.xac"
|
||||
|
||||
# open a file that isn't there, detect the error
|
||||
session = None
|
||||
try:
|
||||
session = Session("file:%s" % FILE_1)
|
||||
except GnuCashBackendException, backend_exception:
|
||||
assert( ERR_FILEIO_FILE_NOT_FOUND in backend_exception.errors)
|
||||
|
||||
|
||||
# create a new file
|
||||
session = Session("file:%s" % FILE_2, True)
|
||||
session.save()
|
||||
session.end()
|
||||
session.destroy()
|
||||
|
||||
# open the new file, try to open it a second time, detect the lock
|
||||
session = Session("file:%s" % FILE_2)
|
||||
try:
|
||||
session_2 = Session("file:%s" % FILE_2)
|
||||
except GnuCashBackendException, backend_exception:
|
||||
assert( ERR_BACKEND_LOCKED in backend_exception.errors )
|
||||
session.end()
|
||||
session.destroy()
|
||||
|
||||
|
49
src/optional/python-bindings/example_scripts/simple_test.py
Normal file
49
src/optional/python-bindings/example_scripts/simple_test.py
Normal file
@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from gnucash import \
|
||||
Session, Account, Transaction, Split, GncCommodity, GncNumeric
|
||||
|
||||
|
||||
FILE_1 = "/tmp/example.xac"
|
||||
|
||||
session = None
|
||||
session = Session("file:%s" % FILE_1, True)
|
||||
|
||||
book = session.book
|
||||
root_account = book.get_root_account()
|
||||
acct1 = Account(book)
|
||||
acct2 = Account(book)
|
||||
trans = Transaction(book)
|
||||
split1 = Split(book)
|
||||
split2 = Split(book)
|
||||
comm = GncCommodity(book, "Canadian Dollars", "CURRENCY", "CAD", None, 100)
|
||||
debit_num = GncNumeric(4, 1)
|
||||
credit_num = debit_num.neg()
|
||||
|
||||
acct1.SetCommodity(comm)
|
||||
acct1.SetName("Savings")
|
||||
root_account.append_child(acct1)
|
||||
|
||||
acct2.SetCommodity(comm)
|
||||
acct2.SetName("Food expenses")
|
||||
root_account.append_child(acct2)
|
||||
|
||||
split1.SetValue(credit_num)
|
||||
split1.SetAccount(acct1)
|
||||
split1.SetParent(trans)
|
||||
|
||||
split2.SetValue(debit_num)
|
||||
split2.SetAccount(acct2)
|
||||
split2.SetParent(trans)
|
||||
|
||||
trans.SetCurrency(comm)
|
||||
trans.SetDescription("Groceries")
|
||||
|
||||
book.print_dirty()
|
||||
|
||||
book.mark_saved()
|
||||
book.mark_closed()
|
||||
|
||||
session.save()
|
||||
session.end()
|
||||
session.destroy()
|
167
src/optional/python-bindings/function_class.py
Normal file
167
src/optional/python-bindings/function_class.py
Normal file
@ -0,0 +1,167 @@
|
||||
# function_class.py -- Library for making python classes from a set
|
||||
# of functions.
|
||||
#
|
||||
# Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
|
||||
# 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
|
||||
#
|
||||
# @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
|
||||
|
||||
INSTANCE_ARGUMENT = "instance"
|
||||
|
||||
class ClassFromFunctions(object):
|
||||
"""Inherit this class to give yourself a python class that wraps a set of
|
||||
functions that together consitute the methods of the class.
|
||||
|
||||
The method functions must all have as a first argument an object
|
||||
holding the instance data. There must also be a function that
|
||||
returns a new instance of the class, the constructor.
|
||||
|
||||
Your subclass must define
|
||||
_module - The module where the method functions, including the
|
||||
constructor can be found
|
||||
_new_instance - The name of a function that serves as a constructor,
|
||||
returning the instance data.
|
||||
|
||||
To access the instance data, use the read-only property instance.
|
||||
|
||||
To add some functions from _module as methods, call classmethods like
|
||||
add_method and add_methods_with_prefix.
|
||||
"""
|
||||
def __new__(cls, *args, **kargs):
|
||||
# why reimpliment __new__? Because later on we're going to
|
||||
# use new to avoid creating new instances when existing instances
|
||||
# already exist with the same __instance value, or equivlent __instance
|
||||
# values, where this is desirable...
|
||||
return super(ClassFromFunctions, cls).__new__(cls, *args, **kargs)
|
||||
|
||||
def __init__(self, *args, **kargs):
|
||||
"""Construct a new instance, using either the function
|
||||
self._module[self._new_instance] or using existing instance
|
||||
data. (specified with the keyword argument, instance)
|
||||
|
||||
Pass the arguments that should be passed on to
|
||||
self._module[self._new_instance] . Any arguments of that
|
||||
are instances of ClassFromFunctions will be switched with the instance
|
||||
data. (by calling the .instance property)
|
||||
"""
|
||||
if INSTANCE_ARGUMENT in kargs:
|
||||
self.__instance = kargs[INSTANCE_ARGUMENT]
|
||||
else:
|
||||
self.__instance = getattr(self._module, self._new_instance)(
|
||||
*process_list_convert_to_instance(args) )
|
||||
|
||||
def get_instance(self):
|
||||
"""Get the instance data.
|
||||
|
||||
You can also call the instance property
|
||||
"""
|
||||
return self.__instance
|
||||
|
||||
instance = property(get_instance)
|
||||
|
||||
# CLASS METHODS
|
||||
|
||||
@classmethod
|
||||
def add_method(cls, function_name, method_name):
|
||||
"""Add the function, method_name to this class as a method named name
|
||||
"""
|
||||
def method_function(self, *meth_func_args):
|
||||
return getattr(self._module, function_name)(
|
||||
self.instance,
|
||||
*process_list_convert_to_instance(meth_func_args) )
|
||||
|
||||
setattr(cls, method_name, method_function)
|
||||
setattr(method_function, "__name__", method_name)
|
||||
return method_function
|
||||
|
||||
@classmethod
|
||||
def add_methods_with_prefix(cls, prefix):
|
||||
"""Add a group of functions with the same prefix
|
||||
"""
|
||||
for function_name, function_value, after_prefix in \
|
||||
extract_attributes_with_prefix(cls._module, prefix):
|
||||
cls.add_method(function_name, after_prefix)
|
||||
|
||||
@classmethod
|
||||
def add_constructor_and_methods_with_prefix(cls, prefix, constructor):
|
||||
"""Add a group of functions with the same prefix, and set the
|
||||
_new_instance attribute to prefix + constructor
|
||||
"""
|
||||
cls.add_methods_with_prefix(prefix)
|
||||
cls._new_instance = prefix + constructor
|
||||
|
||||
@classmethod
|
||||
def decorate_functions(cls, decorator, *args):
|
||||
for function_name in args:
|
||||
setattr( cls, function_name,
|
||||
decorator( getattr(cls, function_name) ) )
|
||||
|
||||
def method_function_returns_instance(method_function, cls):
|
||||
"""A function decorator that is used to decorates method functions that
|
||||
return instance data, to return instances instead.
|
||||
|
||||
You can't use this decorator with @, because this function has a second
|
||||
argument.
|
||||
"""
|
||||
assert( 'instance' == INSTANCE_ARGUMENT )
|
||||
def new_function(*args):
|
||||
kargs = { INSTANCE_ARGUMENT : method_function(*args) }
|
||||
return cls( **kargs )
|
||||
|
||||
return new_function
|
||||
|
||||
def default_arguments_decorator(function, *args):
|
||||
"""Decorates a function to give it default, positional arguments
|
||||
|
||||
You can't use this decorator with @, because this function has more
|
||||
than one argument.
|
||||
"""
|
||||
def new_function(*function_args):
|
||||
new_argset = list(function_args)
|
||||
new_argset.extend( args[ len(function_args): ] )
|
||||
return function( *new_argset )
|
||||
return new_function
|
||||
|
||||
def return_instance_if_value_has_it(value):
|
||||
"""Return value.instance if value is an instance of ClassFromFunctions,
|
||||
else return value
|
||||
"""
|
||||
if isinstance(value, ClassFromFunctions):
|
||||
return value.instance
|
||||
else:
|
||||
return value
|
||||
|
||||
def process_list_convert_to_instance( value_list ):
|
||||
"""Return a list built from value_list, where if a value is in an instance
|
||||
of ClassFromFunctions, we put value.instance in the list instead.
|
||||
|
||||
Things that are not instances of ClassFromFunctions are returned to
|
||||
the new list unchanged.
|
||||
"""
|
||||
return [ return_instance_if_value_has_it(value)
|
||||
for value in value_list ]
|
||||
|
||||
def extract_attributes_with_prefix(obj, prefix):
|
||||
"""Generator that iterates through the attributes of an object and
|
||||
for any attribute that matches a prefix, this yields
|
||||
the attribute name, the attribute value, and the text that appears
|
||||
after the prefix in the name
|
||||
"""
|
||||
for attr_name, attr_value in obj.__dict__.iteritems():
|
||||
if attr_name.startswith(prefix):
|
||||
after_prefix = attr_name[ len(prefix): ]
|
||||
yield attr_name, attr_value, after_prefix
|
92
src/optional/python-bindings/glib.i
Normal file
92
src/optional/python-bindings/glib.i
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* glib.i -- SWIG interface file for type translation of glib types
|
||||
*
|
||||
* Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
|
||||
*/
|
||||
|
||||
%typemap(in) gint8, gint16, gint32, gint64, gint, gshort, glong {
|
||||
$1 = ($1_type)PyInt_AsLong($input);
|
||||
}
|
||||
|
||||
%typemap(out) gint8, gint16, gint32, gint64, gint, gshort, glong {
|
||||
$result = PyInt_FromLong($1);
|
||||
}
|
||||
|
||||
%typemap(in) guint8, guint16, guint32, guint64, guint, gushort, gulong {
|
||||
$1 = ($1_type)PyLong_AsUnsignedLong($input);
|
||||
}
|
||||
|
||||
%typemap(out) guint8, guint16, guint32, guint64, guint, gushort, gulong {
|
||||
$result = PyLong_FromUnsignedLong($1);
|
||||
}
|
||||
|
||||
%typemap(in) gfloat, gdouble {
|
||||
$1 = ($1_type)PyFloat_AsDouble($input);
|
||||
}
|
||||
|
||||
%typemap(out) gfloat, gdouble {
|
||||
$result = PyFloat_FromDouble($1);
|
||||
}
|
||||
|
||||
%typemap(in) gchar * {
|
||||
$1 = ($1_type)PyString_AsString($input);
|
||||
}
|
||||
|
||||
%typemap(out) gchar * {
|
||||
$result = PyString_FromString($1);
|
||||
}
|
||||
|
||||
%typemap(in) gboolean {
|
||||
if ($input == Py_True)
|
||||
$1 = TRUE;
|
||||
else if ($input == Py_False)
|
||||
$1 = FALSE;
|
||||
else
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_ValueError,
|
||||
"Python object passed to a gboolean argument was not True "
|
||||
"or False" );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(out) gboolean {
|
||||
if ($1 == TRUE)
|
||||
{
|
||||
Py_INCREF(Py_True);
|
||||
$result = Py_True;
|
||||
}
|
||||
else if ($1 == FALSE)
|
||||
{
|
||||
Py_INCREF(Py_False);
|
||||
$result = Py_False;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(
|
||||
PyExc_ValueError,
|
||||
"function returning gboolean returned a value that wasn't "
|
||||
"TRUE or FALSE.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
76
src/optional/python-bindings/gnucash_core.i
Normal file
76
src/optional/python-bindings/gnucash_core.i
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* gnucash_core.i -- SWIG interface file for the core parts of GnuCash
|
||||
*
|
||||
* Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
|
||||
* @author Jeff Green, ParIT Worker Co-operative <jeff@parit.ca>
|
||||
*/
|
||||
|
||||
%module(package="gnucash") gnucash_core_c
|
||||
|
||||
%{
|
||||
#include "config.h"
|
||||
#include <datetime.h>
|
||||
#include "qofsession.h"
|
||||
#include "qofbook.h"
|
||||
#include "qofbackend.h"
|
||||
#include "gnc-commodity.h"
|
||||
#include "gnc-lot.h"
|
||||
#include "gnc-numeric.h"
|
||||
#include "Transaction.h"
|
||||
#include "Split.h"
|
||||
#include "Account.h"
|
||||
#include <guile/gh.h>
|
||||
%}
|
||||
|
||||
%include <timespec.i>
|
||||
|
||||
%include <glib.i>
|
||||
|
||||
%include <qofbackend.h>
|
||||
|
||||
// this function is defined in qofsession.h, but isnt found in the libraries,
|
||||
// ignoroed because SWIG attempts to link against (to create language bindings)
|
||||
%ignore qof_session_not_saved;
|
||||
%include <qofsession.h>
|
||||
|
||||
%include <qofbook.h>
|
||||
|
||||
%include <Transaction.h>
|
||||
%include <Split.h>
|
||||
%include <Account.h>
|
||||
|
||||
//Ignored because it is unimplemented
|
||||
%ignore gnc_numeric_convert_with_error;
|
||||
%include <gnc-numeric.h>
|
||||
|
||||
%include <gnc-commodity.h>
|
||||
|
||||
%include <gnc-lot.h>
|
||||
|
||||
%init %{
|
||||
|
||||
g_type_init();
|
||||
scm_init_guile();
|
||||
gnc_module_load("gnucash/engine", 0);
|
||||
gnc_module_load("gnucash/business-core-file", 0);
|
||||
|
||||
%}
|
374
src/optional/python-bindings/gnucash_core.py
Normal file
374
src/optional/python-bindings/gnucash_core.py
Normal file
@ -0,0 +1,374 @@
|
||||
# gnucash_core.py -- High level python wrapper classes for the core parts
|
||||
# of GnuCash
|
||||
#
|
||||
# Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
|
||||
# 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
|
||||
#
|
||||
# @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
|
||||
# @author Jeff Green, ParIT Worker Co-operative <jeff@parit.ca>
|
||||
|
||||
import gnucash_core_c
|
||||
|
||||
from function_class import \
|
||||
ClassFromFunctions, extract_attributes_with_prefix, \
|
||||
default_arguments_decorator, method_function_returns_instance
|
||||
|
||||
class GnuCashCoreClass(ClassFromFunctions):
|
||||
_module = gnucash_core_c
|
||||
|
||||
class GnuCashBackendException(Exception):
|
||||
def __init__(self, msg, errors):
|
||||
Exception.__init__(self, msg)
|
||||
self.errors = errors
|
||||
|
||||
class Session(GnuCashCoreClass):
|
||||
def __init__(self, book_uri=None, is_new=False):
|
||||
"""A convienent contructor that allows you to specify a book URI,
|
||||
begin the session, and load the book.
|
||||
|
||||
This can give you the power of calling
|
||||
qof_session_new, qof_session_begin, and qof_session_load all in one!
|
||||
|
||||
book_uri can be None to skip the calls to qof_session_begin and
|
||||
qof_session_load, or it can be a string like "file:/test.xac"
|
||||
|
||||
qof_session_load is only called if is_new is set to False
|
||||
|
||||
is_new is passed to qof_session_begin as the
|
||||
argument create_if_nonexistent
|
||||
|
||||
This function can raise a GnuCashBackendException. If it does,
|
||||
you don't need to cleanup and call end() and destroy(), that is handled
|
||||
for you, and the exception is raised.
|
||||
"""
|
||||
GnuCashCoreClass.__init__(self)
|
||||
if book_uri is not None:
|
||||
try:
|
||||
self.begin(book_uri, False, is_new)
|
||||
if not is_new:
|
||||
self.load()
|
||||
except GnuCashBackendException, backend_exception:
|
||||
self.end()
|
||||
self.destroy()
|
||||
raise
|
||||
|
||||
def raise_backend_errors(self, called_function="qof_session function"):
|
||||
"""Raises a GnuCashBackendException if there are outstanding
|
||||
QOF_BACKEND errors.
|
||||
|
||||
set called_function to name the function that was last called
|
||||
"""
|
||||
errors = self.pop_all_errors()
|
||||
if errors != ():
|
||||
raise GnuCashBackendException(
|
||||
"call to %s resulted in the "
|
||||
"following errors, %s" % (called_function, errors),
|
||||
errors )
|
||||
|
||||
def generate_errors(self):
|
||||
"""A generator that yeilds any outstanding QofBackend errors
|
||||
"""
|
||||
while self.get_error() is not ERR_BACKEND_NO_ERR:
|
||||
error = self.pop_error()
|
||||
yield error
|
||||
|
||||
def pop_all_errors(self):
|
||||
"""Returns any accumulated qof backend errors as a tuple
|
||||
"""
|
||||
return tuple( self.generate_errors() )
|
||||
|
||||
# STATIC METHODS
|
||||
@staticmethod
|
||||
def raise_backend_errors_after_call(function):
|
||||
"""A function decorator that results in a call to
|
||||
raise_backend_errors after execution.
|
||||
"""
|
||||
def new_function(self, *args):
|
||||
return_value = function(self, *args)
|
||||
self.raise_backend_errors(function.__name__)
|
||||
return return_value
|
||||
return new_function
|
||||
|
||||
class Book(GnuCashCoreClass): pass
|
||||
|
||||
class GncNumeric(GnuCashCoreClass):
|
||||
def __init__(self, num=0, denom=0, **kargs):
|
||||
GnuCashCoreClass.__init__(self, num, denom, **kargs)
|
||||
#if INSTANCE_ARG in kargs:
|
||||
# GnuCashCoreClass.__init__(**kargs)
|
||||
#else:
|
||||
# self.set_denom(denom) # currently undefined
|
||||
# self.set_num(num) # currently undefined
|
||||
|
||||
class GncCommodity(GnuCashCoreClass):
|
||||
def __init__(self, book, name=None, namespace=None, mnemonic=None, cusip=None, fraction=1, **kargs):
|
||||
GnuCashCoreClass.__init__(self, book, name, namespace, mnemonic, cusip, fraction, **kargs)
|
||||
|
||||
class GncCommodityTable(GnuCashCoreClass):
|
||||
def __init__(self, book, **kargs):
|
||||
GnuCashCoreClass.__init__(self, book, **kargs)
|
||||
|
||||
class GncLot(GnuCashCoreClass):
|
||||
def __init__(self, book, **kargs):
|
||||
GnuCashCoreClass.__init__(self, book, **kargs)
|
||||
|
||||
class Transaction(GnuCashCoreClass):
|
||||
_new_instance = 'xaccMallocTransaction'
|
||||
|
||||
class Split(GnuCashCoreClass):
|
||||
_new_instance = 'xaccMallocSplit'
|
||||
|
||||
class Account(GnuCashCoreClass):
|
||||
_new_instance = 'xaccMallocAccount'
|
||||
|
||||
# Session
|
||||
Session.add_constructor_and_methods_with_prefix('qof_session_', 'new')
|
||||
|
||||
def one_arg_default_none(function):
|
||||
return default_arguments_decorator(function, None, None)
|
||||
Session.decorate_functions(one_arg_default_none, "load", "save")
|
||||
|
||||
Session.decorate_functions( Session.raise_backend_errors_after_call,
|
||||
"begin", "load", "save", "end")
|
||||
Session.get_book = method_function_returns_instance(
|
||||
Session.get_book, Book )
|
||||
|
||||
Session.book = property( Session.get_book )
|
||||
|
||||
# import all of the session backend error codes into this module
|
||||
this_module_dict = globals()
|
||||
for error_name, error_value, error_name_after_prefix in \
|
||||
extract_attributes_with_prefix(gnucash_core_c, 'ERR_'):
|
||||
this_module_dict[ error_name ] = error_value
|
||||
|
||||
#Book
|
||||
Book.add_constructor_and_methods_with_prefix('qof_book_', 'new')
|
||||
Book.add_method('gnc_book_get_root_account', 'get_root_account')
|
||||
#Functions that return Account
|
||||
Book.get_root_account = method_function_returns_instance(
|
||||
Book.get_root_account, Account )
|
||||
|
||||
# GncNumeric
|
||||
GncNumeric.add_constructor_and_methods_with_prefix('gnc_numeric_', 'create')
|
||||
#Functions that return GncNumeric
|
||||
GncNumeric.same = method_function_returns_instance(
|
||||
GncNumeric.same, GncNumeric )
|
||||
GncNumeric.add = method_function_returns_instance(
|
||||
GncNumeric.add, GncNumeric )
|
||||
GncNumeric.sub = method_function_returns_instance(
|
||||
GncNumeric.sub, GncNumeric )
|
||||
GncNumeric.mul = method_function_returns_instance(
|
||||
GncNumeric.mul, GncNumeric )
|
||||
GncNumeric.div = method_function_returns_instance(
|
||||
GncNumeric.div, GncNumeric )
|
||||
GncNumeric.neg = method_function_returns_instance(
|
||||
GncNumeric.neg, GncNumeric )
|
||||
GncNumeric.abs = method_function_returns_instance(
|
||||
GncNumeric.abs, GncNumeric )
|
||||
GncNumeric.add_fixed = method_function_returns_instance(
|
||||
GncNumeric.add_fixed, GncNumeric )
|
||||
GncNumeric.sub_fixed = method_function_returns_instance(
|
||||
GncNumeric.sub_fixed, GncNumeric )
|
||||
GncNumeric.add_with_error = method_function_returns_instance(
|
||||
GncNumeric.add_with_error, GncNumeric )
|
||||
GncNumeric.sub_with_error = method_function_returns_instance(
|
||||
GncNumeric.sub_with_error, GncNumeric )
|
||||
GncNumeric.mul_with_error = method_function_returns_instance(
|
||||
GncNumeric.mul_with_error, GncNumeric )
|
||||
GncNumeric.div_with_error = method_function_returns_instance(
|
||||
GncNumeric.div_with_error, GncNumeric )
|
||||
GncNumeric.convert = method_function_returns_instance(
|
||||
GncNumeric.convert, GncNumeric )
|
||||
GncNumeric.reduce = method_function_returns_instance(
|
||||
GncNumeric.reduce, GncNumeric )
|
||||
|
||||
# GncCommodity
|
||||
GncCommodity.add_constructor_and_methods_with_prefix('gnc_commodity_', 'new')
|
||||
#Functions that return GncCommodity
|
||||
GncCommodity.clone = method_function_returns_instance(
|
||||
GncCommodity.clone, GncCommodity )
|
||||
|
||||
# GncCommodityTable
|
||||
GncCommodityTable.add_constructor_and_methods_with_prefix('gnc_commodity_table_', 'get_table')
|
||||
#Functions that return GncCommodity
|
||||
GncCommodityTable.lookup = method_function_returns_instance(
|
||||
GncCommodityTable.lookup, GncCommodity )
|
||||
GncCommodityTable.lookup_unique = method_function_returns_instance(
|
||||
GncCommodityTable.lookup_unique, GncCommodity )
|
||||
GncCommodityTable.find_full = method_function_returns_instance(
|
||||
GncCommodityTable.find_full, GncCommodity )
|
||||
GncCommodityTable.insert = method_function_returns_instance(
|
||||
GncCommodityTable.insert, GncCommodity )
|
||||
|
||||
# GncLot
|
||||
GncLot.add_constructor_and_methods_with_prefix('gnc_lot_', 'new')
|
||||
#Functions that return Account
|
||||
GncLot.get_account = method_function_returns_instance(
|
||||
GncLot.get_account, Account )
|
||||
#Functions that return Book
|
||||
GncLot.get_book = method_function_returns_instance(
|
||||
GncLot.get_book, Book )
|
||||
#Functions that return Split
|
||||
GncLot.get_earliest_split = method_function_returns_instance(
|
||||
GncLot.get_earliest_split, Split )
|
||||
GncLot.get_latest_split = method_function_returns_instance(
|
||||
GncLot.get_latest_split, Split )
|
||||
#Functions that return GncNumeric
|
||||
GncLot.get_balance = method_function_returns_instance(
|
||||
GncLot.get_balance, GncNumeric )
|
||||
#Functions that return GncLot
|
||||
GncLot.lookup = method_function_returns_instance(
|
||||
GncLot.lookup, GncLot )
|
||||
GncLot.make_default = method_function_returns_instance(
|
||||
GncLot.make_default, GncLot )
|
||||
|
||||
|
||||
# Transaction
|
||||
Transaction.add_methods_with_prefix('xaccTrans')
|
||||
#Functions that return Split
|
||||
Transaction.GetSplit = method_function_returns_instance(
|
||||
Transaction.GetSplit, Split )
|
||||
Transaction.FindSplitByAccount = method_function_returns_instance(
|
||||
Transaction.FindSplitByAccount, Split )
|
||||
#Functions that return Transaction
|
||||
Transaction.Clone = method_function_returns_instance(
|
||||
Transaction.Clone, Transaction )
|
||||
Transaction.Reverse = method_function_returns_instance(
|
||||
Transaction.Reverse, Transaction )
|
||||
Transaction.GetReversedBy = method_function_returns_instance(
|
||||
Transaction.GetReversedBy, Transaction )
|
||||
#Functions that return GncCommodity
|
||||
Transaction.GetCurrency = method_function_returns_instance(
|
||||
Transaction.GetCurrency, GncCommodity )
|
||||
#Functions that return GncNumeric
|
||||
Transaction.GetImbalance = method_function_returns_instance(
|
||||
Transaction.GetImbalance, GncNumeric )
|
||||
Transaction.GetAccountValue = method_function_returns_instance(
|
||||
Transaction.GetAccountValue, GncNumeric )
|
||||
Transaction.GetAccountAmount = method_function_returns_instance(
|
||||
Transaction.GetAccountAmount, GncNumeric )
|
||||
Transaction.GetAccountConvRate = method_function_returns_instance(
|
||||
Transaction.GetAccountConvRate, GncNumeric )
|
||||
Transaction.GetAccountBalance = method_function_returns_instance(
|
||||
Transaction.GetAccountBalance, GncNumeric )
|
||||
|
||||
# Split
|
||||
Split.add_methods_with_prefix('xaccSplit')
|
||||
#Functions that return Book
|
||||
Split.GetBook = method_function_returns_instance(
|
||||
Split.GetBook, Book )
|
||||
#Functions that return Account
|
||||
Split.GetAccount = method_function_returns_instance(
|
||||
Split.GetAccount, Account )
|
||||
#Functions that return Transaction
|
||||
Split.GetParent = method_function_returns_instance(
|
||||
Split.GetParent, Transaction )
|
||||
#Functions that return Split
|
||||
Split.Lookup = method_function_returns_instance(
|
||||
Split.Lookup, Split )
|
||||
Split.GetOtherSplit = method_function_returns_instance(
|
||||
Split.GetOtherSplit, Split )
|
||||
#Functions that return GncNumeric
|
||||
Split.GetAmount = method_function_returns_instance(
|
||||
Split.GetAmount, GncNumeric )
|
||||
Split.GetValue = method_function_returns_instance(
|
||||
Split.GetValue, GncNumeric )
|
||||
Split.GetSharePrice = method_function_returns_instance(
|
||||
Split.GetSharePrice, GncNumeric )
|
||||
Split.ConvertAmount = method_function_returns_instance(
|
||||
Split.ConvertAmount, GncNumeric )
|
||||
Split.GetBaseValue = method_function_returns_instance(
|
||||
Split.GetBaseValue, GncNumeric )
|
||||
Split.GetBalance = method_function_returns_instance(
|
||||
Split.GetBalance, GncNumeric )
|
||||
Split.GetClearedBalance = method_function_returns_instance(
|
||||
Split.GetClearedBalance, GncNumeric )
|
||||
Split.GetReconciledBalance = method_function_returns_instance(
|
||||
Split.GetReconciledBalance, GncNumeric )
|
||||
Split.VoidFormerAmount = method_function_returns_instance(
|
||||
Split.VoidFormerAmount, GncNumeric )
|
||||
Split.VoidFormerValue = method_function_returns_instance(
|
||||
Split.VoidFormerValue, GncNumeric )
|
||||
|
||||
Split.account = property( Split.GetAccount, Split.SetAccount )
|
||||
Split.parent = property( Split.GetParent, Split.SetParent )
|
||||
|
||||
# Account
|
||||
Account.add_methods_with_prefix('xaccAccount')
|
||||
Account.add_methods_with_prefix('gnc_account_')
|
||||
#Functions that return Book
|
||||
Account.get_book = method_function_returns_instance(
|
||||
Account.get_book, Book )
|
||||
#Functions that return Account
|
||||
Account.Lookup = method_function_returns_instance(
|
||||
Account.Lookup, Account )
|
||||
Account.get_parent = method_function_returns_instance(
|
||||
Account.get_parent, Account )
|
||||
Account.get_root = method_function_returns_instance(
|
||||
Account.get_root, Account )
|
||||
Account.nth_child = method_function_returns_instance(
|
||||
Account.nth_child, Account )
|
||||
Account.lookup_by_name = method_function_returns_instance(
|
||||
Account.lookup_by_name, Account )
|
||||
Account.lookup_by_full_name = method_function_returns_instance(
|
||||
Account.lookup_by_full_name, Account )
|
||||
#Functions that return Transaction
|
||||
Account.FindTransByDesc = method_function_returns_instance(
|
||||
Account.FindTransByDesc, Transaction )
|
||||
#Functions that return Split
|
||||
Account.FindSplitByDesc = method_function_returns_instance(
|
||||
Account.FindSplitByDesc, Split )
|
||||
#Functions that return GncNumeric
|
||||
Account.get_start_balance = method_function_returns_instance(
|
||||
Account.get_start_balance, GncNumeric )
|
||||
Account.get_start_cleared_balance = method_function_returns_instance(
|
||||
Account.get_start_cleared_balance, GncNumeric )
|
||||
Account.GetBalance = method_function_returns_instance(
|
||||
Account.GetBalance, GncNumeric )
|
||||
Account.GetClearedBalance = method_function_returns_instance(
|
||||
Account.GetClearedBalance, GncNumeric )
|
||||
Account.GetReconciledBalance = method_function_returns_instance(
|
||||
Account.GetReconciledBalance, GncNumeric )
|
||||
Account.GetPresentBalance = method_function_returns_instance(
|
||||
Account.GetPresentBalance, GncNumeric )
|
||||
Account.GetProjectedMinimumBalance = method_function_returns_instance(
|
||||
Account.GetProjectedMinimumBalance, GncNumeric )
|
||||
Account.GetBalanceAsOfDate = method_function_returns_instance(
|
||||
Account.GetBalanceAsOfDate, GncNumeric )
|
||||
Account.ConvertBalanceToCurrency = method_function_returns_instance(
|
||||
Account.ConvertBalanceToCurrency, GncNumeric )
|
||||
Account.ConvertBalanceToCurrencyAsOfDate = method_function_returns_instance(
|
||||
Account.ConvertBalanceToCurrencyAsOfDate, GncNumeric )
|
||||
Account.GetBalanceInCurrency = method_function_returns_instance(
|
||||
Account.GetBalanceInCurrency, GncNumeric )
|
||||
Account.GetClearedBalanceInCurrency = method_function_returns_instance(
|
||||
Account.GetClearedBalanceInCurrency, GncNumeric )
|
||||
Account.GetReconciledBalanceInCurrency = method_function_returns_instance(
|
||||
Account.GetReconciledBalanceInCurrency, GncNumeric )
|
||||
Account.GetPresentBalanceInCurrency = method_function_returns_instance(
|
||||
Account.GetPresentBalanceInCurrency, GncNumeric )
|
||||
Account.GetProjectedMinimumBalanceInCurrency = method_function_returns_instance(
|
||||
Account.GetProjectedMinimumBalanceInCurrency, GncNumeric )
|
||||
Account.GetBalanceAsOfDateInCurrency = method_function_returns_instance(
|
||||
Account.GetBalanceInCurrency, GncNumeric )
|
||||
Account.GetBalanceChangeForPeriod = method_function_returns_instance(
|
||||
Account.GetBalanceChangeForPeriod, GncNumeric )
|
||||
#Functions that return GncCommodity
|
||||
Account.GetCommodity = method_function_returns_instance(
|
||||
Account.GetCommodity, GncCommodity )
|
||||
|
||||
Account.name = property( Account.GetName, Account.SetName )
|
67
src/optional/python-bindings/timespec.i
Normal file
67
src/optional/python-bindings/timespec.i
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* timespec.i -- SWIG interface file for type translation of Timespec types
|
||||
*
|
||||
* Copyright (C) 2008 ParIT Worker Co-operative <paritinfo@parit.ca>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* @author Mark Jenkins, ParIT Worker Co-operative <mark@parit.ca>
|
||||
*/
|
||||
|
||||
// A typemap for converting python dates to Timespec in functions that
|
||||
// require Timespec as an argument
|
||||
%typemap(in) Timespec {
|
||||
PyDateTime_IMPORT;
|
||||
$1 = gnc_dmy2timespec(PyDateTime_GET_DAY($input),
|
||||
PyDateTime_GET_MONTH($input),
|
||||
PyDateTime_GET_YEAR($input) );
|
||||
}
|
||||
|
||||
// A typemap for converting python dates to Timespec *, for fuctions that
|
||||
// requires a Timespec * as an argument. BIG ASSUMPTION, the function
|
||||
// recieving this pointer is going to make a copy of the data. After the
|
||||
// function call, the memory for the Timespec used to perform this conversion
|
||||
// is going to be lost, so make damn sure that the recipiant of this pointer
|
||||
// is NOT going dereference it sometime after this function call takes place.
|
||||
//
|
||||
// As far as I know, the xaccTransSetDate[Posted|Entered|Due]TS functions
|
||||
// from Transaction.h are the only functions with Timespec * that we re
|
||||
// actually using. I have personaly verifyed in the source that the pointer
|
||||
// being produced by this typemap is being deferenced, and the data copied
|
||||
// in all three functions.
|
||||
//
|
||||
// The memory for the Timespec used for this conversion is allocated on the
|
||||
// stack. (SWIG will name the variables ts1, ts2, ts3...)
|
||||
//
|
||||
// Mark Jenkins <mark@parit.ca>
|
||||
%typemap(in) Timespec * (Timespec ts) {
|
||||
PyDateTime_IMPORT;
|
||||
ts = gnc_dmy2timespec(PyDateTime_GET_DAY($input),
|
||||
PyDateTime_GET_MONTH($input),
|
||||
PyDateTime_GET_YEAR($input) );
|
||||
$1 = &ts;
|
||||
}
|
||||
|
||||
// A typemap for converting Timespec values returned from functions to
|
||||
// python dates.
|
||||
%typemap(out) Timespec {
|
||||
int year, month, day;
|
||||
gnc_timespec2dmy($1, &day, &month, &year);
|
||||
PyDateTime_IMPORT;
|
||||
$result = PyDate_FromDate(year, month, day);
|
||||
}
|
Loading…
Reference in New Issue
Block a user