// Callbacks
self->callbacks.log = NULL;
self->callbacks.confirm = NULL;
- self->callbacks.status = NULL;
- self->callbacks.progress = NULL;
}
return (PyObject *)self;
return r;
}
-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",
pakfire_unref(self->pakfire);
}
- // Free callbacks
- Py_XDECREF(self->callbacks.status);
- Py_XDECREF(self->callbacks.progress);
-
Py_TYPE(self)->tp_free((PyObject *)self);
}
return obj;
}
+static void Pakfire_status_callback(struct pakfire* pakfire, void* data,
+ int progress, const char* status) {
+ PyObject* callback = (PyObject*)data;
+
+ // Do not attempt to call nothing
+ if (!callback)
+ return;
+
+ // Compile arguments
+ PyObject* args = Py_BuildValue("(is)", progress, status);
+ if (!args)
+ return;
+
+ // Call the callback
+ PyObject* result = PyObject_CallObject(callback, args);
+
+ Py_XDECREF(result);
+ Py_DECREF(args);
+}
+
static int convert_packages(PyObject* object, void* address) {
char*** packages = (char***)address;
"without_recommended",
"allow_uninstall",
"allow_downgrade",
+ "status_callback",
NULL
};
char** packages = NULL;
int allow_uninstall = 0;
int allow_downgrade = 0;
int solver_flags = 0;
+ PyObject* status_callback = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$ppp", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$pppO", kwlist,
convert_packages, &packages, &without_recommended, &allow_uninstall,
- &allow_downgrade))
+ &allow_downgrade, &status_callback))
+ return NULL;
+
+ // Check if callback is callable
+ if (status_callback && !PyCallable_Check(status_callback)) {
+ PyErr_SetString(PyExc_TypeError, "status_callback must be callable");
return NULL;
+ }
// Do not install recommended packages
if (without_recommended)
solver_flags |= PAKFIRE_REQUEST_ALLOW_DOWNGRADE;
// Run pakfire_install
- int r = pakfire_install(self->pakfire, solver_flags, (const char**)packages, NULL, 0, NULL);
+ int r = pakfire_install(self->pakfire, solver_flags, (const char**)packages,
+ NULL, 0, NULL, Pakfire_status_callback, status_callback);
if (r)
PyErr_SetFromErrno(PyExc_OSError);
char* kwlist[] = {
"packages",
"keep_dependencies",
+ "status_callback",
NULL
};
char** packages = NULL;
int keep_dependencies = 0;
int flags = 0;
+ PyObject* status_callback = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$p", kwlist,
- convert_packages, &packages, &keep_dependencies))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$pO", kwlist,
+ convert_packages, &packages, &keep_dependencies, &status_callback))
return NULL;
+ // Check if callback is callable
+ if (status_callback && !PyCallable_Check(status_callback)) {
+ PyErr_SetString(PyExc_TypeError, "status_callback must be callable");
+ return NULL;
+ }
+
if (keep_dependencies)
flags |= PAKFIRE_REQUEST_KEEP_DEPS;
// Run pakfire_erase
- int r = pakfire_erase(self->pakfire, 0, (const char**)packages, NULL, flags, NULL);
+ int r = pakfire_erase(self->pakfire, 0, (const char**)packages, NULL, flags, NULL,
+ Pakfire_status_callback, status_callback);
if (r)
PyErr_SetFromErrno(PyExc_OSError);
"excludes",
"allow_uninstall",
"allow_downgrade",
+ "status_callback",
NULL
};
char** packages = NULL;
int allow_uninstall = 0;
int allow_downgrade = 0;
int solver_flags = 0;
+ PyObject* status_callback = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&pp", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&ppO", kwlist,
convert_packages, &packages, convert_packages, &excludes,
- &allow_uninstall, &allow_downgrade))
+ &allow_uninstall, &allow_downgrade, &status_callback))
+ return NULL;
+
+ // Check if callback is callable
+ if (status_callback && !PyCallable_Check(status_callback)) {
+ PyErr_SetString(PyExc_TypeError, "status_callback must be callable");
return NULL;
+ }
// Can the solver uninstall packages?
if (allow_uninstall)
// Run pakfire_update
int r = pakfire_update(self->pakfire, solver_flags, (const char**)packages,
- (const char**)excludes, 0, NULL);
+ (const char**)excludes, 0, NULL, Pakfire_status_callback, status_callback);
if (r)
PyErr_SetFromErrno(PyExc_OSError);
}
static PyObject* Pakfire_sync(PakfireObject* self, PyObject* args, PyObject* kwargs) {
- char* kwlist[] = {"keep_orphaned", NULL};
+ char* kwlist[] = {
+ "keep_orphaned",
+ "status_callback",
+ NULL,
+ };
int keep_orphaned = 0;
int flags = 0;
+ PyObject* status_callback = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p", kwlist, &keep_orphaned))
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$pO", kwlist,
+ &keep_orphaned, &status_callback))
return NULL;
if (keep_orphaned)
flags |= PAKFIRE_REQUEST_KEEP_ORPHANED;
- int r = pakfire_sync(self->pakfire, 0, flags, NULL);
+ int r = pakfire_sync(self->pakfire, 0, flags, NULL,
+ Pakfire_status_callback, status_callback);
if (r) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
struct callbacks {
PyObject* log;
PyObject* confirm;
- PyObject* status;
- PyObject* progress;
} callbacks;
} PakfireObject;
};
// Install the package into the build environment
- r = pakfire_install(pakfire, 0, packages, NULL, 0, NULL);
+ r = pakfire_install(pakfire, 0, packages, NULL, 0, NULL, NULL, NULL);
if (r) {
ERROR(pakfire, "Could not install %s\n", path);
goto ERROR;
const char* message, const char* question);
void pakfire_set_confirm_callback(struct pakfire* pakfire,
pakfire_confirm_callback callback, void* data);
+typedef void (*pakfire_status_callback)(struct pakfire* pakfire, void* data,
+ int progress, const char* status);
int pakfire_create(struct pakfire** pakfire, const char* path, const char* arch,
const char* conf, int flags, pakfire_log_callback log_callback, void* log_data);
// Install/Erase/Update
int pakfire_install(struct pakfire* pakfire, int solver_flags, const char** packages,
- const char** locks, int job_flags, int* changed);
+ const char** locks, int job_flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data);
int pakfire_erase(struct pakfire* pakfire, int solver_flags, const char** packages,
- const char** locks, int job_flags, int* changed);
+ const char** locks, int job_flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data);
int pakfire_update(struct pakfire* pakfire, int solver_flags, const char** packages,
- const char** locks, int jobs_flags, int* changed);
+ const char** locks, int jobs_flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data);
// Check
// Sync
-int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags, int* changed);
+int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data);
#ifdef PAKFIRE_PRIVATE
int pakfire_is_mountpoint(struct pakfire* pakfire, const char* path);
int pakfire_confirm(struct pakfire* pakfire, const char* message, const char* question);
-void pakfire_call_status_callback(struct pakfire* pakfire, const char* message, ...);
-void pakfire_call_progress_callback(struct pakfire* pakfire, int progress);
gpgme_ctx_t pakfire_get_gpgctx(struct pakfire* pakfire);
size_t pakfire_transaction_count(struct pakfire_transaction* transaction);
char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t width);
+void pakfire_transaction_set_status_callback(
+ struct pakfire_transaction* transaction, pakfire_status_callback callback, void* data);
+
int pakfire_transaction_run(struct pakfire_transaction* transaction);
int pakfire_transaction_download(struct pakfire_transaction* transaction);
#include <solv/solver.h>
-
int pakfire_transaction_create(struct pakfire_transaction** transaction,
struct pakfire* pakfire, Solver* solver);
// Confirm
pakfire_confirm_callback confirm;
void* confirm_data;
-
- // Status
- void (*status)(void* data, const char* message);
- void* status_data;
-
- // Progress
- void (*progress)(void* data, int progress);
- void* progress_data;
-
- // Speed
- void (*speed)(void* data, const char* speed);
- void* speed_data;
} callbacks;
// Logging
unlink(pakfire->lock_path);
}
-void pakfire_call_status_callback(struct pakfire* pakfire, const char* message, ...) {
- char* buffer = NULL;
- va_list args;
- int r;
-
- // Do nothing if call isn't set
- if (!pakfire->callbacks.status)
- return;
-
- // Format the message
- va_start(args, message);
- r = vasprintf(&buffer, message, args);
- va_end(args);
-
- if (r < 0)
- return;
-
- // Call the callback
- pakfire->callbacks.status(pakfire->callbacks.status_data, buffer);
-
- // Cleanup
- if (buffer)
- free(buffer);
-}
-
-void pakfire_call_progress_callback(struct pakfire* pakfire, int progress) {
- // Do nothing if call isn't set
- if (!pakfire->callbacks.progress)
- return;
-
- pakfire->callbacks.progress(pakfire->callbacks.progress_data, progress);
-}
-
const char* pakfire_get_keystore_path(struct pakfire* pakfire) {
return pakfire->keystore_path;
}
static int pakfire_perform_transaction(struct pakfire* pakfire, int solver_flags,
int (*action)(struct pakfire_request* request, const char* what, int flags),
- const char** packages, const char** locks, int job_flags, int* changed) {
+ const char** packages, const char** locks, int job_flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data) {
struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
struct pakfire_problem** problems = NULL;
if (changed)
*changed = pakfire_transaction_count(transaction);
+ // Set status callback
+ if (status_callback)
+ pakfire_transaction_set_status_callback(
+ transaction, status_callback, status_callback_data);
+
// Run the transaction
r = pakfire_transaction_run(transaction);
if (r)
}
PAKFIRE_EXPORT int pakfire_install(struct pakfire* pakfire, int solver_flags,
- const char** packages, const char** locks, int flags, int* changed) {
+ const char** packages, const char** locks, int flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data) {
return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_install,
- packages, locks, flags, changed);
+ packages, locks, flags, changed, status_callback, status_callback_data);
}
PAKFIRE_EXPORT int pakfire_erase(struct pakfire* pakfire, int solver_flags,
- const char** packages, const char** locks, int flags, int* changed) {
+ const char** packages, const char** locks, int flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data) {
return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_erase,
- packages, locks, flags, changed);
+ packages, locks, flags, changed, status_callback, status_callback_data);
}
static int pakfire_perform_transaction_simple(struct pakfire* pakfire, int solver_flags,
int (*action)(struct pakfire_request* request, int flags),
- int job_flags, int* changed) {
+ int job_flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data) {
struct pakfire_request* request = NULL;
struct pakfire_transaction* transaction = NULL;
struct pakfire_problem** problems = NULL;
if (changed)
*changed = pakfire_transaction_count(transaction);
+ // Set status callback
+ if (status_callback)
+ pakfire_transaction_set_status_callback(
+ transaction, status_callback, status_callback_data);
+
// Run the transaction
r = pakfire_transaction_run(transaction);
if (r)
}
PAKFIRE_EXPORT int pakfire_update(struct pakfire* pakfire, int solver_flags,
- const char** packages, const char** locks, int flags, int* changed) {
+ const char** packages, const char** locks, int flags, int* changed,
+ pakfire_status_callback status_callback, void* status_callback_data) {
// If no packages are being passed, we will try to update everything
// XXX add locks
if (!packages)
return pakfire_perform_transaction_simple(
- pakfire, solver_flags, pakfire_request_update_all, flags, changed);
+ pakfire, solver_flags, pakfire_request_update_all, flags, changed,
+ status_callback, status_callback_data);
return pakfire_perform_transaction(pakfire, solver_flags, pakfire_request_update,
- packages, locks, flags, changed);
+ packages, locks, flags, changed, status_callback, status_callback_data);
}
static int pakfire_verify(struct pakfire* pakfire, int *changed) {
- return pakfire_perform_transaction_simple(pakfire, 0, pakfire_request_verify, 0, changed);
+ return pakfire_perform_transaction_simple(pakfire, 0, pakfire_request_verify,
+ 0, changed, NULL, NULL);
}
PAKFIRE_EXPORT int pakfire_check(struct pakfire* pakfire) {
return r;
}
-PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags, int* changed) {
+PAKFIRE_EXPORT int pakfire_sync(struct pakfire* pakfire, int solver_flags, int flags,
+ int* changed, pakfire_status_callback status_callback, void* status_callback_data) {
return pakfire_perform_transaction_simple(pakfire, solver_flags,
- pakfire_request_sync, flags, changed);
+ pakfire_request_sync, flags, changed, status_callback, status_callback_data);
}
// Build Stuff
int changed = 0;
// Install everything
- r = pakfire_install(pakfire, 0, (const char**)packages, NULL, 0, &changed);
+ r = pakfire_install(pakfire, 0, (const char**)packages, NULL, 0, &changed, NULL, NULL);
if (r) {
ERROR(pakfire, "Could not install build dependencies: %m\n");
goto ERROR;
*snapshot_needs_update = 1;
// Update everything
- r = pakfire_sync(pakfire, 0, 0, &changed);
+ r = pakfire_sync(pakfire, 0, 0, &changed, NULL, NULL);
if (r) {
ERROR(pakfire, "Could not update packages: %m\n");
goto ERROR;
struct pakfire_package** packages;
size_t num;
size_t progress;
+
+ // Callbacks
+ struct pakfire_transaction_callbacks {
+ // Status
+ pakfire_status_callback status;
+ void* status_data;
+ } callbacks;
};
enum pakfire_actions {
return NULL;
}
+void pakfire_transaction_set_status_callback(struct pakfire_transaction* transaction,
+ pakfire_status_callback callback, void* data) {
+ transaction->callbacks.status = callback;
+ transaction->callbacks.status_data = data;
+}
+
static int pakfire_transaction_get_progress(struct pakfire_transaction* transaction) {
return transaction->progress * 100 / transaction->num;
}
+static void pakfire_transaction_status(struct pakfire_transaction* transaction,
+ const char* message, ...) {
+ char* buffer = NULL;
+ va_list args;
+ int r;
+
+ // Do nothing if callback isn't set
+ if (!transaction->callbacks.status)
+ return;
+
+ // Format the message
+ if (message) {
+ va_start(args, message);
+ r = vasprintf(&buffer, message, args);
+ va_end(args);
+
+ if (r < 0)
+ return;
+ }
+
+ // Fetch progress
+ const int progress = pakfire_transaction_get_progress(transaction);
+
+ // Call the callback
+ transaction->callbacks.status(transaction->pakfire,
+ transaction->callbacks.status_data, progress, buffer);
+
+ // Cleanup
+ if (buffer)
+ free(buffer);
+}
+
PAKFIRE_EXPORT size_t pakfire_transaction_count(struct pakfire_transaction* transaction) {
return transaction->num;
}
const char* nevra = pakfire_package_get_nevra(pkg);
// Update status
- pakfire_call_status_callback(transaction->pakfire, _("Installing %s..."), nevra);
+ pakfire_transaction_status(transaction, _("Installing %s..."), nevra);
// Extract payload to the root of the Pakfire instance
int r = pakfire_archive_extract(archive, NULL);
transaction->progress++;
// Update progress callback
- pakfire_call_progress_callback(transaction->pakfire,
- pakfire_transaction_get_progress(transaction));
+ pakfire_transaction_status(transaction, NULL);
switch (type) {
case PAKFIRE_STEP_INSTALL:
// Update status
switch (action) {
case PAKFIRE_ACTION_VERIFY:
- pakfire_call_status_callback(transaction->pakfire, _("Verifying packages..."));
+ pakfire_transaction_status(transaction, _("Verifying packages..."));
break;
case PAKFIRE_ACTION_PRETRANS:
- pakfire_call_status_callback(transaction->pakfire, _("Preparing installation..."));
+ pakfire_transaction_status(transaction, _("Preparing installation..."));
break;
case PAKFIRE_ACTION_POSTTRANS:
- pakfire_call_status_callback(transaction->pakfire, _("Finishing up..."));
+ pakfire_transaction_status(transaction, _("Finishing up..."));
break;
default: