[discident-glib] lib: Add async versions of the EAN lookup functions



commit 4c718645e4bc4e29dad5a8669883575655ba8f22
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Dec 6 00:38:07 2012 +0100

    lib: Add async versions of the EAN lookup functions

 discident-glib/discident-ean-glib.c   |  192 +++++++++++++++++++++++++++++++++
 discident-glib/discident-ean-glib.h   |   10 ++
 discident-glib/discident-glib.symbols |    2 +
 3 files changed, 204 insertions(+), 0 deletions(-)
---
diff --git a/discident-glib/discident-ean-glib.c b/discident-glib/discident-ean-glib.c
index 3e90a4d..e75c4ac 100644
--- a/discident-glib/discident-ean-glib.c
+++ b/discident-glib/discident-ean-glib.c
@@ -354,6 +354,198 @@ discident_ean_lookup_sync (DiscidentEan *ean,
 	return TRUE;
 }
 
+typedef struct {
+	DiscidentEan       *ean;
+	GSimpleAsyncResult *simple;
+	SoupSession        *session;
+	char               *barcode;
+} QueryData;
+
+static void
+free_query_data (QueryData *data)
+{
+	g_object_unref (data->ean);
+	g_object_unref (data->session);
+	g_free (data->barcode);
+	g_free (data);
+}
+
+static void
+got_body_query (SoupMessage *msg,
+		QueryData   *data)
+{
+	char *response;
+	char *title;
+	char *img_url;
+
+	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) ||
+	    msg->response_body == NULL) {
+		g_simple_async_result_set_error (data->simple,
+						 SOUP_HTTP_ERROR,
+						 msg->status_code,
+						 "Could not query EAN service: %s",
+						 soup_status_get_phrase (msg->status_code));
+		goto out;
+	}
+
+	response = uncompress (msg->response_body->data,
+			       msg->response_body->length);
+
+	if (parse_lookup_response (response, &title, &img_url) == FALSE) {
+		g_simple_async_result_set_error (data->simple,
+						 DISCIDENT_ERROR,
+						 DISCIDENT_ERROR_PARSE,
+						 "Failed to parse response from EAN service");
+		g_free (response);
+		goto out;
+	}
+	g_free (response);
+
+	g_object_set_data_full (G_OBJECT (data->simple), "image-url", img_url, g_free);
+	g_simple_async_result_set_op_res_gpointer (data->simple, title, NULL);
+
+out:
+	g_simple_async_result_complete_in_idle (data->simple);
+	free_query_data (data);
+}
+
+static void
+got_body_login (SoupMessage *msg,
+		QueryData   *data)
+{
+	char *response;
+	SoupMessage *query_msg;
+
+	if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code) ||
+	    msg->response_body == NULL) {
+		g_simple_async_result_set_error (data->simple,
+						 SOUP_HTTP_ERROR,
+						 msg->status_code,
+						 "Could not login to EAN service: %s",
+						 soup_status_get_phrase (msg->status_code));
+		goto error;
+	}
+
+	response = g_strndup (msg->response_body->data,
+			      msg->response_body->length);
+
+	if (parse_login_response (data->ean, response) == FALSE) {
+		g_simple_async_result_set_error (data->simple,
+						 DISCIDENT_ERROR,
+						 DISCIDENT_ERROR_PARSE,
+						 "Failed to parse login response from EAN service");
+		g_free (response);
+		goto error;
+	}
+
+	g_free (response);
+
+	query_msg = create_query_message (data->ean, data->barcode);
+	g_signal_connect (G_OBJECT (query_msg), "got-body",
+			  G_CALLBACK (got_body_query), data);
+	soup_session_queue_message (data->session, query_msg, NULL, NULL);
+	return;
+
+error:
+	g_simple_async_result_complete_in_idle (data->simple);
+	free_query_data (data);
+}
+
+/**
+ * discident_ean_lookup:
+ * @ean: a #DiscidentEan object.
+ * @barcode: the EAN barcode to lookup
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback to call when the request is satisfied
+ * @user_data: the data to pass to callback function
+ *
+ * Asynchronously gets the title and image URL for an EAN barcode
+ * using a web service.
+ *
+ * When the operation is finished, @callback will be called. You can then call
+ * discident_ean_lookup_finish() to get the result of the operation.
+ **/
+void
+discident_ean_lookup (DiscidentEan        *ean,
+		      const char          *barcode,
+		      GCancellable        *cancellable,
+		      GAsyncReadyCallback  callback,
+		      gpointer             user_data)
+{
+	GSimpleAsyncResult *simple;
+	SoupSession *session;
+	QueryData *data;
+	SoupMessage *msg;
+
+	simple = g_simple_async_result_new (G_OBJECT (ean),
+					    callback,
+					    user_data,
+					    discident_ean_lookup);
+	g_object_set_data_full (G_OBJECT (simple), "barcode", g_strdup (barcode), g_free);
+
+	session = soup_session_async_new_with_options (
+	    SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_PROXY_RESOLVER_GNOME,
+	    NULL);
+
+	data = g_new0 (QueryData, 1);
+	data->ean = g_object_ref (ean);
+	data->session = session;
+	data->barcode = g_strdup (barcode);
+	data->simple = simple;
+
+	if (ean->priv->login_done == FALSE) {
+		msg = soup_message_new ("GET", ORIGINAL_QUERY);
+		g_signal_connect (G_OBJECT (msg), "got-body",
+				  G_CALLBACK (got_body_login), data);
+	} else {
+		msg = create_query_message (ean, barcode);
+		g_signal_connect (G_OBJECT (msg), "got-body",
+				  G_CALLBACK (got_body_query), data);
+	}
+	soup_session_queue_message (session, msg, NULL, NULL);
+}
+
+/**
+ * discident_ean_lookup_finish:
+ * @ean: a #DiscidentEan object
+ * @res: a #GAsyncResult.
+ * @barcode: (out) the return location for the looked up barcode, or %NULL to ignore.
+ * @img_url: (out) the return location for the image URL, or %NULL to ignore.
+ * @error: a #GError.
+ *
+ * Finishes an EAN lookup operation. See discident_ean_lookup().
+ *
+ * Returns: a string containing the name of the looked up barcode, or
+ * %NULL in case of errors.
+ * Free the returned string with g_free() when done.
+ **/
+char *
+discident_ean_lookup_finish (DiscidentEan  *ean,
+			     GAsyncResult  *res,
+			     char         **barcode,
+			     char         **img_url,
+			     GError       **error)
+{
+	GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
+	char *ret;
+
+	g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == discident_ean_lookup);
+
+	ret = NULL;
+
+	if (g_simple_async_result_propagate_error (simple, error))
+		goto out;
+
+	ret = g_simple_async_result_get_op_res_gpointer (simple);
+	if (*img_url != NULL)
+		*img_url = g_strdup (g_object_get_data (G_OBJECT (res), "image-url"));
+	if (*barcode != NULL)
+		*barcode = g_strdup (g_object_get_data (G_OBJECT (res), "barcode"));
+
+out:
+	return ret;
+}
+
 /**
  * discident_ean_new:
  *
diff --git a/discident-glib/discident-ean-glib.h b/discident-glib/discident-ean-glib.h
index 22f6c11..cfeae20 100644
--- a/discident-glib/discident-ean-glib.h
+++ b/discident-glib/discident-ean-glib.h
@@ -64,6 +64,16 @@ gboolean      discident_ean_lookup_sync  (DiscidentEan *ean,
 					  char        **title,
 					  char        **img_url,
 					  GError      **error);
+void discident_ean_lookup (DiscidentEan        *ean,
+			   const char          *barcode,
+			   GCancellable        *cancellable,
+			   GAsyncReadyCallback  callback,
+			   gpointer             user_data);
+char * discident_ean_lookup_finish (DiscidentEan  *ean,
+				    GAsyncResult  *res,
+				    char         **barcode,
+				    char         **img_url,
+				    GError       **error);
 
 G_END_DECLS
 
diff --git a/discident-glib/discident-glib.symbols b/discident-glib/discident-glib.symbols
index fe877b6..22949cd 100644
--- a/discident-glib/discident-glib.symbols
+++ b/discident-glib/discident-glib.symbols
@@ -9,4 +9,6 @@ discident_get_title_for_gtin
 discident_ean_get_type
 discident_ean_new
 discident_ean_lookup_sync
+discident_ean_lookup
+discident_ean_lookup_finish
 discident_error_quark



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