Factor out summary loading

This commit is contained in:
Matthias Clasen
2015-02-09 15:21:23 +01:00
parent 4ff10fee86
commit 4571eb85f7
3 changed files with 122 additions and 84 deletions

View File

@@ -6,7 +6,6 @@
#include <string.h>
#include "libgsystem.h"
#include <libsoup/soup.h>
#include "xdg-app-builtins.h"
#include "xdg-app-utils.h"
@@ -24,50 +23,6 @@ static GOptionEntry options[] = {
{ NULL }
};
static gboolean
load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
gs_free char *scheme = NULL;
scheme = g_uri_parse_scheme (uri);
if (strcmp (scheme, "file") == 0)
{
char *buffer;
gsize length;
gs_unref_object GFile *file = NULL;
g_debug ("Loading summary %s using GIO", uri);
file = g_file_new_for_uri (uri);
if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL))
goto out;
*contents = g_bytes_new_take (buffer, length);
}
else
{
gs_unref_object SoupSession *session = NULL;
gs_unref_object SoupMessage *msg = NULL;
g_debug ("Loading summary %s using libsoup", uri);
session = soup_session_new ();
msg = soup_message_new ("GET", uri);
soup_session_send_message (session, msg);
if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
goto out;
*contents = g_bytes_new (msg->response_body->data, msg->response_body->length);
}
ret = TRUE;
g_debug ("Received %ld bytes", g_bytes_get_size (*contents));
out:
return ret;
}
gboolean
xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable, GError **error)
{
@@ -76,6 +31,7 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable,
gs_unref_object XdgAppDir *dir = NULL;
gs_unref_object OstreeRepo *repo = NULL;
gs_unref_hashtable GHashTable *refs = NULL;
gs_free char *title = NULL;
GHashTableIter iter;
gpointer key;
gpointer value;
@@ -100,47 +56,9 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable,
repository = argv[1];
repo = xdg_app_dir_get_repo (dir);
if (!ostree_repo_remote_get_url (repo, repository, &url, error))
if (!ostree_repo_load_summary (repo, repository, &refs, &title, cancellable, error))
goto out;
summary_url = g_build_filename (url, "summary", NULL);
if (load_contents (summary_url, &bytes, cancellable, NULL))
{
gs_unref_variant GVariant *summary;
gs_unref_variant GVariant *ref_list;
int n;
refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE);
ref_list = g_variant_get_child_value (summary, 0);
n = g_variant_n_children (ref_list);
g_debug ("Summary contains %d refs", n);
for (i = 0; i < n; i++)
{
gs_unref_variant GVariant *ref = NULL;
gs_unref_variant GVariant *csum_v = NULL;
char *refname;
char *checksum;
ref = g_variant_get_child_value (ref_list, i);
g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL);
if (!ostree_validate_rev (refname, error))
goto out;
checksum = ostree_checksum_from_bytes_v (csum_v);
g_debug ("%s summary: %s -> %s\n", repository, refname, checksum);
g_hash_table_insert (refs, g_strdup (refname), checksum);
}
}
else
{
g_printerr ("Failed to load summary file for remote %s, listing local refs\n", repository);
if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error))
goto out;
}
names = g_ptr_array_new_with_free_func (g_free);
g_hash_table_iter_init (&iter, refs);

View File

@@ -5,6 +5,7 @@
#include <glib.h>
#include "libgsystem.h"
#include <libsoup/soup.h>
#include <stdlib.h>
#include <errno.h>
@@ -343,3 +344,114 @@ xdg_app_remove_dangling_symlinks (GFile *dir,
out:
return ret;
}
static gboolean
load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error)
{
gboolean ret = FALSE;
gs_free char *scheme = NULL;
scheme = g_uri_parse_scheme (uri);
if (strcmp (scheme, "file") == 0)
{
char *buffer;
gsize length;
gs_unref_object GFile *file = NULL;
g_debug ("Loading summary %s using GIO", uri);
file = g_file_new_for_uri (uri);
if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL))
goto out;
*contents = g_bytes_new_take (buffer, length);
}
else
{
gs_unref_object SoupSession *session = NULL;
gs_unref_object SoupMessage *msg = NULL;
g_debug ("Loading summary %s using libsoup", uri);
session = soup_session_new ();
msg = soup_message_new ("GET", uri);
soup_session_send_message (session, msg);
if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
goto out;
*contents = g_bytes_new (msg->response_body->data, msg->response_body->length);
}
ret = TRUE;
g_debug ("Received %ld bytes", g_bytes_get_size (*contents));
out:
return ret;
}
gboolean
ostree_repo_load_summary (OstreeRepo *repo,
const char *repository,
GHashTable **refs,
gchar **title,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
gs_free char *url = NULL;
gs_free char *summary_url = NULL;
gs_unref_bytes GBytes *bytes = NULL;
gs_unref_hashtable GHashTable *local_refs = NULL;
gs_free char *local_title = NULL;
if (!ostree_repo_remote_get_url (repo, repository, &url, error))
goto out;
summary_url = g_build_filename (url, "summary", NULL);
if (load_contents (summary_url, &bytes, cancellable, NULL))
{
gs_unref_variant GVariant *summary;
gs_unref_variant GVariant *ref_list;
gs_unref_variant GVariant *extensions;
GVariantDict dict;
int i, n;
local_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE);
ref_list = g_variant_get_child_value (summary, 0);
extensions = g_variant_get_child_value (summary, 1);
n = g_variant_n_children (ref_list);
g_debug ("Summary contains %d refs", n);
for (i = 0; i < n; i++)
{
gs_unref_variant GVariant *ref = NULL;
gs_unref_variant GVariant *csum_v = NULL;
char *refname;
char *checksum;
ref = g_variant_get_child_value (ref_list, i);
g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL);
if (!ostree_validate_rev (refname, error))
goto out;
checksum = ostree_checksum_from_bytes_v (csum_v);
g_debug ("%s summary: %s -> %s", repository, refname, checksum);
g_hash_table_insert (local_refs, g_strdup (refname), checksum);
}
g_variant_dict_init (&dict, extensions);
g_variant_dict_lookup (&dict, "xa.title", "s", &local_title);
g_debug ("%s summary: title %s", repository, local_title);
g_variant_dict_end (&dict);
}
*refs = g_hash_table_ref (local_refs);
*title = g_strdup (local_title);
ret = TRUE;
out:
return ret;
}

View File

@@ -2,6 +2,7 @@
#define __XDG_APP_UTILS_H__
#include <gio/gio.h>
#include <ostree.h>
const char * xdg_app_get_arch (void);
@@ -33,6 +34,13 @@ gboolean xdg_app_remove_dangling_symlinks (GFile *dir,
GCancellable *cancellable,
GError **error);
gboolean ostree_repo_load_summary (OstreeRepo *repo,
const char *repository,
GHashTable **refs,
gchar **title,
GCancellable *cancellable,
GError **error);
#if !GLIB_CHECK_VERSION(2,43,1)
static inline gboolean
g_strv_contains (const gchar * const *strv,