From dca735d0a5b215fdbc278d0656f90f72612bac44 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 15 Mar 2025 11:53:25 +0000 Subject: [PATCH] progress: Add a status callback Signed-off-by: Michael Tremer --- src/pakfire/progress.c | 31 ++++++++++++++++++++++++++++++- src/pakfire/progress.h | 4 ++++ src/python/ctx.c | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/pakfire/progress.c b/src/pakfire/progress.c index ecd8ff7c..eaedf649 100644 --- a/src/pakfire/progress.c +++ b/src/pakfire/progress.c @@ -57,6 +57,7 @@ struct pakfire_progress { pakfire_progress_start_callback start; pakfire_progress_finish_callback finish; pakfire_progress_update_callback update; + pakfire_progress_status_callback status; pakfire_progress_free_callback free; } callbacks; @@ -194,6 +195,11 @@ void pakfire_progress_set_update_callback( p->callbacks.update = callback; } +void pakfire_progress_set_status_callback( + struct pakfire_progress* p, pakfire_progress_status_callback callback) { + p->callbacks.status = callback; +} + void pakfire_progress_set_free_callback( struct pakfire_progress* p, pakfire_progress_free_callback callback) { p->callbacks.free = callback; @@ -384,11 +390,34 @@ int pakfire_progress_push_status(struct pakfire_progress* p, const char* format, return r; // Append the status - return pakfire_strings_append(&p->status, status); + r = pakfire_strings_append(&p->status, status); + if (r < 0) + return r; + + // Call the callback + if (p->callbacks.status) { + r = p->callbacks.status(p->ctx, p, p->callbacks.data, status); + if (r < 0) + return r; + } + + return 0; } void pakfire_progress_pop_status(struct pakfire_progress* p) { + const char* status = NULL; + + // Remove the latest status pakfire_strings_pop(&p->status); + + // Call the status callback + if (p->callbacks.status) { + // Fetch the latest status + status = pakfire_progress_get_status(p); + + // Call the callback + p->callbacks.status(p->ctx, p, p->callbacks.data, status); + } } double pakfire_progress_get_percentage(struct pakfire_progress* p) { diff --git a/src/pakfire/progress.h b/src/pakfire/progress.h index 1d787d60..ebee0f3c 100644 --- a/src/pakfire/progress.h +++ b/src/pakfire/progress.h @@ -48,6 +48,8 @@ typedef int (*pakfire_progress_finish_callback) (struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data); typedef int (*pakfire_progress_update_callback) (struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data, unsigned long int value); +typedef int (*pakfire_progress_status_callback) + (struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data, const char* status); typedef void (*pakfire_progress_free_callback) (struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data); @@ -59,6 +61,8 @@ void pakfire_progress_set_finish_callback( struct pakfire_progress* p, pakfire_progress_finish_callback callback); void pakfire_progress_set_update_callback( struct pakfire_progress* p, pakfire_progress_update_callback callback); +void pakfire_progress_set_status_callback( + struct pakfire_progress* p, pakfire_progress_status_callback callback); void pakfire_progress_set_free_callback( struct pakfire_progress* p, pakfire_progress_free_callback callback); diff --git a/src/python/ctx.c b/src/python/ctx.c index 18d25bcb..a1b3b53f 100644 --- a/src/python/ctx.c +++ b/src/python/ctx.c @@ -373,6 +373,38 @@ ERROR: return r; } +static int Ctx_progress_status(struct pakfire_ctx* ctx, + struct pakfire_progress* progress, void* data, const char* text) { + PyObject* ret = NULL; + PyObject* p = data; + int r = -1; + + // Acquire the GIL + PyGILState_STATE state = PyGILState_Ensure(); + + // Fetch the status method + PyObject* status = PyObject_GetAttrString(p, "status"); + if (!status) + goto ERROR; + + // Call it with the value + ret = PyObject_CallFunction(status, "z", text); + if (!ret) + goto ERROR; + + // Success + r = 0; + +ERROR: + Py_XDECREF(status); + Py_XDECREF(ret); + + // Release the GIL + PyGILState_Release(state); + + return r; +} + static void Ctx_progress_free( struct pakfire_ctx* ctx, struct pakfire_progress* progress, void* data) { PyObject* p = data; @@ -418,6 +450,9 @@ static int Ctx_progress_callback( // Set update callback pakfire_progress_set_update_callback(progress, Ctx_progress_update); + // Set status callback + pakfire_progress_set_status_callback(progress, Ctx_progress_status); + // Set free callback pakfire_progress_set_free_callback(progress, Ctx_progress_free); -- 2.39.5