[gnome-software/wip/rancell/snapd-glib] Replace gs-snapd with snapd-glib



commit b86d67944b06507de59cd48e929c65f07ec43eb6
Author: Robert Ancell <robert ancell canonical com>
Date:   Wed Feb 1 16:42:52 2017 +1300

    Replace gs-snapd with snapd-glib

 src/plugins/Makefile.am      |    8 +-
 src/plugins/gs-plugin-snap.c |  275 ++++++++---------
 src/plugins/gs-snapd.c       |  689 ------------------------------------------
 src/plugins/gs-snapd.h       |   77 -----
 src/plugins/meson.build      |    3 +-
 5 files changed, 136 insertions(+), 916 deletions(-)
---
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 6853865..2760f3c 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -391,14 +391,10 @@ libgs_plugin_packagekit_proxy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 if HAVE_SNAP
 appdata_in_files += org.gnome.Software.Plugin.Snap.metainfo.xml.in
 libgs_plugin_snap_la_SOURCES =                         \
-       gs-plugin-snap.c                                \
-       gs-snapd.h                                      \
-       gs-snapd.c
+       gs-plugin-snap.c
 libgs_plugin_snap_la_LIBADD =                          \
        $(GS_PLUGIN_LIBS)                               \
-       $(SNAP_LIBS)                                    \
-       $(SOUP_LIBS)                                    \
-       $(JSON_GLIB_LIBS)
+       $(SNAP_LIBS)
 libgs_plugin_snap_la_LDFLAGS = -module -avoid-version
 libgs_plugin_snap_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
 endif
diff --git a/src/plugins/gs-plugin-snap.c b/src/plugins/gs-plugin-snap.c
index 0ae92f9..d7ccb8d 100644
--- a/src/plugins/gs-plugin-snap.c
+++ b/src/plugins/gs-plugin-snap.c
@@ -21,7 +21,6 @@
 
 #include <config.h>
 
-#include <json-glib/json-glib.h>
 #include <snapd-glib/snapd-glib.h>
 #include <gnome-software.h>
 
@@ -31,8 +30,6 @@ struct GsPluginData {
        GsAuth          *auth;
 };
 
-typedef gboolean (*AppFilterFunc)(const gchar *id, JsonObject *object, gpointer data);
-
 void
 gs_plugin_initialize (GsPlugin *plugin)
 {
@@ -74,93 +71,97 @@ gs_plugin_setup (GsPlugin *plugin, GCancellable *cancellable, GError **error)
        return TRUE;
 }
 
-static void
-get_macaroon (GsPlugin *plugin, gchar **macaroon, gchar ***discharges)
+static SnapdAuthData *
+get_auth (GsPlugin *plugin)
 {
        GsAuth *auth;
        const gchar *serialized_macaroon;
        g_autoptr(GVariant) macaroon_variant = NULL;
+       const gchar *macaroon;
+       g_auto(GStrv) discharges = NULL;
        g_autoptr (GError) error_local = NULL;
 
-       *macaroon = NULL;
-       *discharges = NULL;
-
        auth = gs_plugin_get_auth_by_id (plugin, "snapd");
        if (auth == NULL)
-               return;
+               return NULL;
        serialized_macaroon = gs_auth_get_metadata_item (auth, "macaroon");
        if (serialized_macaroon == NULL)
-               return;
+               return NULL;
        macaroon_variant = g_variant_parse (G_VARIANT_TYPE ("(sas)"),
                                            serialized_macaroon,
                                            NULL,
                                            NULL,
                                            NULL);
        if (macaroon_variant == NULL)
-               return;
-       g_variant_get (macaroon_variant, "(s^as)", macaroon, discharges);
+               return NULL;
+       g_variant_get (macaroon_variant, "(&s^as)", &macaroon, &discharges);
+
+       return snapd_auth_data_new (macaroon, discharges);
+}
+
+static SnapdClient *
+get_client (GsPlugin *plugin, GCancellable *cancellable, GError **error)
+{
+       g_autoptr(SnapdClient) client = NULL;
+       g_autoptr(SnapdAuthData) auth_data = NULL;
+
+       client = snapd_client_new ();
+       if (!snapd_client_connect_sync (client, cancellable, error))
+               return NULL;
+       auth_data = get_auth (plugin);
+       snapd_client_set_auth_data (client, auth_data);
+
+       return g_steal_pointer (&client);
 }
 
 static void
-refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package, gboolean from_search, GCancellable 
*cancellable)
+refine_app (GsPlugin *plugin, GsApp *app, SnapdSnap *snap, gboolean from_search, GCancellable *cancellable)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
        const gchar *status, *icon_url, *launch_name = NULL;
        g_autoptr(GdkPixbuf) icon_pixbuf = NULL;
+       GPtrArray *screenshots;
        gint64 size = -1;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-
-       status = json_object_get_string_member (package, "status");
-       if (g_strcmp0 (status, "installed") == 0 || g_strcmp0 (status, "active") == 0) {
-               const gchar *update_available;
-
-               update_available = json_object_has_member (package, "update_available") ?
-                       json_object_get_string_member (package, "update_available") : NULL;
-               if (update_available)
-                       gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
-               else {
-                       if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE)
-                               gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
-                       gs_app_set_state (app, AS_APP_STATE_INSTALLED);
-               }
-       } else if (g_strcmp0 (status, "not installed") == 0 || g_strcmp0 (status, "available") == 0) {
+       switch (snapd_snap_get_status (snap)) {
+       case SNAPD_SNAP_STATUS_INSTALLED:
+       case SNAPD_SNAP_STATUS_ACTIVE:
+               if (gs_app_get_state (app) == AS_APP_STATE_AVAILABLE)
+                       gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
+               gs_app_set_state (app, AS_APP_STATE_INSTALLED);
+               break;
+       case SNAPD_SNAP_STATUS_AVAILABLE:
+       case SNAPD_SNAP_STATUS_PRICED:
                gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
+               break;
+       default:
+               g_warning ("Ignoring snap with unknown state");
+               return;
        }
-       gs_app_set_name (app, GS_APP_QUALITY_HIGHEST,
-                        json_object_get_string_member (package, "summary"));
-       gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST,
-                           json_object_get_string_member (package, "summary"));
-       gs_app_set_description (app, GS_APP_QUALITY_HIGHEST,
-                               json_object_get_string_member (package, "description"));
-       gs_app_set_version (app, json_object_get_string_member (package, "version"));
-       if (json_object_has_member (package, "installed-size")) {
-               size = json_object_get_int_member (package, "installed-size");
-               if (size > 0)
-                       gs_app_set_size_installed (app, (guint64) size);
-       }
-       if (json_object_has_member (package, "download-size")) {
-               size = json_object_get_int_member (package, "download-size");
-               if (size > 0)
-                       gs_app_set_size_download (app, (guint64) size);
-       }
+       gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, snapd_snap_get_summary (snap));
+       gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST, snapd_snap_get_summary (snap));
+       gs_app_set_description (app, GS_APP_QUALITY_HIGHEST, snapd_snap_get_description (snap));
+       gs_app_set_version (app, snapd_snap_get_version (snap));
+       if (snapd_snap_get_installed_size (snap) > 0)
+               gs_app_set_size_installed (app, snapd_snap_get_installed_size (snap));
+       if (snapd_snap_get_download_size (snap) > 0)
+               gs_app_set_size_download (app, snapd_snap_get_download_size (snap));
        gs_app_add_quirk (app, AS_APP_QUIRK_PROVENANCE);
