PakfireObject* self = (PakfireObject *)type->tp_alloc(type, 0);
if (self) {
self->pakfire = NULL;
- self->logger = NULL;
+
+ // Callbacks
+ self->callbacks.log = NULL;
+ self->callbacks.status = NULL;
+ self->callbacks.progress = NULL;
}
return (PyObject *)self;
}
-static void Pakfire_logging_callback(void* data, int priority, const char* file, int line,
+static void Pakfire_log_callback(void* data, int priority, const char* file, int line,
const char* fn, const char* format, va_list args) {
- PyObject* callback = (PyObject*)data;
+ struct callbacks* callbacks = (struct callbacks*)data;
// Do nothing if callback isn't set
- if (!callback)
+ if (!callbacks->log)
return;
// Translate priority to Python logging priorities
goto ERROR;
// Call the callback
- result = PyObject_CallObject(callback, tuple);
+ result = PyObject_CallObject(callbacks->log, tuple);
ERROR:
if (buffer)
Py_XDECREF(result);
}
+static void Pakfire_status_callback(void* data, const char* message) {
+ struct callbacks* callbacks = (struct callbacks*)data;
+
+ // Do nothing if callback isn't set
+ if (!callbacks->status)
+ return;
+
+ PyObject* args = NULL;
+ PyObject* result = NULL;
+
+ // Create arguments tuple
+ args = Py_BuildValue("(s)", message);
+ if (!args)
+ goto ERROR;
+
+ // Call the callback
+ result = PyObject_CallObject(callbacks->status, args);
+
+ERROR:
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+}
+
+static void Pakfire_progress_callback(void* data, int progress) {
+ struct callbacks* callbacks = (struct callbacks*)data;
+
+ // Do nothing if callback isn't set
+ if (!callbacks->progress)
+ return;
+
+ PyObject* args = NULL;
+ PyObject* result = NULL;
+
+ // Create arguments tuple
+ args = Py_BuildValue("(i)", progress);
+ if (!args)
+ goto ERROR;
+
+ // Call the callback
+ result = PyObject_CallObject(callbacks->progress, args);
+
+ERROR:
+ Py_XDECREF(args);
+ Py_XDECREF(result);
+}
+
static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) {
char* kwlist[] = { "path", "arch", "logger", "offline", "conf", "build",
- "enable_ccache", "enable_snapshot", NULL };
+ "enable_ccache", "enable_snapshot", "status_callback", "progress_callback", NULL };
const char* path = NULL;
const char* arch = NULL;
- PyObject* logger = NULL;
const char* conf = NULL;
int offline = 0;
int build = 0;
int enable_ccache = 1;
int enable_snapshot = 1;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpzppp", kwlist,
- &path, &arch, &logger, &offline, &conf, &build,
- &enable_ccache, &enable_snapshot))
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOpzpppOO", kwlist,
+ &path, &arch, &self->callbacks.log, &offline, &conf, &build,
+ &enable_ccache, &enable_snapshot, &self->callbacks.status,
+ &self->callbacks.progress))
return -1;
- // Check if logger is callable
- if (logger && !PyCallable_Check(logger)) {
+ // Check if log callback is callable
+ if (self->callbacks.log && !PyCallable_Check(self->callbacks.log)) {
PyErr_SetString(PyExc_TypeError, "logger must be callable\n");
return -1;
}
+ // Check if status callback is callable
+ if (self->callbacks.status && !PyCallable_Check(self->callbacks.status)) {
+ PyErr_SetString(PyExc_TypeError, "status callback must be callable\n");
+ return -1;
+ }
+
+ // Check if progress callback is callable
+ if (self->callbacks.progress && !PyCallable_Check(self->callbacks.progress)) {
+ PyErr_SetString(PyExc_TypeError, "progress callback must be callable\n");
+ return -1;
+ }
+
int flags = 0;
// Enable offline mode
// Configure callbacks
struct pakfire_callbacks callbacks = {
- .data = logger,
- .log = (logger) ? Pakfire_logging_callback : NULL,
+ .data = &self->callbacks,
};
+ if (self->callbacks.log) {
+ callbacks.log = Pakfire_log_callback;
+ Py_INCREF(self->callbacks.log);
+ }
+
+ if (self->callbacks.status) {
+ callbacks.status = Pakfire_status_callback;
+ Py_INCREF(self->callbacks.status);
+ }
+
+ if (self->callbacks.progress) {
+ callbacks.progress = Pakfire_progress_callback;
+ Py_INCREF(self->callbacks.progress);
+ }
+
// Create a new Pakfire instance
int r = pakfire_create(&self->pakfire, path, arch, conf, flags, &callbacks);
if (r) {
return -1;
}
- // Store a reference to the logger
- if (logger) {
- self->logger = logger;
- Py_INCREF(self->logger);
- }
-
return 0;
}
TODO This has to move into struct pakfire or something similar.
*/
- if (self->logger)
- Py_DECREF(self->logger);
+ Py_XDECREF(self->callbacks.log);
+ Py_XDECREF(self->callbacks.status);
+ Py_XDECREF(self->callbacks.progress);
#endif
Py_TYPE(self)->tp_free((PyObject *)self);