summaryrefslogtreecommitdiffstats
path: root/libreport/src/report-python
diff options
context:
space:
mode:
Diffstat (limited to 'libreport/src/report-python')
-rw-r--r--libreport/src/report-python/Makefile.am43
-rw-r--r--libreport/src/report-python/README44
-rw-r--r--libreport/src/report-python/__init__.py147
-rw-r--r--libreport/src/report-python/accountmanager.py6
-rw-r--r--libreport/src/report-python/common.h53
-rw-r--r--libreport/src/report-python/dump_dir.c264
-rw-r--r--libreport/src/report-python/io/GTKIO.py11
-rw-r--r--libreport/src/report-python/io/NewtIO.py7
-rw-r--r--libreport/src/report-python/io/TextIO.py6
-rw-r--r--libreport/src/report-python/io/__init__.py1
-rw-r--r--libreport/src/report-python/libreport-meh-test.py31
-rw-r--r--libreport/src/report-python/problem_data.c147
-rw-r--r--libreport/src/report-python/py_report_test.py7
-rw-r--r--libreport/src/report-python/pyreport.c22
-rw-r--r--libreport/src/report-python/report.c59
-rw-r--r--libreport/src/report-python/reportmodule.c95
-rw-r--r--libreport/src/report-python/run_event.c220
-rwxr-xr-xlibreport/src/report-python/test_dd_create25
-rwxr-xr-xlibreport/src/report-python/test_full27
-rwxr-xr-xlibreport/src/report-python/test_full217
-rw-r--r--libreport/src/report-python/test_problem_data21
-rw-r--r--libreport/src/report-python/test_problem_data210
-rwxr-xr-xlibreport/src/report-python/test_run_event_state13
-rwxr-xr-xlibreport/src/report-python/test_run_event_state127
-rwxr-xr-xlibreport/src/report-python/test_setroubleshoot_example18
-rwxr-xr-xlibreport/src/report-python/test_setroubleshoot_example227
26 files changed, 1348 insertions, 0 deletions
diff --git a/libreport/src/report-python/Makefile.am b/libreport/src/report-python/Makefile.am
new file mode 100644
index 00000000..c1b37596
--- /dev/null
+++ b/libreport/src/report-python/Makefile.am
@@ -0,0 +1,43 @@
+pyreportexecdir = $(pyexecdir)/report
+
+pyreportexec_PYTHON = \
+ __init__.py \
+ accountmanager.py
+
+pyreportexec_LTLIBRARIES = _pyreport.la
+
+_pyreport_la_SOURCES = \
+ reportmodule.c \
+ problem_data.c \
+ dump_dir.c \
+ run_event.c \
+ report.c \
+ common.h
+_pyreport_la_CPPFLAGS = \
+ -I$(srcdir)/../include/report -I$(srcdir)/../include \
+ -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
+ -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
+ -DPLUGINS_CONF_DIR=\"$(PLUGINS_CONF_DIR)\" \
+ -DLOCALSTATEDIR='"$(localstatedir)"' \
+ -DCONF_DIR=\"$(CONF_DIR)\" \
+ -DVAR_RUN=\"$(VAR_RUN)\" \
+ $(GLIB_CFLAGS) \
+ $(PYTHON_CFLAGS) \
+ -D_GNU_SOURCE \
+ -Wall -Wwrite-strings -Werror
+_pyreport_la_LDFLAGS = \
+ -module \
+ -avoid-version \
+ -export-symbols-regex init_pyreport
+_pyreport_la_LIBADD = \
+ ../lib/libreport.la
+
+# report compat:
+
+pyreportioexecdir = $(pyexecdir)/report/io
+
+pyreportioexec_PYTHON = \
+ io/__init__.py \
+ io/GTKIO.py \
+ io/NewtIO.py \
+ io/TextIO.py
diff --git a/libreport/src/report-python/README b/libreport/src/report-python/README
new file mode 100644
index 00000000..1c9c3a27
--- /dev/null
+++ b/libreport/src/report-python/README
@@ -0,0 +1,44 @@
+Currently (2011-05), include/report/*.h are:
+
+dump_dir.h
+event_config.h
+problem_data.h
+report.h
+run_event.h
+
+and we wrap all of them except event_config.h.
+
+Python wrappers for C types and functions declared in include/report/FOO.h
+should be implemented in corresponding FOO.c file in this directory.
+
+Their (C-level) declarations should go to common.h.
+
+Note that methods don't have to be declared in common.h:
+they can be static functions inside FOO.c, and exposed to the rest
+of the world via PyTypeObject instance. In FOO.c:
+
+static PyObject *p_method_name(PyObject *pself, PyObject *args)
+...
+static PyMethodDef p_FOO_methods[] = {
+{ "method_name", p_method_name, METH_VARARGS, NULL }
+...
+};
+PyTypeObject p_FOO_type = {
+ .tp_methods = p_FOO_methods,
+...
+};
+
+and only p_FOO_type needs to be declared in common.h.
+
+Similarly, (de)allocators, attr getters/setters also can be static functions
+and be hooked into p_FOO_type.
+
+However, non-method functions can't be static.
+
+
+File reportmodule.c contains the initialization function which should
+initialize types (p_FOO_type objects) and hook up finctions from every
+FOO.c so that they are usable from python code.
+
+Python wrappers for C constants (enums, defines) are created directly
+by reportmodule.c.
diff --git a/libreport/src/report-python/__init__.py b/libreport/src/report-python/__init__.py
new file mode 100644
index 00000000..9efd5257
--- /dev/null
+++ b/libreport/src/report-python/__init__.py
@@ -0,0 +1,147 @@
+from _pyreport import *
+
+
+#Compatibility with report package:
+
+import os
+
+SYSTEM_RELEASE_PATHS = ["/etc/system-release","/etc/redhat-release"]
+####SYSTEM_RELEASE_DEPS = ["system-release", "redhat-release"]
+
+_hardcoded_default_product = ""
+_hardcoded_default_version = ""
+
+####def getProduct_fromPRODUCT():
+#### try:
+#### import product
+#### return product.productName
+#### except:
+#### return ""
+
+####def getVersion_fromPRODUCT():
+#### try:
+#### import product
+#### return product.productVersion
+#### except:
+#### return ""
+
+####def getProduct_fromRPM():
+#### try:
+#### import rpm
+#### ts = rpm.TransactionSet()
+#### for each_dep in SYSTEM_RELEASE_DEPS:
+#### mi = ts.dbMatch('provides', each_dep)
+#### for h in mi:
+#### if h['name']:
+#### return h['name'].split("-")[0].capitalize()
+####
+#### return ""
+#### except:
+#### return ""
+
+####def getVersion_fromRPM():
+#### try:
+#### import rpm
+#### ts = rpm.TransactionSet()
+#### for each_dep in SYSTEM_RELEASE_DEPS:
+#### mi = ts.dbMatch('provides', each_dep)
+#### for h in mi:
+#### if h['version']:
+#### return str(h['version'])
+#### return ""
+#### except:
+#### return ""
+
+def getProduct_fromFILE():
+ for each_path in SYSTEM_RELEASE_PATHS:
+ try:
+ file = open(each_path, "r")
+ content = file.read()
+ if content.startswith("Red Hat Enterprise Linux"):
+ return "Red Hat Enterprise Linux"
+ if content.startswith("Fedora"):
+ return "Fedora"
+ i = content.find(" release")
+ if i > -1:
+ return content[0:i]
+ except:
+ pass
+ return ""
+
+def getVersion_fromFILE():
+ for each_path in SYSTEM_RELEASE_PATHS:
+ try:
+ file = open(each_path, "r")
+ content = file.read()
+ if content.find("Rawhide") > -1:
+ return "rawhide"
+ clist = content.split(" ")
+ i = clist.index("release")
+ return clist[i+1]
+ except:
+ pass
+ return ""
+
+def getProduct():
+ ####product = getProduct_fromPRODUCT()
+ ####if product:
+ #### return product
+ product = getProduct_fromFILE()
+ if product:
+ return product
+ ####product = getProduct_fromRPM()
+ ####if product:
+ #### return product
+ return _hardcoded_default_product
+
+def getVersion():
+ ####version = getVersion_fromPRODUCT()
+ ####if version:
+ #### return version
+ version = getVersion_fromFILE()
+ if version:
+ return version
+ ####version = getVersion_fromRPM()
+ ####if version:
+ #### return version
+ return _hardcoded_default_version
+
+def createAlertSignature(component, hashmarkername, hashvalue, summary, alertSignature):
+ pd = problem_data()
+ pd.add("component", component)
+ pd.add("hashmarkername", hashmarkername)
+ pd.add("duphash", hashvalue)
+ pd.add("reason", summary)
+ pd.add("description", alertSignature)
+ pd.add_basics()
+
+ return pd
+
+# used in anaconda / python-meh
+def createPythonUnhandledExceptionSignature(component, hashmarkername, hashvalue, summary, description, exnFileName):
+ pd = problem_data()
+ pd.add("component", component)
+ pd.add("hashmarkername", hashmarkername)
+ #cd.add("localhash", hashvalue)
+ pd.add("duphash", hashvalue)
+ pd.add("reason", summary)
+ pd.add("description", description)
+ #pd.add("product", getProduct())
+ #pd.add("version", getVersion())
+ pd.add_basics() # adds product and version + some other required field
+ # FIXME: how to handle files out of dump dir??
+ #1 = flag BIN
+ pd.add("pythonUnhandledException", exnFileName, 1)
+
+ return pd
+
+"""
+def report(cd, io_unused):
+ state = run_event_state()
+ #state.logging_callback = logfunc
+ r = state.run_event_on_problem_data(cd, "report")
+ return r
+"""
+
+def report(pd, io_unused):
+ result = report_problem(pd)
diff --git a/libreport/src/report-python/accountmanager.py b/libreport/src/report-python/accountmanager.py
new file mode 100644
index 00000000..db8ed117
--- /dev/null
+++ b/libreport/src/report-python/accountmanager.py
@@ -0,0 +1,6 @@
+"""
+ Compatibility with report package
+"""
+
+class AccountManager:
+ pass
diff --git a/libreport/src/report-python/common.h b/libreport/src/report-python/common.h
new file mode 100644
index 00000000..713aa2f2
--- /dev/null
+++ b/libreport/src/report-python/common.h
@@ -0,0 +1,53 @@
+/*
+ Copyright (C) 2009 Abrt team.
+ Copyright (C) 2009 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+
+#include "dump_dir.h"
+#include "problem_data.h"
+#include "run_event.h"
+#include "report.h"
+
+/* exception object */
+extern PyObject *ReportError;
+
+/* type objects */
+extern PyTypeObject p_problem_data_type;
+extern PyTypeObject p_dump_dir_type;
+extern PyTypeObject p_run_event_state_type;
+
+/* python objects' struct defs */
+typedef struct {
+ PyObject_HEAD
+ struct dump_dir *dd;
+} p_dump_dir;
+
+typedef struct {
+ PyObject_HEAD
+ problem_data_t *cd;
+} p_problem_data;
+
+/* module-level functions */
+/* for include/report/dump_dir.h */
+PyObject *p_dd_opendir(PyObject *module, PyObject *args);
+PyObject *p_dd_create(PyObject *module, PyObject *args);
+PyObject *p_delete_dump_dir(PyObject *pself, PyObject *args);
+/* for include/report/report.h */
+PyObject *p_report_problem_in_dir(PyObject *pself, PyObject *args);
+PyObject *p_report_problem_in_memory(PyObject *pself, PyObject *args);
+PyObject *p_report_problem(PyObject *pself, PyObject *args);
diff --git a/libreport/src/report-python/dump_dir.c b/libreport/src/report-python/dump_dir.c
new file mode 100644
index 00000000..e14e68d2
--- /dev/null
+++ b/libreport/src/report-python/dump_dir.c
@@ -0,0 +1,264 @@
+/*
+ On-disk storage of problem data
+
+ Copyright (C) 2010 Abrt team
+ Copyright (C) 2010 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+#include <structmember.h>
+
+#include <errno.h>
+#include "common.h"
+
+/*** init/cleanup ***/
+
+static PyObject *
+p_dump_dir_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ p_dump_dir *self = (p_dump_dir *)type->tp_alloc(type, 0);
+ if (self)
+ self->dd = NULL;
+ return (PyObject *)self;
+}
+
+static void
+p_dump_dir_dealloc(PyObject *pself)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ dd_close(self->dd);
+ self->dd = NULL;
+ self->ob_type->tp_free(pself);
+}
+
+//static int
+//p_dump_dir_init(PyObject *pself, PyObject *args, PyObject *kwds)
+//{
+// return 0;
+//}
+
+
+/*** methods ***/
+
+/* void dd_close(struct dump_dir *dd); */
+static PyObject *p_dd_close(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ dd_close(self->dd);
+ self->dd = NULL;
+ Py_RETURN_NONE;
+}
+
+/* void dd_delete(struct dump_dir *dd); */
+static PyObject *p_dd_delete(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+//Do we want to disallow delete() on non-opened dd?
+// if (!self->dd)
+// {
+// PyErr_SetString(ReportError, "dump dir is not open");
+// return NULL;
+// }
+ dd_delete(self->dd);
+ self->dd = NULL;
+ Py_RETURN_NONE;
+}
+
+/* int dd_exist(struct dump_dir *dd, const char *path); */
+static PyObject *p_dd_exist(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ if (!self->dd)
+ {
+ PyErr_SetString(ReportError, "dump dir is not open");
+ return NULL;
+ }
+ const char *path;
+ if (!PyArg_ParseTuple(args, "s", &path))
+ {
+ return NULL;
+ }
+ return Py_BuildValue("i", dd_exist(self->dd, path));
+}
+
+/* DIR *dd_init_next_file(struct dump_dir *dd); */
+//static PyObject *p_dd_init_next_file(PyObject *pself, PyObject *args);
+/* int dd_get_next_file(struct dump_dir *dd, char **short_name, char **full_name); */
+//static PyObject *p_dd_get_next_file(PyObject *pself, PyObject *args);
+
+/* char* dd_load_text_ext(const struct dump_dir *dd, const char *name, unsigned flags); */
+/* char* dd_load_text(const struct dump_dir *dd, const char *name); */
+static PyObject *p_dd_load_text(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ if (!self->dd)
+ {
+ PyErr_SetString(ReportError, "dump dir is not open");
+ return NULL;
+ }
+ const char *name;
+ int flags = 0;
+ if (!PyArg_ParseTuple(args, "s|i", &name, &flags))
+ {
+ return NULL;
+ }
+ char *val = dd_load_text_ext(self->dd, name, flags);
+ PyObject *obj = Py_BuildValue("s", val); /* NB: if val is NULL, obj is None */
+ free(val);
+ return obj;
+}
+
+/* void dd_save_text(struct dump_dir *dd, const char *name, const char *data); */
+static PyObject *p_dd_save_text(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ if (!self->dd)
+ {
+ PyErr_SetString(ReportError, "dump dir is not open");
+ return NULL;
+ }
+ const char *name;
+ const char *data;
+ if (!PyArg_ParseTuple(args, "ss", &name, &data))
+ {
+ return NULL;
+ }
+ dd_save_text(self->dd, name, data);
+ Py_RETURN_NONE;
+}
+
+/* void dd_save_binary(struct dump_dir *dd, const char *name, const char *data, unsigned size); */
+static PyObject *p_dd_save_binary(PyObject *pself, PyObject *args)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ if (!self->dd)
+ {
+ PyErr_SetString(ReportError, "dump dir is not open");
+ return NULL;
+ }
+ const char *name;
+ const char *data;
+ unsigned size;
+ if (!PyArg_ParseTuple(args, "ssI", &name, &data, &size))
+ {
+ return NULL;
+ }
+ dd_save_binary(self->dd, name, data, size);
+ Py_RETURN_NONE;
+}
+
+
+/*** attribute getters/setters ***/
+
+static PyObject *get_name(PyObject *pself, void *unused)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ if (self->dd)
+ return Py_BuildValue("s", self->dd->dd_dirname);
+ Py_RETURN_NONE;
+}
+
+//static PyObject *set_name(PyObject *pself, void *unused)
+//{
+// PyErr_SetString(ReportError, "dump dir name is not settable");
+// Py_RETURN_NONE;
+//}
+
+
+/*** type object ***/
+
+static PyMethodDef p_dump_dir_methods[] = {
+ /* method_name, func, flags, doc_string */
+ { "close" , p_dd_close, METH_NOARGS, NULL },
+ { "delete" , p_dd_delete, METH_NOARGS, NULL },
+ { "exist" , p_dd_exist, METH_VARARGS, NULL },
+ { "load_text" , p_dd_load_text, METH_VARARGS, NULL },
+ { "save_text" , p_dd_save_text, METH_VARARGS, NULL },
+ { "save_binary", p_dd_save_binary, METH_VARARGS, NULL },
+ { NULL }
+};
+
+static PyGetSetDef p_dump_dir_getset[] = {
+ /* attr_name, getter_func, setter_func, doc_string, void_param */
+ { (char*) "name", get_name, NULL /*set_name*/ },
+ { NULL }
+};
+
+/* Support for "dd = dd_opendir(...); if [not] dd: ..." */
+static int p_dd_is_non_null(PyObject *pself)
+{
+ p_dump_dir *self = (p_dump_dir*)pself;
+ return self->dd != NULL;
+}
+static PyNumberMethods p_dump_dir_number_methods = {
+ .nb_nonzero = p_dd_is_non_null,
+};
+
+PyTypeObject p_dump_dir_type = {
+ PyObject_HEAD_INIT(NULL)
+ .tp_name = "report.dump_dir",
+ .tp_basicsize = sizeof(p_dump_dir),
+ /* Py_TPFLAGS_BASETYPE means "can be subtyped": */
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = p_dump_dir_new,
+ .tp_dealloc = p_dump_dir_dealloc,
+ //.tp_init = p_dump_dir_init,
+ //.tp_members = p_dump_dir_members,
+ .tp_methods = p_dump_dir_methods,
+ .tp_as_number = &p_dump_dir_number_methods,
+ .tp_getset = p_dump_dir_getset,
+};
+
+
+/*** module-level functions ***/
+
+/* struct dump_dir *dd_opendir(const char *dir, int flags); */
+PyObject *p_dd_opendir(PyObject *module, PyObject *args)
+{
+ const char *dir;
+ int flags = 0;
+ if (!PyArg_ParseTuple(args, "s|i", &dir, &flags))
+ return NULL;
+ p_dump_dir *new_dd = PyObject_New(p_dump_dir, &p_dump_dir_type);
+ if (!new_dd)
+ return NULL;
+ new_dd->dd = dd_opendir(dir, flags);
+ return (PyObject*)new_dd;
+}
+
+/* struct dump_dir *dd_create(const char *dir, uid_t uid); */
+PyObject *p_dd_create(PyObject *module, PyObject *args)
+{
+ const char *dir;
+ int uid = -1;
+ if (!PyArg_ParseTuple(args, "s|i", &dir, &uid))
+ return NULL;
+ p_dump_dir *new_dd = PyObject_New(p_dump_dir, &p_dump_dir_type);
+ if (!new_dd)
+ return NULL;
+ new_dd->dd = dd_create(dir, uid, 0640);
+ return (PyObject*)new_dd;
+}
+
+/* void delete_dump_dir(const char *dirname); */
+PyObject *p_delete_dump_dir(PyObject *pself, PyObject *args)
+{
+ const char *dirname;
+ if (!PyArg_ParseTuple(args, "s", &dirname))
+ return NULL;
+ delete_dump_dir(dirname);
+ Py_RETURN_NONE;
+}
diff --git a/libreport/src/report-python/io/GTKIO.py b/libreport/src/report-python/io/GTKIO.py
new file mode 100644
index 00000000..4cc8766e
--- /dev/null
+++ b/libreport/src/report-python/io/GTKIO.py
@@ -0,0 +1,11 @@
+"""
+ Compatibility with report package
+"""
+
+class GTKIO:
+ def __init__(self, loginManager = None):
+ pass
+
+#class FailDialog():
+# def __init__(self, title, message):
+# pass
diff --git a/libreport/src/report-python/io/NewtIO.py b/libreport/src/report-python/io/NewtIO.py
new file mode 100644
index 00000000..10eae284
--- /dev/null
+++ b/libreport/src/report-python/io/NewtIO.py
@@ -0,0 +1,7 @@
+"""
+ Compatibility with report package
+"""
+
+class NewtIO:
+ def __init__(self, screen = None):
+ pass
diff --git a/libreport/src/report-python/io/TextIO.py b/libreport/src/report-python/io/TextIO.py
new file mode 100644
index 00000000..6162fb8b
--- /dev/null
+++ b/libreport/src/report-python/io/TextIO.py
@@ -0,0 +1,6 @@
+"""
+ Compatibility with report package
+"""
+
+class TextIO:
+ pass
diff --git a/libreport/src/report-python/io/__init__.py b/libreport/src/report-python/io/__init__.py
new file mode 100644
index 00000000..2ae28399
--- /dev/null
+++ b/libreport/src/report-python/io/__init__.py
@@ -0,0 +1 @@
+pass
diff --git a/libreport/src/report-python/libreport-meh-test.py b/libreport/src/report-python/libreport-meh-test.py
new file mode 100644
index 00000000..4ef24834
--- /dev/null
+++ b/libreport/src/report-python/libreport-meh-test.py
@@ -0,0 +1,31 @@
+#!/bin/env python
+
+from meh.dump import ReverseExceptionDump
+from meh.handler import *
+from meh.ui.gui import *
+
+class Config:
+ def __init__(self):
+ self.programName = "abrt"
+ self.programVersion = "2.0"
+ self.attrSkipList = []
+ self.fileList = []
+ self.config_value_one = 1
+ self.config_value_two = 2
+
+
+
+#meh.makeRHHandler("crash-test-meh", "1.0", Config())
+config = Config()
+intf = GraphicalIntf(None)
+handler = ExceptionHandler(config, intf, ReverseExceptionDump)
+handler.install(None)
+
+
+print "handler set up, about to divide by zero"
+
+zero = 0
+print 1 / zero
+
+print "should have crashed"
+
diff --git a/libreport/src/report-python/problem_data.c b/libreport/src/report-python/problem_data.c
new file mode 100644
index 00000000..9067dead
--- /dev/null
+++ b/libreport/src/report-python/problem_data.c
@@ -0,0 +1,147 @@
+/*
+ Copyright (C) 2010 Abrt team.
+ Copyright (C) 2010 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+#include <structmember.h>
+
+#include <errno.h>
+#include "common.h"
+
+static void
+p_problem_data_dealloc(PyObject *pself)
+{
+ p_problem_data *self = (p_problem_data*)pself;
+ free_problem_data(self->cd);
+ self->cd = NULL;
+ self->ob_type->tp_free(pself);
+}
+
+static PyObject *
+p_problem_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ p_problem_data *self = (p_problem_data *)type->tp_alloc(type, 0);
+ if (self)
+ self->cd = new_problem_data();
+ return (PyObject *)self;
+}
+
+//static int
+//p_problem_data_init(PyObject *pself, PyObject *args, PyObject *kwds)
+//{
+// return 0;
+//}
+
+/*
+void add_to_problem_data_ext(problem_data_t *problem_data,
+ const char *name,
+ const char *content,
+ unsigned flags);
+*/
+static PyObject *p_problem_data_add(PyObject *pself, PyObject *args)
+{
+ p_problem_data *self = (p_problem_data*)pself;
+
+ const char *name;
+ const char *content;
+ int flags = 0;
+ if (!PyArg_ParseTuple(args, "ss|i", &name, &content, &flags))
+ {
+ /* PyArg_ParseTuple raises the exception saying why it fails
+ * eg: TypeError: function takes exactly 2 arguments (1 given)
+ */
+ return NULL;
+ }
+ add_to_problem_data_ext(self->cd, name, content, flags);
+
+ /* every function returns PyObject, to return void we need to do this */
+ Py_RETURN_NONE;
+}
+
+/* struct problem_item *get_problem_data_item_or_NULL(problem_data_t *problem_data, const char *key); */
+static PyObject *p_get_problem_data_item(PyObject *pself, PyObject *args)
+{
+ p_problem_data *self = (p_problem_data*)pself;
+ const char *key;
+ if (!PyArg_ParseTuple(args, "s", &key))
+ {
+ return NULL;
+ }
+ struct problem_item *ci = get_problem_data_item_or_NULL(self->cd, key);
+ if (ci == NULL)
+ {
+ Py_RETURN_NONE;
+ }
+ return Py_BuildValue("sI", ci->content, ci->flags);
+}
+
+/* struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name); */
+static PyObject *p_create_dump_dir_from_problem_data(PyObject *pself, PyObject *args)
+{
+ p_problem_data *self = (p_problem_data*)pself;
+ const char *base_dir_name = NULL;
+ if (!PyArg_ParseTuple(args, "|s", &base_dir_name))
+ {
+ return NULL;
+ }
+ p_dump_dir *new_dd = PyObject_New(p_dump_dir, &p_dump_dir_type);
+ if (!new_dd)
+ return NULL;
+ struct dump_dir *dd = create_dump_dir_from_problem_data(self->cd, base_dir_name);
+ if (!dd)
+ {
+ PyObject_Del((PyObject*)new_dd);
+ PyErr_SetString(ReportError, "Can't create the dump dir");
+ return NULL;
+ }
+ new_dd->dd = dd;
+ return (PyObject*)new_dd;
+}
+
+static PyObject *p_add_basics_to_problem_data(PyObject *pself, PyObject *always_null)
+{
+ p_problem_data *self = (p_problem_data*)pself;
+ add_basics_to_problem_data(self->cd);
+
+ Py_RETURN_NONE;
+}
+
+
+//static PyMemberDef p_problem_data_members[] = {
+// { NULL }
+//};
+
+static PyMethodDef p_problem_data_methods[] = {
+ /* method_name, func, flags, doc_string */
+ { "add" , p_problem_data_add , METH_VARARGS },
+ { "get" , p_get_problem_data_item , METH_VARARGS },
+ { "create_dump_dir", p_create_dump_dir_from_problem_data, METH_VARARGS },
+ { "add_basics", p_add_basics_to_problem_data, METH_NOARGS },
+ { NULL }
+};
+
+PyTypeObject p_problem_data_type = {
+ PyObject_HEAD_INIT(NULL)
+ .tp_name = "report.problem_data",
+ .tp_basicsize = sizeof(p_problem_data),
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = p_problem_data_new,
+ .tp_dealloc = p_problem_data_dealloc,
+ //.tp_init = p_problem_data_init,
+ //.tp_members = p_problem_data_members,
+ .tp_methods = p_problem_data_methods,
+};
diff --git a/libreport/src/report-python/py_report_test.py b/libreport/src/report-python/py_report_test.py
new file mode 100644
index 00000000..e15044f8
--- /dev/null
+++ b/libreport/src/report-python/py_report_test.py
@@ -0,0 +1,7 @@
+import _pyreport
+
+pd = _pyreport.problem_data()
+pd.add("foo", "bar")
+pd.add("description", "python-libreport test bug")
+
+_pyreport.report(pd)
diff --git a/libreport/src/report-python/pyreport.c b/libreport/src/report-python/pyreport.c
new file mode 100644
index 00000000..0df47e78
--- /dev/null
+++ b/libreport/src/report-python/pyreport.c
@@ -0,0 +1,22 @@
+/*
+ Copyright (C) 2009 Abrt team.
+ Copyright (C) 2009 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "common.h"
+
+/* struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data, const char *base_dir_name); */
diff --git a/libreport/src/report-python/report.c b/libreport/src/report-python/report.c
new file mode 100644
index 00000000..0bdd4076
--- /dev/null
+++ b/libreport/src/report-python/report.c
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2010 Abrt team.
+ Copyright (C) 2010 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+
+#include "common.h"
+
+/* C: int report_problem_in_dir(const char *dirname, int flags); */
+PyObject *p_report_problem_in_dir(PyObject *pself, PyObject *args)
+{
+ const char *dirname;
+ int flags;
+ if (!PyArg_ParseTuple(args, "si", &dirname, &flags))
+ {
+ return NULL;
+ }
+ int r = report_problem_in_dir(dirname, flags);
+ return Py_BuildValue("i", r);
+}
+
+/* C: int report_problem_in_memory(problem_data_t *pd, int flags); */
+PyObject *p_report_problem_in_memory(PyObject *pself, PyObject *args)
+{
+ p_problem_data *pd;
+ int flags;
+ if (!PyArg_ParseTuple(args, "O!i", &p_problem_data_type, &pd, &flags))
+ {
+ return NULL;
+ }
+ int r = report_problem_in_memory(pd->cd, flags);
+ return Py_BuildValue("i", r);
+}
+
+/* C: int report_problem(problem_data_t *pd); */
+PyObject *p_report_problem(PyObject *pself, PyObject *args)
+{
+ p_problem_data *pd;
+ if (!PyArg_ParseTuple(args, "O!", &p_problem_data_type, &pd))
+ {
+ return NULL;
+ }
+ int r = report_problem(pd->cd);
+ return Py_BuildValue("i", r);
+}
diff --git a/libreport/src/report-python/reportmodule.c b/libreport/src/report-python/reportmodule.c
new file mode 100644
index 00000000..539c66aa
--- /dev/null
+++ b/libreport/src/report-python/reportmodule.c
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2010 Abrt team.
+ Copyright (C) 2010 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+
+#include "common.h"
+
+PyObject *ReportError;
+
+static PyMethodDef module_methods[] = {
+ /* method_name, func, flags, doc_string */
+ /* for include/report/dump_dir.h */
+ { "dd_opendir" , p_dd_opendir , METH_VARARGS },
+ { "dd_create" , p_dd_create , METH_VARARGS },
+ { "delete_dump_dir" , p_delete_dump_dir , METH_VARARGS },
+ /* for include/report/report.h */
+ { "report_problem_in_dir" , p_report_problem_in_dir , METH_VARARGS },
+ { "report_problem_in_memory" , p_report_problem_in_memory, METH_VARARGS },
+ { "report_problem" , p_report_problem , METH_VARARGS },
+ { NULL }
+};
+
+#ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
+#define PyMODINIT_FUNC void
+#endif
+PyMODINIT_FUNC
+init_pyreport(void)
+{
+ if (PyType_Ready(&p_problem_data_type) < 0)
+ {
+ printf("PyType_Ready(&p_problem_data_type) < 0\n");
+ return;
+ }
+ if (PyType_Ready(&p_dump_dir_type) < 0)
+ {
+ printf("PyType_Ready(&p_dump_dir_type) < 0\n");
+ return;
+ }
+ if (PyType_Ready(&p_run_event_state_type) < 0)
+ {
+ printf("PyType_Ready(&p_run_event_state_type) < 0\n");
+ return;
+ }
+
+ PyObject *m = Py_InitModule("_pyreport", module_methods);
+ //m = Py_InitModule3("_pyreport", module_methods, "Python wrapper for libreport");
+ if (!m)
+ {
+ printf("m == NULL\n");
+ return;
+ }
+
+ /* init the exception object */
+ ReportError = PyErr_NewException((char*) "_pyreport.error", NULL, NULL);
+ Py_INCREF(ReportError);
+ PyModule_AddObject(m, "error", ReportError);
+
+ /* init type objects and constants */
+ /* for include/report/problem_data.h */
+ Py_INCREF(&p_problem_data_type);
+ PyModule_AddObject(m, "problem_data", (PyObject *)&p_problem_data_type);
+ PyModule_AddObject(m, "CD_FLAG_BIN" , Py_BuildValue("i", CD_FLAG_BIN ));
+ PyModule_AddObject(m, "CD_FLAG_TXT" , Py_BuildValue("i", CD_FLAG_TXT ));
+ PyModule_AddObject(m, "CD_FLAG_ISEDITABLE" , Py_BuildValue("i", CD_FLAG_ISEDITABLE ));
+ PyModule_AddObject(m, "CD_FLAG_ISNOTEDITABLE", Py_BuildValue("i", CD_FLAG_ISNOTEDITABLE));
+ /* for include/report/dump_dir.h */
+ Py_INCREF(&p_dump_dir_type);
+ PyModule_AddObject(m, "dump_dir", (PyObject *)&p_dump_dir_type);
+ PyModule_AddObject(m, "DD_FAIL_QUIETLY_ENOENT" , Py_BuildValue("i", DD_FAIL_QUIETLY_ENOENT ));
+ PyModule_AddObject(m, "DD_FAIL_QUIETLY_EACCES" , Py_BuildValue("i", DD_FAIL_QUIETLY_EACCES ));
+ PyModule_AddObject(m, "DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE", Py_BuildValue("i", DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE));
+ /* for include/report/run_event.h */
+ Py_INCREF(&p_run_event_state_type);
+ PyModule_AddObject(m, "run_event_state", (PyObject *)&p_run_event_state_type);
+ /* for include/report/report.h */
+ PyModule_AddObject(m, "LIBREPORT_NOWAIT" , Py_BuildValue("i", LIBREPORT_NOWAIT ));
+ PyModule_AddObject(m, "LIBREPORT_WAIT" , Py_BuildValue("i", LIBREPORT_WAIT ));
+ PyModule_AddObject(m, "LIBREPORT_ANALYZE" , Py_BuildValue("i", LIBREPORT_ANALYZE ));
+ PyModule_AddObject(m, "LIBREPORT_RELOAD_DATA", Py_BuildValue("i", LIBREPORT_RELOAD_DATA));
+}
diff --git a/libreport/src/report-python/run_event.c b/libreport/src/report-python/run_event.c
new file mode 100644
index 00000000..50e3794e
--- /dev/null
+++ b/libreport/src/report-python/run_event.c
@@ -0,0 +1,220 @@
+/*
+ Copyright (C) 2010 Abrt team.
+ Copyright (C) 2010 RedHat inc.
+
+ 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <Python.h>
+#include <structmember.h>
+
+#include <errno.h>
+#include "common.h"
+#include "problem_data.h"
+#include "run_event.h"
+
+typedef struct {
+ PyObject_HEAD
+ struct run_event_state *state;
+ PyObject *post_run_callback;
+ PyObject *logging_callback;
+} p_run_event_state;
+
+
+/*** init/cleanup ***/
+
+static int post_run_callback(const char *dump_dir_name, void *param);
+static char *logging_callback(char *log_line, void *param);
+
+static PyObject *p_run_event_state_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ p_run_event_state *self = (p_run_event_state *)type->tp_alloc(type, 0);
+ if (self)
+ {
+ self->state = new_run_event_state();
+ self->state->post_run_callback = post_run_callback;
+ self->state->logging_callback = logging_callback;
+ self->state->post_run_param = self;
+ self->state->logging_param = self;
+ }
+ return (PyObject *)self;
+}
+
+static void p_run_event_state_dealloc(PyObject *pself)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ free_run_event_state(self->state);
+ self->state = NULL;
+ Py_XDECREF(self->post_run_callback);
+ self->post_run_callback = NULL;
+ Py_XDECREF(self->logging_callback);
+ self->logging_callback = NULL;
+ self->ob_type->tp_free(pself);
+}
+
+//static int
+//p_run_event_state_init(PyObject *pself, PyObject *args, PyObject *kwds)
+//{
+// return 0;
+//}
+
+
+/*** methods ***/
+
+/* First, C-level callback helpers for run_event_on_FOO(): */
+static int post_run_callback(const char *dump_dir_name, void *param)
+{
+ PyObject *obj = (PyObject*)param;
+ PyObject *ret = PyObject_CallMethod(obj, (char*) "post_run_callback", (char*) "(s)", dump_dir_name);
+ int r = 0;
+ if (ret)
+ {
+ r = PyInt_AsLong(ret);
+ Py_DECREF(ret);
+ }
+ // TODO: handle exceptions: if (PyErr_Occurred()) ...
+ return r;
+}
+static char *logging_callback(char *log_line, void *param)
+{
+ PyObject *obj = (PyObject*)param;
+ PyObject *ret = PyObject_CallMethod(obj, (char*) "logging_callback", (char*) "(s)", log_line);
+ Py_XDECREF(ret);
+ // TODO: handle exceptions: if (PyErr_Occurred()) ...
+ return log_line; /* signaling to caller that we didnt consume the string */
+}
+
+/* int run_event_on_dir_name(struct run_event_state *state, const char *dump_dir_name, const char *event); */
+static PyObject *p_run_event_on_dir_name(PyObject *pself, PyObject *args)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ const char *dump_dir_name;
+ const char *event;
+ if (!PyArg_ParseTuple(args, "ss", &dump_dir_name, &event))
+ {
+ return NULL;
+ }
+ int r = run_event_on_dir_name(self->state, dump_dir_name, event);
+ PyObject *obj = Py_BuildValue("i", r);
+ return obj;
+}
+
+/* int run_event_on_problem_data(struct run_event_state *state, problem_data_t *data, const char *event); */
+static PyObject *p_run_event_on_problem_data(PyObject *pself, PyObject *args)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ p_problem_data *cd;
+ const char *event;
+ if (!PyArg_ParseTuple(args, "O!s", &p_problem_data_type, &cd, &event))
+ {
+ return NULL;
+ }
+ int r = run_event_on_problem_data(self->state, cd->cd, event);
+ PyObject *obj = Py_BuildValue("i", r);
+ return obj;
+}
+
+/* TODO: char *list_possible_events(struct dump_dir *dd, const char *dump_dir_name, const char *pfx); */
+
+
+/*** attribute getters/setters ***/
+
+static PyObject *get_post_run_callback(PyObject *pself, void *unused)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ if (self->post_run_callback)
+ {
+ Py_INCREF(self->post_run_callback);
+ return self->post_run_callback;
+ }
+ Py_RETURN_NONE;
+}
+
+static PyObject *get_logging_callback(PyObject *pself, void *unused)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ if (self->logging_callback)
+ {
+ Py_INCREF(self->logging_callback);
+ return self->logging_callback;
+ }
+ Py_RETURN_NONE;
+}
+
+static int set_post_run_callback(PyObject *pself, PyObject *callback, void *unused)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+//WRONG: we aren't a Python function, calling convention is different
+// PyObject *callback;
+// if (!PyArg_ParseTuple(args, "O", &callback))
+// return -1;
+ if (!PyCallable_Check(callback))
+ {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+ return -1;
+ }
+ Py_INCREF(callback);
+ Py_XDECREF(self->post_run_callback);
+ self->post_run_callback = callback;
+ return 0;
+}
+
+static int set_logging_callback(PyObject *pself, PyObject *callback, void *unused)
+{
+ p_run_event_state *self = (p_run_event_state*)pself;
+ if (!PyCallable_Check(callback))
+ {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+ return -1;
+ }
+ Py_INCREF(callback);
+ Py_XDECREF(self->logging_callback);
+ self->logging_callback = callback;
+ return 0;
+}
+
+
+/*** type object ***/
+
+//static PyMemberDef p_run_event_state_members[] = {
+// { NULL }
+//};
+
+static PyMethodDef p_run_event_state_methods[] = {
+ /* method_name, func, flags, doc_string */
+ { "run_event_on_dir_name" , p_run_event_on_dir_name , METH_VARARGS },
+ { "run_event_on_problem_data", p_run_event_on_problem_data, METH_VARARGS },
+ { NULL }
+};
+
+static PyGetSetDef p_run_event_state_getset[] = {
+ /* attr_name, getter_func, setter_func, doc_string, void_param */
+ { (char*) "post_run_callback", get_post_run_callback, set_post_run_callback },
+ { (char*) "logging_callback" , get_logging_callback , set_logging_callback },
+ { NULL }
+};
+
+PyTypeObject p_run_event_state_type = {
+ PyObject_HEAD_INIT(NULL)
+ .tp_name = "report.run_event_state",
+ .tp_basicsize = sizeof(p_run_event_state),
+ /* Py_TPFLAGS_BASETYPE means "can be subtyped": */
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = p_run_event_state_new,
+ .tp_dealloc = p_run_event_state_dealloc,
+ //.tp_init = p_run_event_state_init,
+ //.tp_members = p_run_event_state_members,
+ .tp_methods = p_run_event_state_methods,
+ .tp_getset = p_run_event_state_getset,
+};
diff --git a/libreport/src/report-python/test_dd_create b/libreport/src/report-python/test_dd_create
new file mode 100755
index 00000000..4da29b11
--- /dev/null
+++ b/libreport/src/report-python/test_dd_create
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+from report import *
+
+dd = dd_create("testdir")
+print dd
+
+if dd:
+ print "dd is nonzero"
+else:
+ print "dd is zero"
+
+print "name:", dd.name
+print "closing"
+dd.close()
+
+if dd:
+ print "dd is nonzero"
+else:
+ print "dd is zero"
+
+# Should fail here
+dd.name = "qwe"
+
+print "Done"
diff --git a/libreport/src/report-python/test_full b/libreport/src/report-python/test_full
new file mode 100755
index 00000000..107c4857
--- /dev/null
+++ b/libreport/src/report-python/test_full
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import sys
+from report import *
+
+def run_event_on_problem_data(cd, event, log_function = None):
+ dd = cd.create_dump_dir("/tmp")
+ dir_name = dd.name
+ print "Created dump_dir:", dir_name
+ dd.close()
+ run_state = run_event_state()
+ if log_function: # maybe if callable(log_function)?
+ run_state.logging_callback = log_function
+ print "Running event:", event
+ r = run_state.run_event_on_dir_name(dir_name, event)
+ print "Deleting:", dir_name
+ delete_dump_dir(dir_name)
+ return r;
+
+def log_function(line):
+ print "LOG:", line
+
+cd = problem_data()
+cd.add("foo", "bar")
+cd.add("analyzer", "baz", CD_FLAG_ISNOTEDITABLE)
+r = run_event_on_problem_data(cd, "post-create", log_function)
+print "Result:", r
diff --git a/libreport/src/report-python/test_full2 b/libreport/src/report-python/test_full2
new file mode 100755
index 00000000..e6cfd4d9
--- /dev/null
+++ b/libreport/src/report-python/test_full2
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import sys
+from report import *
+
+def log_function(line):
+ print "LOG:", line
+
+cd = problem_data()
+cd.add("foo", "bar")
+cd.add("analyzer", "baz", CD_FLAG_ISNOTEDITABLE)
+
+st = run_event_state()
+st.logging_callback = log_function
+r = st.run_event_on_problem_data(cd, "post-create")
+
+print "Result:", r
diff --git a/libreport/src/report-python/test_problem_data b/libreport/src/report-python/test_problem_data
new file mode 100644
index 00000000..16f1f9ae
--- /dev/null
+++ b/libreport/src/report-python/test_problem_data
@@ -0,0 +1,21 @@
+#!/usr/bin/python
+
+from report import *
+
+cd = problem_data()
+cd.add("foo", "bar")
+
+dd = cd.create_dump_dir()
+
+if dd:
+ print "dd is nonzero"
+else:
+ print "dd is zero"
+
+print "closing"
+dd.close()
+
+if dd:
+ print "dd is nonzero"
+else:
+ print "dd is zero"
diff --git a/libreport/src/report-python/test_problem_data2 b/libreport/src/report-python/test_problem_data2
new file mode 100644
index 00000000..3d3692b9
--- /dev/null
+++ b/libreport/src/report-python/test_problem_data2
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+
+from report import *
+
+cd = problem_data()
+cd.add("foo", "bar")
+
+print "foo:", cd.get("foo")
+print "nonexistent:", cd.get("nonexistent")
+print "done"
diff --git a/libreport/src/report-python/test_run_event_state b/libreport/src/report-python/test_run_event_state
new file mode 100755
index 00000000..3e391407
--- /dev/null
+++ b/libreport/src/report-python/test_run_event_state
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+from report import *
+
+def func():
+ return 0
+
+res = run_event_state()
+print res
+print res.post_run_callback
+res.post_run_callback = func
+res.logging_callback = func
+print res.post_run_callback
diff --git a/libreport/src/report-python/test_run_event_state1 b/libreport/src/report-python/test_run_event_state1
new file mode 100755
index 00000000..6c3584fe
--- /dev/null
+++ b/libreport/src/report-python/test_run_event_state1
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import sys
+from report import *
+
+def post_run_callback(dump_dir_name):
+ return 0
+
+def logging_callback(line):
+ print "LOG:", line
+ return
+
+res = run_event_state()
+res.post_run_callback = post_run_callback
+res.logging_callback = logging_callback
+
+dd = dd_create("testdir")
+if not dd:
+ sys.exit(1)
+dd.save_text("analyzer", "foo")
+dd.close()
+
+res.run_event_on_dir_name("testdir", "post-create")
+
+dd = dd_opendir("testdir")
+dd.delete()
+dd.close()
diff --git a/libreport/src/report-python/test_setroubleshoot_example b/libreport/src/report-python/test_setroubleshoot_example
new file mode 100755
index 00000000..74428f16
--- /dev/null
+++ b/libreport/src/report-python/test_setroubleshoot_example
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+
+import report
+import report.io
+import report.io.GTKIO
+import report.accountmanager
+
+accounts = report.accountmanager.AccountManager()
+
+signature = report.createAlertSignature("selinux-policy",
+ "setroubleshoot",
+ "self.siginfo.get_hash()",
+ "self.summary",
+ "content")
+
+rc = report.report(signature, report.io.GTKIO.GTKIO(accounts))
+
+print "rc:", rc
diff --git a/libreport/src/report-python/test_setroubleshoot_example2 b/libreport/src/report-python/test_setroubleshoot_example2
new file mode 100755
index 00000000..b712cda7
--- /dev/null
+++ b/libreport/src/report-python/test_setroubleshoot_example2
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+import report
+import report.io
+import report.io.GTKIO
+import report.accountmanager
+
+accounts = report.accountmanager.AccountManager()
+
+signature = report.createAlertSignature("selinux-policy",
+ "setroubleshoot",
+ "self.siginfo.get_hash()",
+ "self.summary",
+ "content")
+
+# Won't send log anywhere:
+#rc = report.report(signature, report.io.GTKIO.GTKIO(accounts))
+
+# report.report() + logging:
+def logging_callback(line):
+ print "LOG:", line
+ return
+state = report.run_event_state()
+state.logging_callback = logging_callback
+rc = state.run_event_on_problem_data(signature, "report")
+
+print "rc:", rc