-       icon_url = json_object_get_string_member (package, "icon");
+       icon_url = snapd_snap_get_icon (snap);
        if (g_str_has_prefix (icon_url, "/")) {
-               g_autofree gchar *icon_data = NULL;
-               gsize icon_data_length;
+               g_autoptr(SnapdClient) client = NULL;
+               g_autoptr(SnapdIcon) icon = NULL;
                g_autoptr(GError) error = NULL;
 
-               icon_data = gs_snapd_get_resource (macaroon, discharges, icon_url, &icon_data_length, 
cancellable, &error);
-               if (icon_data != NULL) {
+               client = get_client (plugin, cancellable, &error);
+               if (client != NULL)
+                       icon = snapd_client_get_icon_sync (client, snapd_snap_get_name (snap), cancellable, 
&error);
+               if (icon != NULL) {
                        g_autoptr(GdkPixbufLoader) loader = NULL;
 
                        loader = gdk_pixbuf_loader_new ();
-                       gdk_pixbuf_loader_write (loader,
-                                                (guchar *) icon_data,
-                                                icon_data_length,
-                                                NULL);
+                       gdk_pixbuf_loader_write_bytes (loader,
+                                                      snapd_icon_get_data (icon),
+                                                      NULL);
                        gdk_pixbuf_loader_close (loader, NULL);
                        icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
                }
@@ -193,20 +194,19 @@ refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package, gboolean from_sea
                gs_app_add_icon (app, icon);
        }
 
-       if (json_object_has_member (package, "screenshots") && gs_app_get_screenshots (app)->len <= 0) {
-               JsonArray *screenshots;
+       screenshots = snapd_snap_get_screenshots (snap);
+       if (screenshots != NULL && gs_app_get_screenshots (app)->len <= 0) {
                guint i;
 
-               screenshots = json_object_get_array_member (package, "screenshots");
-               for (i = 0; i < json_array_get_length (screenshots); i++) {
-                       JsonObject *screenshot = json_array_get_object_element (screenshots, i);
+               for (i = 0; i < screenshots->len; i++) {
+                       SnapdScreenshot *screenshot = screenshots->pdata[i];
                        g_autoptr(AsScreenshot) ss = NULL;
                        g_autoptr(AsImage) image = NULL;
 
                        ss = as_screenshot_new ();
                        as_screenshot_set_kind (ss, AS_SCREENSHOT_KIND_NORMAL);
                        image = as_image_new ();
-                       as_image_set_url (image, json_object_get_string_member (screenshot, "url"));
+                       as_image_set_url (image, snapd_screenshot_get_url (screenshot));
                        as_image_set_kind (image, AS_IMAGE_KIND_SOURCE);
                        as_screenshot_add_image (ss, image);
                        gs_app_add_screenshot (app, ss);
@@ -214,13 +214,13 @@ refine_app (GsPlugin *plugin, GsApp *app, JsonObject *package, gboolean from_sea
        }
 
        if (!from_search) {
-               JsonArray *apps;
+               GPtrArray *apps;
 
-               apps = json_object_get_array_member (package, "apps");
-               if (apps && json_array_get_length (apps) > 0)
-                       launch_name = json_object_get_string_member (json_array_get_object_element (apps, 0), 
"name");
+               apps = snapd_snap_get_apps (snap);
+               if (apps->len > 0)
+                       launch_name = snapd_app_get_name (apps->pdata[0]);
 
-               if (launch_name)
+               if (launch_name != NULL)
                        gs_app_set_metadata (app, "snap::launch-name", launch_name);
                else
                        gs_app_add_quirk (app, AS_APP_QUIRK_NOT_LAUNCHABLE);
@@ -240,34 +240,32 @@ gs_plugin_add_installed (GsPlugin *plugin,
                         GCancellable *cancellable,
                         GError **error)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
-       g_autoptr(JsonArray) result = NULL;
+       g_autoptr(SnapdClient) client = NULL;
+       g_autoptr(GPtrArray) snaps = NULL;
        guint i;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-       result = gs_snapd_list (macaroon, discharges, cancellable, error);
-       if (result == NULL)
+       client = get_client (plugin, cancellable, error);
+       if (client == NULL)
+               return FALSE;
+       snaps = snapd_client_list_sync (client, cancellable, error);
+       if (snaps == NULL)
                return FALSE;
 
-       for (i = 0; i < json_array_get_length (result); i++) {
-               JsonObject *package = json_array_get_object_element (result, i);
+       for (i = 0; i < snaps->len; i++) {
+               SnapdSnap *snap = snaps->pdata[i];
                g_autoptr(GsApp) app = NULL;
-               const gchar *status, *name;
 
-               status = json_object_get_string_member (package, "status");
-               if (g_strcmp0 (status, "active") != 0)
+               if (snapd_snap_get_status (snap) != SNAPD_SNAP_STATUS_ACTIVE)
                        continue;
 
                /* create a unique ID for deduplication, TODO: branch? */
-               name = json_object_get_string_member (package, "name");
-               app = gs_app_new (name);
+               app = gs_app_new (snapd_snap_get_name (snap));
                gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_SNAP);
                gs_app_set_management_plugin (app, "snap");
                gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
                gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE);
-               refine_app (plugin, app, package, TRUE, cancellable);
+               refine_app (plugin, app, snap, TRUE, cancellable);
                gs_app_list_add (list, app);
        }
 
@@ -281,30 +279,32 @@ gs_plugin_add_search (GsPlugin *plugin,
                      GCancellable *cancellable,
                      GError **error)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
-       g_autoptr(JsonArray) result = NULL;
+       g_autoptr(SnapdClient) client = NULL;
+       g_autofree gchar *query = NULL;
+       g_autoptr(GPtrArray) snaps = NULL;
        guint i;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-       result = gs_snapd_find (macaroon, discharges, values, cancellable, error);
-       if (result == NULL)
+       client = get_client (plugin, cancellable, error);
+       if (client == NULL)
+               return FALSE;
+       query = g_strjoinv (" ", values);
+       snaps = snapd_client_find_sync (client, SNAPD_FIND_FLAGS_NONE, query, NULL, cancellable, error);
+       if (snaps == NULL)
                return FALSE;
 
-       for (i = 0; i < json_array_get_length (result); i++) {
-               JsonObject *package = json_array_get_object_element (result, i);
+       for (i = 0; i < snaps->len; i++) {
+               SnapdSnap *snap = snaps->pdata[i];
                g_autoptr(GsApp) app = NULL;
                const gchar *name;
 
                /* create a unique ID for deduplication, TODO: branch? */
-               name = json_object_get_string_member (package, "name");
-               app = gs_app_new (name);
+               app = gs_app_new (snapd_snap_get_name (snap));
                gs_app_set_scope (app, AS_APP_SCOPE_SYSTEM);
                gs_app_set_bundle_kind (app, AS_BUNDLE_KIND_SNAP);
                gs_app_set_management_plugin (app, "snap");
                gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
                gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE);
-               refine_app (plugin, app, package, TRUE, cancellable);
+               refine_app (plugin, app, snap, TRUE, cancellable);
                gs_app_list_add (list, app);
        }
 
@@ -318,51 +318,40 @@ gs_plugin_refine_app (GsPlugin *plugin,
                      GCancellable *cancellable,
                      GError **error)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
-       g_autoptr(JsonObject) result = NULL;
+       g_autoptr(SnapdClient) client = NULL;
+       g_autoptr(SnapdSnap) snap = NULL;
 
        /* not us */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0)
                return TRUE;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-
-       result = gs_snapd_list_one (macaroon, discharges, gs_app_get_id (app), cancellable, error);
-       if (result == NULL)
+       client = get_client (plugin, cancellable, error);
+       if (client == NULL)
+               return FALSE;
+       snap = snapd_client_list_one_sync (client, gs_app_get_id (app), cancellable, error);
+       if (snap == NULL)
                return FALSE;
-       refine_app (plugin, app, result, FALSE, cancellable);
+       refine_app (plugin, app, snap, FALSE, cancellable);
 
        return TRUE;
 }
 
 static void
-progress_cb (JsonObject *result, gpointer user_data)
+progress_cb (SnapdClient *client, SnapdChange *change, gpointer deprecated, gpointer user_data)
 {
        GsApp *app = user_data;
-       JsonArray *tasks;
-       GList *task_list, *l;
+       GPtrArray *tasks;
+       guint i;
        gint64 done = 0, total = 0;
 
-       tasks = json_object_get_array_member (result, "tasks");
-       task_list = json_array_get_elements (tasks);
-
-       for (l = task_list; l != NULL; l = l->next) {
-               JsonObject *task, *progress;
-               gint64 task_done, task_total;
-
-               task = json_node_get_object (l->data);
-               progress = json_object_get_object_member (task, "progress");
-               task_done = json_object_get_int_member (progress, "done");
-               task_total = json_object_get_int_member (progress, "total");
-
-               done += task_done;
-               total += task_total;
+       tasks = snapd_change_get_tasks (change);
+       for (i = 0; i < tasks->len; i++) {
+               SnapdTask *task = tasks->pdata[i];
+               done += snapd_task_get_progress_done (task);
+               total += snapd_task_get_progress_total (task);
        }
 
        gs_app_set_progress (app, (guint) (100 * done / total));
-
-       g_list_free (task_list);
 }
 
 gboolean
@@ -371,18 +360,17 @@ gs_plugin_app_install (GsPlugin *plugin,
                       GCancellable *cancellable,
                       GError **error)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
+       g_autoptr(SnapdClient) client = NULL;
 
        /* We can only install apps we know of */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0)
                return TRUE;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-
        gs_app_set_state (app, AS_APP_STATE_INSTALLING);
-       get_macaroon (plugin, &macaroon, &discharges);
-       if (!gs_snapd_install (macaroon, discharges, gs_app_get_id (app), progress_cb, app, cancellable, 
error)) {
+       client = get_client (plugin, cancellable, error);
+       if (client == NULL)
+               return FALSE;
+       if (!snapd_client_install_sync (client, gs_app_get_id (app), NULL, progress_cb, app, cancellable, 
error)) {
                gs_app_set_state_recover (app);
                return FALSE;
        }
@@ -394,29 +382,32 @@ gs_plugin_app_install (GsPlugin *plugin,
 // This doesn't necessarily mean that every binary uses this interfaces, but is probably true.
 // https://bugs.launchpad.net/bugs/1595023
 static gboolean
-is_graphical (GsApp *app, GCancellable *cancellable)
+is_graphical (GsPlugin *plugin, GsApp *app, GCancellable *cancellable)
 {
-       g_autoptr(JsonObject) result = NULL;
-       JsonArray *plugs;
+       g_autoptr(SnapdClient) client = NULL;
+       g_autoptr(GPtrArray) plugs = NULL;
        guint i;
        g_autoptr(GError) error = NULL;
 
-       result = gs_snapd_get_interfaces (NULL, NULL, cancellable, &error);
-       if (result == NULL) {
+       client = get_client (plugin, cancellable, &error);
+       if (client == NULL) {
+               g_warning ("Failed to make snapd client: %s", error->message);
+               return FALSE;
+       }
+       if (!snapd_client_get_interfaces_sync (client, &plugs, NULL, cancellable, &error)) {
                g_warning ("Failed to check interfaces: %s", error->message);
                return FALSE;
        }
 
-       plugs = json_object_get_array_member (result, "plugs");
-       for (i = 0; i < json_array_get_length (plugs); i++) {
-               JsonObject *plug = json_array_get_object_element (plugs, i);
+       for (i = 0; i < plugs->len; i++) {
+               SnapdPlug *plug = plugs->pdata[i];
                const gchar *interface;
 
                // Only looks at the plugs for this snap
-               if (g_strcmp0 (json_object_get_string_member (plug, "snap"), gs_app_get_id (app)) != 0)
+               if (g_strcmp0 (snapd_plug_get_snap (plug), gs_app_get_id (app)) != 0)
                        continue;
 
-               interface = json_object_get_string_member (plug, "interface");
+               interface = snapd_plug_get_interface (plug);
                if (interface == NULL)
                        continue;
 
@@ -451,7 +442,7 @@ gs_plugin_launch (GsPlugin *plugin,
        else
                binary_name = g_strdup_printf ("/snap/bin/%s.%s", gs_app_get_id (app), launch_name);
 
-       if (!is_graphical (app, cancellable))
+       if (!is_graphical (plugin, app, cancellable))
                flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL;
        info = g_app_info_create_from_commandline (binary_name, NULL, flags, error);
        if (info == NULL)
@@ -466,17 +457,17 @@ gs_plugin_app_remove (GsPlugin *plugin,
                      GCancellable *cancellable,
                      GError **error)
 {
-       g_autofree gchar *macaroon = NULL;
-       g_auto(GStrv) discharges = NULL;
+       g_autoptr(SnapdClient) client = NULL;
 
        /* We can only remove apps we know of */
        if (g_strcmp0 (gs_app_get_management_plugin (app), "snap") != 0)
                return TRUE;
 
-       get_macaroon (plugin, &macaroon, &discharges);
-
        gs_app_set_state (app, AS_APP_STATE_REMOVING);
-       if (!gs_snapd_remove (macaroon, discharges, gs_app_get_id (app), progress_cb, app, cancellable, 
error)) {
+       client = get_client (plugin, cancellable, error);
+       if (client == NULL)
+               return FALSE;
+       if (!snapd_client_remove_sync (client, gs_app_get_id (app), progress_cb, app, cancellable, error)) {
                gs_app_set_state_recover (app);
                return FALSE;
        }
diff --git a/src/plugins/meson.build b/src/plugins/meson.build
index 24a0ad4..ba2a6cd 100644
--- a/src/plugins/meson.build
+++ b/src/plugins/meson.build
@@ -544,8 +544,7 @@ endif
 if get_option('enable-snap')
   shared_module('gs_plugin_snap',
     sources : [
-      'gs-plugin-snap.c',
-      'gs-snapd.c'
+      'gs-plugin-snap.c'
     ],
     include_directories : [
       include_directories('..'),


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