[libgrss] Utilities to fetch enclosures (both sync and async)
- From: Roberto Guido <rguido src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgrss] Utilities to fetch enclosures (both sync and async)
- Date: Wed, 25 Dec 2013 16:53:02 +0000 (UTC)
commit c8500f37fcba1b2b7f9bbeaa9ef62813af07f9eb
Author: Roberto Guido <bob4job gmail com>
Date: Wed Dec 25 17:52:06 2013 +0100
Utilities to fetch enclosures (both sync and async)
src/feed-enclosure.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++-
src/feed-enclosure.h | 4 +
2 files changed, 159 insertions(+), 1 deletions(-)
---
diff --git a/src/feed-enclosure.c b/src/feed-enclosure.c
index 3ed0c71..312f2b3 100644
--- a/src/feed-enclosure.c
+++ b/src/feed-enclosure.c
@@ -21,7 +21,8 @@
#include "utils.h"
#include "feed-enclosure.h"
-#define FEED_ENCLOSURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GRSS_FEED_ENCLOSURE_TYPE,
GrssFeedEnclosurePrivate))
+#define FEED_ENCLOSURE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj),
GRSS_FEED_ENCLOSURE_TYPE, GrssFeedEnclosurePrivate))
+#define FEED_ENCLOSURE_ERROR feed_enclosure_error_quark()
/**
* SECTION: feed-enclosure
@@ -38,8 +39,19 @@ struct _GrssFeedEnclosurePrivate {
gsize length;
};
+enum {
+ FEED_ENCLOSURE_FETCH_ERROR,
+ FEED_ENCLOSURE_FILE_ERROR,
+};
+
G_DEFINE_TYPE (GrssFeedEnclosure, grss_feed_enclosure, G_TYPE_OBJECT);
+static GQuark
+feed_enclosure_error_quark ()
+{
+ return g_quark_from_static_string ("feed_enclosure_error");
+}
+
static void grss_feed_enclosure_finalize (GObject *obj)
{
GrssFeedEnclosure *enclosure;
@@ -145,3 +157,145 @@ gsize grss_feed_enclosure_get_length (GrssFeedEnclosure *enclosure)
{
return enclosure->priv->length;
}
+
+static GFile*
+msg_to_internal_file (GrssFeedEnclosure *enclosure, SoupMessage *msg, GError **error)
+{
+ gboolean test;
+ GFile *ret;
+ GFileIOStream *stream;
+ GOutputStream *stream_out;
+
+ ret = g_file_new_tmp ("enclosure_XXXXXX", &stream, error);
+
+ if (ret != NULL) {
+ stream_out = g_io_stream_get_output_stream (G_IO_STREAM (stream));
+ test = g_output_stream_write_all (stream_out, msg->response_body->data,
msg->response_body->length,
+ NULL, NULL, error);
+
+ if (test == FALSE) {
+ g_object_unref (ret);
+ ret = NULL;
+ }
+
+ g_object_unref (stream_out);
+ g_object_unref (stream);
+ }
+
+ return ret;
+}
+
+/**
+ * grss_feed_enclosure_fetch:
+ * @enclosure: a #GrssFeedEnclosure.
+ * @error: if an error occourred, %NULL is returned and this is filled with the
+ * message.
+ *
+ * Utility to fetch a #GrssFeedEnclosure. Contents are stored in a temporary
+ * #GFile, which is suggested to move on a permanent location to keep it over
+ * time.
+ *
+ * Return value: (transfer full): temporary file where the contents have been
+ * written, or %NULL if an error occours.
+ */
+GFile*
+grss_feed_enclosure_fetch (GrssFeedEnclosure *enclosure, GError **error)
+{
+ const gchar *url;
+ guint status;
+ GFile *ret;
+ SoupMessage *msg;
+ SoupSession *session;
+
+ ret = NULL;
+ url = grss_feed_enclosure_get_url (enclosure);
+
+ session = soup_session_sync_new ();
+ msg = soup_message_new ("GET", url);
+ status = soup_session_send_message (session, msg);
+
+ if (status >= 200 && status <= 299)
+ ret = msg_to_internal_file (enclosure, msg, error);
+ else
+ g_set_error (error, FEED_ENCLOSURE_ERROR, FEED_ENCLOSURE_FETCH_ERROR,
+ "Unable to download from %s", url);
+
+ g_object_unref (session);
+ g_object_unref (msg);
+ return ret;
+}
+
+static void
+enclosure_downloaded (SoupSession *session, SoupMessage *msg, gpointer user_data) {
+ guint status;
+ const gchar *url;
+ GFile *file;
+ GSimpleAsyncResult *result;
+ GrssFeedEnclosure *enclosure;
+ GError *error;
+
+ result = user_data;
+ enclosure = GRSS_FEED_ENCLOSURE (g_async_result_get_source_object (G_ASYNC_RESULT (result)));
+ url = grss_feed_enclosure_get_url (enclosure);
+ g_object_get (msg, "status-code", &status, NULL);
+
+ if (status >= 200 && status <= 299) {
+ error = NULL;
+ file = msg_to_internal_file (enclosure, msg, &error);
+
+ if (file != NULL)
+ g_simple_async_result_set_op_res_gpointer (result, file, g_object_unref);
+ else
+ g_simple_async_result_take_error (result, error);
+ }
+ else {
+ g_simple_async_result_set_error (result, FEED_ENCLOSURE_ERROR, FEED_ENCLOSURE_FETCH_ERROR,
+ "Unable to download from %s", url);
+ }
+
+ g_simple_async_result_complete_in_idle (result);
+ g_object_unref (result);
+}
+
+/**
+ * grss_feed_enclosure_fetch_async:
+ * @enclosure: a #GrssFeedEnclosure.
+ * @callback: function to invoke at the end of the download.
+ * @user_data: data passed to the callback.
+ *
+ * Similar to grss_feed_enclosure_fetch(), but asyncronous.
+ */
+void
+grss_feed_enclosure_fetch_async (GrssFeedEnclosure *enclosure, GAsyncReadyCallback callback, gpointer
user_data)
+{
+ GSimpleAsyncResult *result;
+ SoupMessage *msg;
+ SoupSession *session;
+
+ result = g_simple_async_result_new (G_OBJECT (enclosure), callback, user_data,
grss_feed_enclosure_fetch_async);
+ session = soup_session_async_new ();
+ msg = soup_message_new ("GET", grss_feed_enclosure_get_url (enclosure));
+ soup_session_queue_message (session, msg, enclosure_downloaded, result);
+}
+
+/**
+ * grss_feed_enclosure_fetch_finish:
+ * @enclosure: a #GrssFeedEnclosure.
+ * @res: the #GAsyncResult passed to the callback.
+ * @error: if an error occourred, %NULL is returned and this is filled with the
+ * message.
+ *
+ * Finalizes an asyncronous operation started with
+ * grss_feed_enclosure_fetch_async().
+ *
+ * Return value: (transfer full): temporary file where the contents have been
+ * written, or %NULL if an error occours.
+ */
+GFile*
+grss_feed_enclosure_fetch_finish (GrssFeedEnclosure *enclosure, GAsyncResult *res, GError **error)
+{
+ if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
+ return NULL;
+ else
+ return (GFile*) g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
+}
diff --git a/src/feed-enclosure.h b/src/feed-enclosure.h
index 17b2d9f..7bba3b8 100644
--- a/src/feed-enclosure.h
+++ b/src/feed-enclosure.h
@@ -52,4 +52,8 @@ const gchar* grss_feed_enclosure_get_format (GrssFeedEnclosure *enclosure);
void grss_feed_enclosure_set_length (GrssFeedEnclosure *enclosure, gsize length);
gsize grss_feed_enclosure_get_length (GrssFeedEnclosure *enclosure);
+GFile* grss_feed_enclosure_fetch (GrssFeedEnclosure *enclosure, GError
**error);
+void grss_feed_enclosure_fetch_async (GrssFeedEnclosure *enclosure,
GAsyncReadyCallback callback, gpointer user_data);
+GFile* grss_feed_enclosure_fetch_finish (GrssFeedEnclosure *enclosure, GAsyncResult
*res, GError **error);
+
#endif /* __FEED_ENCLOSURE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]