[gnome-software] fedora-tagger-usage: Add a plugin to collect install/remove data



commit d94e102fb850b721df68fa56d1a3a6985812c7ab
Author: Richard Hughes <richard hughsie com>
Date:   Thu Jan 30 21:14:24 2014 +0000

    fedora-tagger-usage: Add a plugin to collect install/remove data
    
    This is disabled by default at the moment. To enable, use:
    
    $ gsettings set org.gnome.software enable-usage true

 data/org.gnome.software.gschema.xml                |    9 +
 src/gs-plugin-loader.c                             |    2 +
 src/gs-plugin.h                                    |    1 +
 src/plugins/Makefile.am                            |   16 +-
 ...-tagger.c => gs-plugin-fedora-tagger-ratings.c} |    2 +-
 src/plugins/gs-plugin-fedora-tagger-usage.c        |  250 ++++++++++++++++++++
 6 files changed, 274 insertions(+), 6 deletions(-)
---
diff --git a/data/org.gnome.software.gschema.xml b/data/org.gnome.software.gschema.xml
index e182d99..8e9e14c 100644
--- a/data/org.gnome.software.gschema.xml
+++ b/data/org.gnome.software.gschema.xml
@@ -10,6 +10,15 @@
       <summary>Applications require AppData to be shown in the search results</summary>
       <description>If enabled applications require a long description before they are shown to the user in 
the search results.</description>
     </key>
+    <key name="enable-usage" type="b">
+      <default>false</default>
+      <summary>Enable collection of user data</summary>
+      <description>
+        If enabled the application will send an report to your distribution
+        noting the application that was installed or removed to provide better
+        suggestions for other users.
+      </description>
+    </key>
     <key name="check-timestamp" type="x">
       <default>0</default>
       <summary>The last update check timestamp</summary>
diff --git a/src/gs-plugin-loader.c b/src/gs-plugin-loader.c
index ae25003..6a40bb2 100644
--- a/src/gs-plugin-loader.c
+++ b/src/gs-plugin-loader.c
@@ -2448,6 +2448,7 @@ gs_plugin_loader_open_plugin (GsPluginLoader *plugin_loader,
        plugin->module = module;
        plugin->pixbuf_size = 64;
        plugin->priority = plugin_prio (plugin);
+       plugin->settings = g_object_ref (plugin_loader->priv->settings);
        plugin->name = g_strdup (plugin_name ());
        plugin->status_update_fn = gs_plugin_loader_status_update_cb;
        plugin->status_update_user_data = plugin_loader;
@@ -2583,6 +2584,7 @@ gs_plugin_loader_plugin_free (GsPlugin *plugin)
        g_free (plugin->name);
        g_object_unref (plugin->profile);
        g_hash_table_unref (plugin->icon_cache);
+       g_object_unref (plugin->settings);
        g_module_close (plugin->module);
        g_slice_free (GsPlugin, plugin);
 }
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 1350cc7..c91022f 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -71,6 +71,7 @@ struct GsPlugin {
        gpointer                 updates_changed_user_data;
        GsProfile               *profile;
        GHashTable              *icon_cache;    /* key is the id.desktop */
+       GSettings               *settings;
 };
 
 typedef enum {
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 49f054d..f83dfeb 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -36,7 +36,8 @@ plugin_LTLIBRARIES =                                  \
        libgs_plugin_menu-spec-categories.la            \
        libgs_plugin_menu-spec-refine.la                \
        libgs_plugin_local-ratings.la                   \
-       libgs_plugin_fedora_tagger.la                   \
+       libgs_plugin_fedora_tagger_ratings.la           \
+       libgs_plugin_fedora_tagger_usage.la             \
        libgs_plugin_epiphany.la                        \
        libgs_plugin_systemd-updates.la                 \
        libgs_plugin_packagekit-search.la               \
@@ -52,10 +53,15 @@ libgs_plugin_dummy_la_LIBADD = $(GS_PLUGIN_LIBS)
 libgs_plugin_dummy_la_LDFLAGS = -module -avoid-version
 libgs_plugin_dummy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
 
-libgs_plugin_fedora_tagger_la_SOURCES = gs-plugin-fedora-tagger.c
-libgs_plugin_fedora_tagger_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS) $(SQLITE_LIBS)
-libgs_plugin_fedora_tagger_la_LDFLAGS = -module -avoid-version
-libgs_plugin_fedora_tagger_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
+libgs_plugin_fedora_tagger_ratings_la_SOURCES = gs-plugin-fedora-tagger-ratings.c
+libgs_plugin_fedora_tagger_ratings_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS) $(SQLITE_LIBS)
+libgs_plugin_fedora_tagger_ratings_la_LDFLAGS = -module -avoid-version
+libgs_plugin_fedora_tagger_ratings_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
+
+libgs_plugin_fedora_tagger_usage_la_SOURCES = gs-plugin-fedora-tagger-usage.c
+libgs_plugin_fedora_tagger_usage_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS) $(SQLITE_LIBS)
+libgs_plugin_fedora_tagger_usage_la_LDFLAGS = -module -avoid-version
+libgs_plugin_fedora_tagger_usage_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARNINGFLAGS_C)
 
 libgs_plugin_epiphany_la_SOURCES = gs-plugin-epiphany.c
 libgs_plugin_epiphany_la_LIBADD = $(GS_PLUGIN_LIBS) $(SOUP_LIBS)
