[gnome-settings-daemon] updates: Add the notification for offline updates
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] updates: Add the notification for offline updates
- Date: Wed, 6 Jun 2012 17:29:03 +0000 (UTC)
commit 1cea16c8c53d69faabfc45ba002b17c9ed166afe
Author: Richard Hughes <richard hughsie com>
Date: Wed Jun 6 14:01:17 2012 +0100
updates: Add the notification for offline updates
Show a notification when offline updates have been installed and when they fail.
plugins/updates/Makefile.am | 1 +
plugins/updates/gsd-updates-manager.c | 270 ++++++++++++++++++++++++++++++++-
2 files changed, 267 insertions(+), 4 deletions(-)
---
diff --git a/plugins/updates/Makefile.am b/plugins/updates/Makefile.am
index 9510c65..7d67855 100644
--- a/plugins/updates/Makefile.am
+++ b/plugins/updates/Makefile.am
@@ -32,6 +32,7 @@ libupdates_la_CFLAGS = \
-DI_KNOW_THE_PACKAGEKIT_GLIB2_API_IS_SUBJECT_TO_CHANGE \
-DDATADIR=\"$(datadir)\" \
-DBINDIR=\"$(bindir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
-I$(top_srcdir)/data \
$(AM_CFLAGS)
diff --git a/plugins/updates/gsd-updates-manager.c b/plugins/updates/gsd-updates-manager.c
index c971528..c48feae 100644
--- a/plugins/updates/gsd-updates-manager.c
+++ b/plugins/updates/gsd-updates-manager.c
@@ -52,7 +52,8 @@ struct GsdUpdatesManagerPrivate
GSettings *settings_gsd;
GSettings *settings_http;
guint number_updates_critical_last_shown;
- guint timeout;
+ guint offline_update_id;
+ PkError *offline_update_error;
NotifyNotification *notification_updates;
PkControl *control;
PkTask *task;
@@ -78,6 +79,118 @@ G_DEFINE_TYPE (GsdUpdatesManager, gsd_updates_manager, G_TYPE_OBJECT)
static gpointer manager_object = NULL;
static void
+clear_offline_updates_message (void)
+{
+ gboolean ret;
+ GError *error = NULL;
+ ret = g_spawn_command_line_async ("pkexec " LIBEXECDIR "/pk-clear-offline-update",
+ &error);
+ if (!ret) {
+ g_warning ("Failure clearing offline update message: %s",
+ error->message);
+ g_error_free (error);
+ }
+}
+
+static void
+show_offline_updates_error (GsdUpdatesManager *manager)
+{
+ const gchar *title;
+ gboolean show_geeky = FALSE;
+ GString *msg;
+ GtkWidget *dialog;
+
+ /* TRANSLATORS: this is when the offline update failed */
+ title = _("Failed To Update");
+ msg = g_string_new ("");
+ switch (pk_error_get_code (manager->priv->offline_update_error)) {
+ case PK_ERROR_ENUM_UNFINISHED_TRANSACTION:
+ /* TRANSLATORS: the transaction could not be completed
+ * as a previous transaction was unfinished */
+ g_string_append (msg, _("A previous update was unfinished."));
+ show_geeky = TRUE;
+ break;
+ case PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED:
+ case PK_ERROR_ENUM_NO_CACHE:
+ case PK_ERROR_ENUM_NO_NETWORK:
+ case PK_ERROR_ENUM_NO_MORE_MIRRORS_TO_TRY:
+ case PK_ERROR_ENUM_CANNOT_FETCH_SOURCES:
+ /* TRANSLATORS: the package manager needed to download
+ * something with no network available */
+ g_string_append (msg, _("Network access was required but not available."));
+ break;
+ case PK_ERROR_ENUM_BAD_GPG_SIGNATURE:
+ case PK_ERROR_ENUM_CANNOT_UPDATE_REPO_UNSIGNED:
+ case PK_ERROR_ENUM_GPG_FAILURE:
+ case PK_ERROR_ENUM_MISSING_GPG_SIGNATURE:
+ case PK_ERROR_ENUM_PACKAGE_CORRUPT:
+ /* TRANSLATORS: if the package is not signed correctly
+ * */
+ g_string_append (msg, _("An update was not signed in the correct way."));
+ show_geeky = TRUE;
+ break;
+ case PK_ERROR_ENUM_DEP_RESOLUTION_FAILED:
+ case PK_ERROR_ENUM_FILE_CONFLICTS:
+ case PK_ERROR_ENUM_INCOMPATIBLE_ARCHITECTURE:
+ case PK_ERROR_ENUM_PACKAGE_CONFLICTS:
+ /* TRANSLATORS: the transaction failed in a way the user
+ * probably cannot comprehend. Package management systems
+ * really are teh suck.*/
+ g_string_append (msg, _("The update could not be completed."));
+ show_geeky = TRUE;
+ break;
+ case PK_ERROR_ENUM_TRANSACTION_CANCELLED:
+ /* TRANSLATORS: the user aborted the update manually */
+ g_string_append (msg, _("The update was cancelled."));
+ break;
+ case PK_ERROR_ENUM_NO_PACKAGES_TO_UPDATE:
+ case PK_ERROR_ENUM_UPDATE_NOT_FOUND:
+ /* TRANSLATORS: the user must have updated manually after
+ * the updates were prepared */
+ g_string_append (msg, _("An offline update was requested but no packages required updating."));
+ break;
+ case PK_ERROR_ENUM_NO_SPACE_ON_DEVICE:
+ /* TRANSLATORS: we ran out of disk space */
+ g_string_append (msg, _("No space was left on the drive."));
+ break;
+ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_BUILD:
+ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_INSTALL:
+ case PK_ERROR_ENUM_PACKAGE_FAILED_TO_REMOVE:
+ /* TRANSLATORS: the update process failed in a general
+ * way, usually this message will come from source distros
+ * like gentoo */
+ g_string_append (msg, _("An update failed to install correctly."));
+ show_geeky = TRUE;
+ break;
+ default:
+ /* TRANSLATORS: We didn't handle the error type */
+ g_string_append (msg, _("The offline update failed in an unexpected way."));
+ show_geeky = TRUE;
+ break;
+ }
+ if (show_geeky) {
+ g_string_append_printf (msg, "\n%s\n\n%s",
+ /* TRANSLATORS: these are geeky messages from the
+ * package manager no mortal is supposed to understand,
+ * but google might know what they mean */
+ _("Detailed errors from the package manager follow:"),
+ pk_error_get_details (manager->priv->offline_update_error));
+ }
+ dialog = gtk_message_dialog_new (NULL,
+ 0,
+ GTK_MESSAGE_INFO,
+ GTK_BUTTONS_CLOSE,
+ "%s", title);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "%s", msg->str);
+ g_signal_connect_swapped (dialog, "response",
+ G_CALLBACK (gtk_widget_destroy),
+ dialog);
+ gtk_widget_show (dialog);
+ clear_offline_updates_message ();
+}
+
+static void
libnotify_action_cb (NotifyNotification *notification,
gchar *action,
gpointer user_data)
@@ -114,6 +227,14 @@ libnotify_action_cb (NotifyNotification *notification,
manager);
goto out;
}
+ if (g_strcmp0 (action, "clear-offline-updates") == 0) {
+ clear_offline_updates_message ();
+ goto out;
+ }
+ if (g_strcmp0 (action, "error-offline-updates") == 0) {
+ show_offline_updates_error (manager);
+ goto out;
+ }
if (g_strcmp0 (action, "cancel") == 0) {
/* try to cancel */
g_cancellable_cancel (manager->priv->cancellable);
@@ -1327,6 +1448,137 @@ on_bus_gotten (GObject *source_object,
NULL);
}
+#define PK_OFFLINE_UPDATE_RESULTS_GROUP "PackageKit Offline Update Results"
+#define PK_OFFLINE_UPDATE_RESULTS_FILENAME "/var/lib/PackageKit/offline-update-competed"
+
+static gboolean
+check_offline_update_cb (gpointer user_data)
+{
+ const gchar *message;
+ const gchar *title;
+ gboolean ret;
+ gboolean success;
+ gchar *error_code = NULL;
+ gchar *error_details = NULL;
+ gchar *packages = NULL;
+ GError *error = NULL;
+ GKeyFile *key_file = NULL;
+ GsdUpdatesManager *manager = (GsdUpdatesManager *) user_data;
+ guint i;
+ guint num_packages = 1;
+ NotifyNotification *notification;
+ PkErrorEnum error_enum = PK_ERROR_ENUM_UNKNOWN;
+
+ /* was any offline update attempted */
+ if (!g_file_test (PK_OFFLINE_UPDATE_RESULTS_FILENAME, G_FILE_TEST_EXISTS))
+ goto out;
+
+ /* open the file and see what happened */
+ key_file = g_key_file_new ();
+ ret = g_key_file_load_from_file (key_file,
+ PK_OFFLINE_UPDATE_RESULTS_FILENAME,
+ G_KEY_FILE_NONE,
+ &error);
+ if (!ret) {
+ g_warning ("failed to open %s: %s",
+ PK_OFFLINE_UPDATE_RESULTS_FILENAME,
+ error->message);
+ g_error_free (error);
+ goto out;
+ }
+ success = g_key_file_get_boolean (key_file,
+ PK_OFFLINE_UPDATE_RESULTS_GROUP,
+ "Success",
+ NULL);
+ if (success) {
+ packages = g_key_file_get_string (key_file,
+ PK_OFFLINE_UPDATE_RESULTS_GROUP,
+ "Packages",
+ NULL);
+ if (packages == NULL) {
+ g_warning ("No 'Packages' in %s",
+ PK_OFFLINE_UPDATE_RESULTS_FILENAME);
+ goto out;
+ }
+
+ /* count the packages for translators */
+ for (i = 0; packages[i] != '\0'; i++) {
+ if (packages[i] == ',')
+ num_packages++;
+ }
+
+ /* TRANSLATORS: title in the libnotify popup */
+ title = ngettext ("Software Update Installed",
+ "Software Updates Installed",
+ num_packages);
+
+ /* TRANSLATORS: message when we've done offline updates */
+ message = ngettext ("An important OS update has been installed.",
+ "Important OS updates have been installed.",
+ num_packages);
+ } else {
+ /* get error details */
+ manager->priv->offline_update_error = pk_error_new ();
+
+ error_code = g_key_file_get_string (key_file,
+ PK_OFFLINE_UPDATE_RESULTS_GROUP,
+ "ErrorCode",
+ NULL);
+ if (error_code != NULL)
+ error_enum = pk_error_enum_from_string (error_code);
+ error_details = g_key_file_get_string (key_file,
+ PK_OFFLINE_UPDATE_RESULTS_GROUP,
+ "ErrorDetails",
+ NULL);
+ g_object_set (manager->priv->offline_update_error,
+ "code", error_enum,
+ "details", error_details,
+ NULL);
+
+ /* TRANSLATORS: title in the libnotify popup */
+ title = _("Software Updates Failed");
+
+ /* TRANSLATORS: message when we've not done offline updates */
+ message = _("An important OS update failed to be installed.");
+ }
+
+ /* do the bubble */
+ g_debug ("title=%s, message=%s", title, message);
+ notification = notify_notification_new (title,
+ message,
+ GSD_UPDATES_ICON_URGENT);
+ notify_notification_set_app_name (notification, _("Software Updates"));
+ notify_notification_set_timeout (notification, -1);
+ notify_notification_set_urgency (notification, NOTIFY_URGENCY_NORMAL);
+ if (success) {
+#if 0
+ notify_notification_add_action (notification, "review-offline-updates",
+ /* TRANSLATORS: button: review the offline update changes */
+ _("Review"), libnotify_action_cb, manager, NULL);
+#endif
+ } else {
+ notify_notification_add_action (notification, "error-offline-updates",
+ /* TRANSLATORS: button: review the offline update changes */
+ _("Show details"), libnotify_action_cb, manager, NULL);
+ }
+ notify_notification_add_action (notification, "clear-offline-updates",
+ /* TRANSLATORS: button: clear notification */
+ _("OK"), libnotify_action_cb, manager, NULL);
+ ret = notify_notification_show (notification, &error);
+ if (!ret) {
+ g_warning ("error: %s", error->message);
+ g_error_free (error);
+ }
+out:
+ g_free (packages);
+ g_free (error_code);
+ g_free (error_details);
+ if (key_file != NULL)
+ g_key_file_free (key_file);
+ manager->priv->offline_update_id = 0;
+ return FALSE;
+}
+
gboolean
gsd_updates_manager_start (GsdUpdatesManager *manager,
GError **error)
@@ -1433,6 +1685,12 @@ gsd_updates_manager_start (GsdUpdatesManager *manager,
(GAsyncReadyCallback) on_bus_gotten,
manager);
+ /* check for offline update */
+ manager->priv->offline_update_id =
+ g_timeout_add_seconds (5,
+ check_offline_update_cb,
+ manager);
+
/* success */
ret = TRUE;
g_debug ("Started updates manager");
@@ -1502,9 +1760,13 @@ gsd_updates_manager_stop (GsdUpdatesManager *manager)
g_bus_unown_name (manager->priv->owner_id);
manager->priv->owner_id = 0;
}
- if (manager->priv->timeout) {
- g_source_remove (manager->priv->timeout);
- manager->priv->timeout = 0;
+ if (manager->priv->offline_update_id) {
+ g_source_remove (manager->priv->offline_update_id);
+ manager->priv->offline_update_id = 0;
+ }
+ if (manager->priv->offline_update_error != NULL) {
+ g_object_unref (manager->priv->offline_update_error);
+ manager->priv->offline_update_error = 0;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]