]> git.ipfire.org Git - pakfire.git/commitdiff
progress: Add a status callback
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 15 Mar 2025 11:53:25 +0000 (11:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 15 Mar 2025 11:53:25 +0000 (11:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/progress.c
src/pakfire/progress.h
src/python/ctx.c

index ecd8ff7c96669670f9b9cba4f39ec750085261ae..eaedf6496c3c9522e8c90dfb665729c9dda507e6 100644 (file)
@@ -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) {
index 1d787d60e9be486ec288b94f5c268ed75f3edf0f..ebee0f3c75d604060d614d656d6d3fd635db1add 100644 (file)
@@ -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);
 
index 18d25bcb848c63c4bb7bd31dae7274105651075c..a1b3b53fc2c70f1c87154434ed620705985198d3 100644 (file)
@@ -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);