From: Michael Tremer Date: Mon, 9 May 2022 10:04:51 +0000 (+0000) Subject: pakfire: Introduce confirm callback X-Git-Tag: 0.9.28~811 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6409945ba09d2c2f5b94a3f6aa6bf37316a4687;p=pakfire.git pakfire: Introduce confirm callback Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index dac3e3ab7..32965390e 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -50,6 +50,7 @@ static PyObject* Pakfire_new(PyTypeObject* type, PyObject* args, PyObject* kwds) // Callbacks self->callbacks.log = NULL; + self->callbacks.confirm = NULL; self->callbacks.status = NULL; self->callbacks.progress = NULL; } @@ -108,6 +109,31 @@ ERROR: Py_XDECREF(result); } +static int Pakfire_confirm_callback(struct pakfire* pakfire, void* data, + const char* message, const char* question) { + PyObject* callback = (PyObject*)data; + int r = 0; + + // Do nothing if callback isn't set + if (!callback) + return 0; + + PyObject* args = Py_BuildValue("(ss)", message, question); + if (!args) + return -1; + + PyObject* result = PyObject_CallObject(callback, args); + + // Extract return code + if (PyLong_Check(result)) + r = PyLong_AsLong(result); + + Py_DECREF(args); + Py_DECREF(result); + + return r; +} + static void Pakfire_status_callback(void* data, const char* message) { struct callbacks* callbacks = (struct callbacks*)data; @@ -165,6 +191,7 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { "build", "enable_ccache", "enable_snapshot", + "confirm_callback", NULL, }; const char* path = NULL; @@ -176,9 +203,9 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { int enable_ccache = 1; int enable_snapshot = 1; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzppp", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOppzpppO", kwlist, &path, &arch, &self->callbacks.log, &interactive, &offline, &conf, &build, - &enable_ccache, &enable_snapshot)) + &enable_ccache, &enable_snapshot, &self->callbacks.confirm)) return -1; // Check if log callback is callable @@ -187,6 +214,12 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { return -1; } + // Check if confirm callback is callable + if (self->callbacks.confirm && !PyCallable_Check(self->callbacks.confirm)) { + PyErr_SetString(PyExc_TypeError, "Confirm callback is not callable"); + return -1; + } + int flags = 0; // Enable interactive mode @@ -230,19 +263,35 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { return -1; } + // Configure confirm callback + if (self->callbacks.confirm) { + pakfire_set_confirm_callback(self->pakfire, + Pakfire_confirm_callback, self->callbacks.confirm); + + Py_INCREF(self->callbacks.confirm); + } + return 0; } static void Pakfire_dealloc(PakfireObject* self) { if (self->pakfire) { // Reset log callback - pakfire_set_log_callback(self->pakfire, NULL, NULL); + if (self->callbacks.log) { + pakfire_set_log_callback(self->pakfire, NULL, NULL); + Py_DECREF(self->callbacks.log); + } + + // Reset confirm callback + if (self->callbacks.confirm) { + pakfire_set_confirm_callback(self->pakfire, NULL, NULL); + Py_DECREF(self->callbacks.confirm); + } pakfire_unref(self->pakfire); } // Free callbacks - Py_XDECREF(self->callbacks.log); Py_XDECREF(self->callbacks.status); Py_XDECREF(self->callbacks.progress); diff --git a/src/_pakfire/pakfire.h b/src/_pakfire/pakfire.h index f720f1402..5a5c6b3f0 100644 --- a/src/_pakfire/pakfire.h +++ b/src/_pakfire/pakfire.h @@ -32,6 +32,7 @@ typedef struct { // Callbacks struct callbacks { PyObject* log; + PyObject* confirm; PyObject* status; PyObject* progress; } callbacks; diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index 9f50ec62f..ba162bda6 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -56,6 +56,10 @@ typedef void (*pakfire_log_callback)(void* data, int priority, const char* file, int line, const char* fn, const char* format, va_list args); void pakfire_set_log_callback(struct pakfire* pakfire, pakfire_log_callback callback, void* data); +typedef int (*pakfire_confirm_callback)(struct pakfire* pakfire, void* data, + const char* message, const char* question); +void pakfire_set_confirm_callback(struct pakfire* pakfire, + pakfire_confirm_callback callback, void* data); 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); @@ -140,6 +144,7 @@ void pakfire_release_lock(struct pakfire* pakfire); struct pakfire_config* pakfire_get_config(struct pakfire* pakfire); 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); diff --git a/src/libpakfire/include/pakfire/ui.h b/src/libpakfire/include/pakfire/ui.h index c4ad3ff30..223c878c8 100644 --- a/src/libpakfire/include/pakfire/ui.h +++ b/src/libpakfire/include/pakfire/ui.h @@ -26,7 +26,8 @@ #include #include -int pakfire_ui_confirm(struct pakfire* pakfire, const char* message, const char* question); +int pakfire_ui_confirm(struct pakfire* pakfire, void* data, + const char* message, const char* question); int pakfire_ui_pick_solution(struct pakfire* pakfire, struct pakfire_request* request, struct pakfire_problem** problems); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 3feed459d..884f0329e 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -40,6 +40,7 @@ global: pakfire_ref; pakfire_refresh; pakfire_search; + pakfire_set_confirm_callback; pakfire_set_log_callback; pakfire_sync; pakfire_unref; diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 43054935a..970df779c 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -94,6 +94,10 @@ struct pakfire { pakfire_log_callback log; void* log_data; + // Confirm + pakfire_confirm_callback confirm; + void* confirm_data; + // Status void (*status)(void* data, const char* message); void* status_data; @@ -908,6 +912,9 @@ PAKFIRE_EXPORT int pakfire_create(struct pakfire** pakfire, const char* path, if (env) pakfire_log_set_priority(p, log_priority(env)); + // Setup confirm callback + pakfire_set_confirm_callback(p, pakfire_ui_confirm, NULL); + // Initialise configuration r = pakfire_config_create(&p->config); if (r) @@ -1709,6 +1716,28 @@ void pakfire_log(struct pakfire* pakfire, int priority, const char* file, int li errno = saved_errno; } +// UI + +PAKFIRE_EXPORT void pakfire_set_confirm_callback(struct pakfire* pakfire, + pakfire_confirm_callback callback, void* data) { + pakfire->callbacks.confirm = callback; + pakfire->callbacks.confirm_data = data; +} + +int pakfire_confirm(struct pakfire* pakfire, const char* message, const char* question) { + // No callback configured + if (!pakfire->callbacks.confirm) + return 0; + + // Skip this, if running in non-interactive mode + if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_INTERACTIVE)) + return 0; + + // Run callback + return pakfire->callbacks.confirm( + pakfire, pakfire->callbacks.confirm_data, message, question); +} + static const char* pakfire_user_lookup(void* data, la_int64_t uid) { struct pakfire* pakfire = (struct pakfire*)data; diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index e2026381f..0b8ba0f66 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -1224,7 +1224,7 @@ PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transacti // Check if we should continue if (pakfire_has_flag(transaction->pakfire, PAKFIRE_FLAGS_INTERACTIVE)) { - r = pakfire_ui_confirm(transaction->pakfire, dump, _("Is this okay? [y/N]")); + r = pakfire_confirm(transaction->pakfire, dump, _("Is this okay? [y/N]")); if (r) { ERROR(transaction->pakfire, "Transaction aborted upon user request\n"); goto ERROR; diff --git a/src/libpakfire/ui.c b/src/libpakfire/ui.c index e009e5493..f62f60371 100644 --- a/src/libpakfire/ui.c +++ b/src/libpakfire/ui.c @@ -27,14 +27,11 @@ #include #include -int pakfire_ui_confirm(struct pakfire* pakfire, const char* message, const char* question) { +int pakfire_ui_confirm(struct pakfire* pakfire, void* data, const char* message, + const char* question) { // The message is only printed once printf("%s\n", message); - // Skip this, if running in non-interactive mode - if (!pakfire_has_flag(pakfire, PAKFIRE_FLAGS_INTERACTIVE)) - return 0; - char* line = NULL; size_t length = 0; int r = 1;