[gnome-software] Add gs_plugin_download_data()
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add gs_plugin_download_data()
- Date: Tue, 12 Apr 2016 13:29:36 +0000 (UTC)
commit 7fb0a391ed7245c2c4344adeff95ffe7ce3da546
Author: Richard Hughes <richard hughsie com>
Date: Tue Apr 12 11:39:19 2016 +0100
Add gs_plugin_download_data()
This allows us to do the progress changed logic in one place.
src/gs-plugin.c | 137 ++++++++++++++++++++++++++++++
src/gs-plugin.h | 11 +++
src/plugins/gs-plugin-fwupd.c | 54 +++++--------
src/plugins/gs-plugin-shell-extensions.c | 34 +++----
src/plugins/gs-plugin-steam.c | 74 ++++-------------
5 files changed, 199 insertions(+), 111 deletions(-)
---
diff --git a/src/gs-plugin.c b/src/gs-plugin.c
index ebb85b0..3957dad 100644
--- a/src/gs-plugin.c
+++ b/src/gs-plugin.c
@@ -391,4 +391,141 @@ gs_plugin_updates_changed (GsPlugin *plugin)
g_idle_add (gs_plugin_updates_changed_cb, plugin);
}
+typedef struct {
+ GsPlugin *plugin;
+ GsApp *app;
+ GCancellable *cancellable;
+} GsPluginDownloadHelper;
+
+/**
+ * gs_plugin_download_chunk_cb:
+ **/
+static void
+gs_plugin_download_chunk_cb (SoupMessage *msg, SoupBuffer *chunk,
+ GsPluginDownloadHelper *helper)
+{
+ guint percentage;
+ goffset header_size;
+ goffset body_length;
+
+ /* cancelled? */
+ if (g_cancellable_is_cancelled (helper->cancellable)) {
+ g_debug ("cancelling download of %s",
+ gs_app_get_id (helper->app));
+ soup_session_cancel_message (helper->plugin->soup_session,
+ msg,
+ SOUP_STATUS_CANCELLED);
+ return;
+ }
+
+ /* if it's returning "Found" or an error, ignore the percentage */
+ if (msg->status_code != SOUP_STATUS_OK) {
+ g_debug ("ignoring status code %i (%s)",
+ msg->status_code, msg->reason_phrase);
+ return;
+ }
+
+ /* get data */
+ body_length = msg->response_body->length;
+ header_size = soup_message_headers_get_content_length (msg->response_headers);
+
+ /* size is not known */
+ if (header_size < body_length)
+ return;
+
+ /* calulate percentage */
+ percentage = (100 * body_length) / header_size;
+ g_debug ("%s progress: %i%%", gs_app_get_id (helper->app), percentage);
+ gs_app_set_progress (helper->app, percentage);
+ gs_plugin_status_update (helper->plugin,
+ helper->app,
+ GS_PLUGIN_STATUS_DOWNLOADING);
+}
+
+/**
+ * gs_plugin_download_data:
+ */
+GBytes *
+gs_plugin_download_data (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginDownloadHelper helper;
+ guint status_code;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ g_debug ("downloading %s from %s", uri, plugin->name);
+ msg = soup_message_new (SOUP_METHOD_GET, uri);
+ if (app != NULL) {
+ helper.plugin = plugin;
+ helper.app = app;
+ helper.cancellable = cancellable;
+ g_signal_connect (msg, "got-chunk",
+ G_CALLBACK (gs_plugin_download_chunk_cb),
+ &helper);
+ }
+ status_code = soup_session_send_message (plugin->soup_session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to get shell extensions: %s",
+ msg->response_body->data);
+ return NULL;
+ }
+ return g_bytes_new (msg->response_body->data,
+ msg->response_body->length);
+}
+
+/**
+ * gs_plugin_download_file:
+ */
+gboolean
+gs_plugin_download_file (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *uri,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginDownloadHelper helper;
+ guint status_code;
+ g_autoptr(GError) error_local = NULL;
+ g_autoptr(SoupMessage) msg = NULL;
+
+ g_debug ("downloading %s to %s from %s", uri, filename, plugin->name);
+ msg = soup_message_new (SOUP_METHOD_GET, uri);
+ if (app != NULL) {
+ helper.plugin = plugin;
+ helper.app = app;
+ helper.cancellable = cancellable;
+ g_signal_connect (msg, "got-chunk",
+ G_CALLBACK (gs_plugin_download_chunk_cb),
+ &helper);
+ }
+ status_code = soup_session_send_message (plugin->soup_session, msg);
+ if (status_code != SOUP_STATUS_OK) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to get shell extensions: %s",
+ msg->response_body->data);
+ return FALSE;
+ }
+ if (!g_file_set_contents (filename,
+ msg->response_body->data,
+ msg->response_body->length,
+ &error_local)) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "Failed to save firmware: %s",
+ error_local->message);
+ return FALSE;
+ }
+ return TRUE;
+}
+
/* vim: set noexpandtab: */
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 814cd43..26c06c9 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -205,6 +205,17 @@ void gs_plugin_initialize (GsPlugin *plugin);
void gs_plugin_destroy (GsPlugin *plugin);
void gs_plugin_set_enabled (GsPlugin *plugin,
gboolean enabled);
+GBytes *gs_plugin_download_data (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GError **error);
+gboolean gs_plugin_download_file (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *uri,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GError **error);
gboolean gs_plugin_check_distro_id (GsPlugin *plugin,
const gchar *distro_id);
void gs_plugin_add_app (GList **list,
diff --git a/src/plugins/gs-plugin-fwupd.c b/src/plugins/gs-plugin-fwupd.c
index 1a137c0..dd5a120 100644
--- a/src/plugins/gs-plugin-fwupd.c
+++ b/src/plugins/gs-plugin-fwupd.c
@@ -455,16 +455,15 @@ gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
- guint status_code;
g_autoptr(GError) error_local = NULL;
g_autofree gchar *basename_data = NULL;
g_autofree gchar *cache_fn_data = NULL;
g_autofree gchar *checksum = NULL;
g_autofree gchar *url_data = NULL;
g_autofree gchar *url_sig = NULL;
+ g_autoptr(GBytes) data = NULL;
g_autoptr(GKeyFile) config = NULL;
- g_autoptr(SoupMessage) msg_data = NULL;
- g_autoptr(SoupMessage) msg_sig = NULL;
+ g_autoptr(GsApp) app_dl = gs_app_new (plugin->name);
/* read config file */
config = g_key_file_new ();
@@ -491,18 +490,18 @@ gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
/* download the signature first, it's smaller */
url_sig = g_strdup_printf ("%s.asc", url_data);
- msg_sig = soup_message_new (SOUP_METHOD_GET, url_sig);
- status_code = soup_session_send_message (plugin->soup_session, msg_sig);
- if (status_code != SOUP_STATUS_OK) {
- g_warning ("Failed to download %s, ignoring: %s",
- url_sig, soup_status_get_phrase (status_code));
- return TRUE;
- }
+ data = gs_plugin_download_data (plugin,
+ app_dl,
+ url_sig,
+ cancellable,
+ error);
+ if (data == NULL)
+ return FALSE;
/* is the signature hash the same as we had before? */
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1,
- (const guchar *) msg_sig->response_body->data,
- msg_sig->response_body->length);
+ (const guchar *) g_bytes_get_data (data, NULL),
+ g_bytes_get_size (data));
if (g_strcmp0 (checksum, plugin->priv->lvfs_sig_hash) == 0) {
g_debug ("signature of %s is unchanged", url_sig);
return TRUE;
@@ -511,8 +510,8 @@ gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
/* save to a file */
g_debug ("saving new LVFS signature to %s:", plugin->priv->lvfs_sig_fn);
if (!g_file_set_contents (plugin->priv->lvfs_sig_fn,
- msg_sig->response_body->data,
- msg_sig->response_body->length,
+ g_bytes_get_data (data, NULL),
+ g_bytes_get_size (data),
&error_local)) {
g_set_error (error,
GS_PLUGIN_ERROR,
@@ -526,30 +525,17 @@ gs_plugin_fwupd_check_lvfs_metadata (GsPlugin *plugin,
g_free (plugin->priv->lvfs_sig_hash);
plugin->priv->lvfs_sig_hash = g_strdup (checksum);
- /* download the payload */
- msg_data = soup_message_new (SOUP_METHOD_GET, url_data);
- status_code = soup_session_send_message (plugin->soup_session, msg_data);
- if (status_code != SOUP_STATUS_OK) {
- g_warning ("Failed to download %s, ignoring: %s",
- url_data, soup_status_get_phrase (status_code));
- return TRUE;
- }
-
- /* save to a file */
+ /* download the payload and save to file */
basename_data = g_path_get_basename (url_data);
cache_fn_data = g_build_filename (plugin->priv->cachedir, basename_data, NULL);
g_debug ("saving new LVFS data to %s:", cache_fn_data);
- if (!g_file_set_contents (cache_fn_data,
- msg_data->response_body->data,
- msg_data->response_body->length,
- &error_local)) {
- g_set_error (error,
- GS_PLUGIN_ERROR,
- GS_PLUGIN_ERROR_FAILED,
- "Failed to save firmware: %s",
- error_local->message);
+ if (!gs_plugin_download_file (plugin,
+ app_dl,
+ url_data,
+ cache_fn_data,
+ cancellable,
+ error))
return FALSE;
- }
/* phew, lets send all this to fwupd */
if (!fwupd_client_update_metadata (plugin->priv->client,
diff --git a/src/plugins/gs-plugin-shell-extensions.c b/src/plugins/gs-plugin-shell-extensions.c
index 924af4e..0651fbb 100644
--- a/src/plugins/gs-plugin-shell-extensions.c
+++ b/src/plugins/gs-plugin-shell-extensions.c
@@ -574,16 +574,16 @@ gs_plugin_shell_extensions_parse_apps (GsPlugin *plugin,
static GPtrArray *
gs_plugin_shell_extensions_get_apps (GsPlugin *plugin,
guint cache_age,
+ GCancellable *cancellable,
GError **error)
{
GPtrArray *apps;
- guint status_code;
g_autofree gchar *cachedir = NULL;
g_autofree gchar *cachefn = NULL;
- g_autofree gchar *data = NULL;
g_autofree gchar *uri = NULL;
g_autoptr(GFile) cachefn_file = NULL;
- g_autoptr(SoupMessage) msg = NULL;
+ g_autoptr(GBytes) data = NULL;
+ g_autoptr(GsApp) dummy = gs_app_new (plugin->name);
/* look in the cache */
cachedir = gs_utils_get_cachedir ("extensions", error);
@@ -607,36 +607,29 @@ gs_plugin_shell_extensions_get_apps (GsPlugin *plugin,
"&page=1&n_per_page=1000",
SHELL_EXTENSIONS_API_URI,
plugin->priv->shell_version);
- msg = soup_message_new (SOUP_METHOD_GET, uri);
- status_code = soup_session_send_message (plugin->soup_session, msg);
- if (status_code != SOUP_STATUS_OK) {
- g_set_error (error,
- GS_PLUGIN_ERROR,
- GS_PLUGIN_ERROR_FAILED,
- "failed to get shell extensions: %s",
- msg->response_body->data);
+ data = gs_plugin_download_data (plugin, dummy, uri, cancellable, error);
+ if (data == NULL)
return NULL;
- }
apps = gs_plugin_shell_extensions_parse_apps (plugin,
- msg->response_body->data,
- msg->response_body->length,
+ g_bytes_get_data (data, NULL),
+ g_bytes_get_size (data),
error);
if (apps == NULL) {
- guint len = msg->response_body->length;
+ guint len = g_bytes_get_size (data);
g_autofree gchar *tmp = NULL;
/* truncate the string if long */
if (len > 100)
len = 100;
- tmp = g_strndup (msg->response_body->data, len);
+ tmp = g_strndup (g_bytes_get_data (data, NULL), len);
g_prefix_error (error, "Failed to parse '%s': ", tmp);
return NULL;
}
/* save to the cache */
if (!g_file_set_contents (cachefn,
- msg->response_body->data,
- msg->response_body->length,
+ g_bytes_get_data (data, NULL),
+ g_bytes_get_size (data),
error))
return NULL;
@@ -680,7 +673,10 @@ gs_plugin_refresh (GsPlugin *plugin,
}
/* get data */
- apps = gs_plugin_shell_extensions_get_apps (plugin, cache_age, error);
+ apps = gs_plugin_shell_extensions_get_apps (plugin,
+ cache_age,
+ cancellable,
+ error);
if (apps == NULL)
return FALSE;
diff --git a/src/plugins/gs-plugin-steam.c b/src/plugins/gs-plugin-steam.c
index b1dc8b1..570353b 100644
--- a/src/plugins/gs-plugin-steam.c
+++ b/src/plugins/gs-plugin-steam.c
@@ -38,50 +38,6 @@ gs_plugin_get_name (void)
}
/**
- * gs_plugin_steam_html_download:
- */
-static gboolean
-gs_plugin_steam_html_download (GsPlugin *plugin,
- const gchar *uri,
- gchar **data,
- gsize *data_len,
- GError **error)
-{
- guint status_code;
- g_autoptr(GInputStream) stream = NULL;
- g_autoptr(SoupMessage) msg = NULL;
-
- /* create the GET data */
- msg = soup_message_new (SOUP_METHOD_GET, uri);
- if (msg == NULL) {
- g_set_error (error,
- GS_PLUGIN_ERROR,
- GS_PLUGIN_ERROR_FAILED,
- "%s is not a valid URL", uri);
- return FALSE;
- }
-
- /* set sync request */
- status_code = soup_session_send_message (plugin->soup_session, msg);
- if (status_code != SOUP_STATUS_OK) {
- g_set_error (error,
- GS_PLUGIN_ERROR,
- GS_PLUGIN_ERROR_FAILED,
- "Failed to download icon %s: %s",
- uri, soup_status_get_phrase (status_code));
- return FALSE;
- }
-
- /* return data */
- if (data != NULL)
- *data = g_memdup (msg->response_body->data,
- msg->response_body->length);
- if (data_len != NULL)
- *data_len = msg->response_body->length;
- return TRUE;
-}
-
-/**
* gs_plugin_order_after:
*/
const gchar **
@@ -469,15 +425,14 @@ gs_plugin_steam_download_icon (GsPlugin *plugin,
if (!g_file_get_contents (cache_fn, &data, &data_len, error))
return FALSE;
} else {
- if (!gs_plugin_steam_html_download (plugin,
- uri,
- &data,
- &data_len,
- error))
- return FALSE;
if (!gs_mkdir_parent (cache_fn, error))
return FALSE;
- if (!g_file_set_contents (cache_fn, data, data_len, error))
+ if (!gs_plugin_download_file (plugin,
+ NULL, /* GsApp */
+ uri,
+ cache_fn,
+ NULL, /* GCancellable */
+ error))
return FALSE;
}
@@ -668,18 +623,21 @@ gs_plugin_steam_update_store_app (GsPlugin *plugin,
if (cachedir == NULL)
return FALSE;
cache_fn = g_build_filename (cachedir, cache_basename, NULL);
- if (g_file_test (cache_fn, G_FILE_TEST_EXISTS)) {
- if (!g_file_get_contents (cache_fn, &html, NULL, error))
- return FALSE;
- } else {
+ if (!g_file_test (cache_fn, G_FILE_TEST_EXISTS)) {
+ g_autoptr(GsApp) app_dl = gs_app_new (plugin->name);
uri = g_strdup_printf ("http://store.steampowered.com/app/%s/", gameid_str);
- if (!gs_plugin_steam_html_download (plugin, uri, &html, NULL, error))
- return FALSE;
- if (!g_file_set_contents (cache_fn, html, -1, error))
+ if (!gs_plugin_download_file (plugin,
+ app_dl,
+ uri,
+ cache_fn,
+ NULL, /* GCancellable */
+ error))
return FALSE;
}
/* get screenshots and descriptions */
+ if (!g_file_get_contents (cache_fn, &html, NULL, error))
+ return FALSE;
if (!gs_plugin_steam_update_screenshots (item, html, error))
return FALSE;
if (!gs_plugin_steam_update_description (item, html, error))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]