diff --git a/src/plugins/gs-plugin-fedora-tagger.c b/src/plugins/gs-plugin-fedora-tagger-ratings.c
similarity index 99%
rename from src/plugins/gs-plugin-fedora-tagger.c
rename to src/plugins/gs-plugin-fedora-tagger-ratings.c
index 444880f..4bace6f 100644
--- a/src/plugins/gs-plugin-fedora-tagger.c
+++ b/src/plugins/gs-plugin-fedora-tagger-ratings.c
@@ -42,7 +42,7 @@ struct GsPluginPrivate {
 const gchar *
 gs_plugin_get_name (void)
 {
-       return "fedora-tagger";
+       return "fedora-tagger-ratings";
 }
 
 #define GS_PLUGIN_FEDORA_TAGGER_OS_RELEASE_FN  "/etc/os-release"
diff --git a/src/plugins/gs-plugin-fedora-tagger-usage.c b/src/plugins/gs-plugin-fedora-tagger-usage.c
new file mode 100644
index 0000000..8c93224
--- /dev/null
+++ b/src/plugins/gs-plugin-fedora-tagger-usage.c
@@ -0,0 +1,250 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <libsoup/soup.h>
+#include <string.h>
+#include <sqlite3.h>
+#include <stdlib.h>
+
+#include <gs-plugin.h>
+#include <gs-utils.h>
+
+struct GsPluginPrivate {
+       SoupSession             *session;
+};
+
+/**
+ * gs_plugin_get_name:
+ */
+const gchar *
+gs_plugin_get_name (void)
+{
+       return "fedora-tagger-usage";
+}
+
+#define GS_PLUGIN_FEDORA_TAGGER_OS_RELEASE_FN  "/etc/os-release"
+#define GS_PLUGIN_FEDORA_TAGGER_SERVER         "https://apps.fedoraproject.org/tagger";
+
+/**
+ * gs_plugin_initialize:
+ */
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+       GError *error = NULL;
+       gboolean ret;
+       gchar *data = NULL;
+
+       plugin->priv = GS_PLUGIN_GET_PRIVATE (GsPluginPrivate);
+
+       /* this is opt-in, and turned off by default */
+       ret = g_settings_get_boolean (plugin->settings, "enable-usage");
+       if (!ret) {
+               gs_plugin_set_enabled (plugin, FALSE);
+               g_debug ("disabling '%s' as 'enable-usage' disabled in GSettings",
+                        plugin->name);
+               goto out;
+       }
+
+       /* check that we are running on Fedora */
+       ret = g_file_get_contents (GS_PLUGIN_FEDORA_TAGGER_OS_RELEASE_FN,
+                                  &data, NULL, &error);
+       if (!ret) {
+               gs_plugin_set_enabled (plugin, FALSE);
+               g_warning ("disabling '%s' as %s could not be read: %s",
+                          plugin->name,
+                          GS_PLUGIN_FEDORA_TAGGER_OS_RELEASE_FN,
+                          error->message);
+               g_error_free (error);
+               goto out;
+       }
+       if (g_strstr_len (data, -1, "ID=fedora\n") == NULL) {
+               gs_plugin_set_enabled (plugin, FALSE);
+               g_debug ("disabling '%s' as %s suggests we're not Fedora",
+                        plugin->name, GS_PLUGIN_FEDORA_TAGGER_OS_RELEASE_FN);
+               goto out;
+       }
+out:
+       g_free (data);
+}
+
+/**
+ * gs_plugin_get_priority:
+ */
+gdouble
+gs_plugin_get_priority (GsPlugin *plugin)
+{
+       /* after packagekit */
+       return 20.f;
+}
+
+/**
+ * gs_plugin_destroy:
+ */
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+       if (plugin->priv->session != NULL)
+               g_object_unref (plugin->priv->session);
+}
+
+/**
+ * gs_plugin_setup_networking:
+ */
+static gboolean
+gs_plugin_setup_networking (GsPlugin *plugin, GError **error)
+{
+       gboolean ret = TRUE;
+
+       /* already set up */
+       if (plugin->priv->session != NULL)
+               goto out;
+
+       /* set up a session */
+       plugin->priv->session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT,
+                                                                   "gnome-software",
+                                                                   SOUP_SESSION_TIMEOUT, 5000,
+                                                                   NULL);
+       if (plugin->priv->session == NULL) {
+               ret = FALSE;
+               g_set_error (error,
+                            GS_PLUGIN_ERROR,
+                            GS_PLUGIN_ERROR_FAILED,
+                            "%s: failed to setup networking",
+                            plugin->name);
+               goto out;
+       }
+       soup_session_add_feature_by_type (plugin->priv->session,
+                                         SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+out:
+       return ret;
+}
+
+/**
+ * gs_plugin_app_set_usage_pkg:
+ */
+static gboolean
+gs_plugin_app_set_usage_pkg (GsPlugin *plugin,
+                            const gchar *pkgname,
+                            gboolean is_install,
+                            GError **error)
+{
+       SoupMessage *msg = NULL;
+       gchar *data = NULL;
+       gchar *error_msg = NULL;
+       gchar *uri = NULL;
+       guint status_code;
+
+       /* create the PUT data */
+       uri = g_strdup_printf ("%s/api/v1/usage/%s/",
+                              GS_PLUGIN_FEDORA_TAGGER_SERVER,
+                              pkgname);
+       data = g_strdup_printf ("pkgname=%s&usage=%s",
+                               pkgname,
+                               is_install ? "true" : "false");
+       msg = soup_message_new (SOUP_METHOD_PUT, uri);
+       soup_message_set_request (msg, SOUP_FORM_MIME_TYPE_URLENCODED,
+                                 SOUP_MEMORY_COPY, data, strlen (data));
+
+       /* set sync request */
+       status_code = soup_session_send_message (plugin->priv->session, msg);
+       if (status_code != SOUP_STATUS_OK) {
+               g_debug ("Failed to set usage on fedora-tagger: %s",
+                        soup_status_get_phrase (status_code));
+               if (msg->response_body->data != NULL) {
+                       g_debug ("the error given was: %s",
+                                msg->response_body->data);
+               }
+       } else {
+               g_debug ("Got response: %s", msg->response_body->data);
+       }
+
+       g_free (error_msg);
+       g_free (data);
+       g_free (uri);
+       if (msg != NULL)
+               g_object_unref (msg);
+       return TRUE;
+}
+
+/**
+ * gs_plugin_app_set_usage_app:
+ */
+static gboolean
+gs_plugin_app_set_usage_app (GsPlugin *plugin,
+                            GsApp *app,
+                            gboolean is_install,
+                            GError **error)
+{
+       GPtrArray *sources;
+       const gchar *pkgname;
+       gboolean ret = TRUE;
+       guint i;
+
+       /* get the package name */
+       sources = gs_app_get_sources (app);
+       if (sources->len == 0)
+               goto out;
+
+       /* ensure networking is set up */
+       ret = gs_plugin_setup_networking (plugin, error);
+       if (!ret)
+               goto out;
+
+       /* tell fedora-tagger about this package */
+       for (i = 0; i < sources->len; i++) {
+               pkgname = g_ptr_array_index (sources, i);
+               ret = gs_plugin_app_set_usage_pkg (plugin,
+                                                  pkgname,
+                                                  is_install,
+                                                  error);
+               if (!ret)
+                       goto out;
+       }
+out:
+       return ret;
+}
+
+/**
+ * gs_plugin_app_install:
+ */
+gboolean
+gs_plugin_app_install (GsPlugin *plugin,
+                      GsApp *app,
+                      GCancellable *cancellable,
+                      GError **error)
+{
+       return gs_plugin_app_set_usage_app (plugin, app, TRUE, error);
+}
+
+/**
+ * gs_plugin_app_remove:
+ */
+gboolean
+gs_plugin_app_remove (GsPlugin *plugin,
+                     GsApp *app,
+                     GCancellable *cancellable,
+                     GError **error)
+{
+       return gs_plugin_app_set_usage_app (plugin, app, FALSE, error);
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]