[libgdata] [core] Add a GDataEntry:content-uri property



commit 14b888cd4da261e8fdc6b139d63c39d963b3ce29
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sat Aug 21 23:24:48 2010 +0100

    [core] Add a GDataEntry:content-uri property
    
    This complements the GDataEntry:content property by exposing content which
    is linked to by a URI, rather than embedded directly, in a more natural way.
    This is an API break, since GDataEntry:content may now return NULL in cases
    where it previously returned a URI (e.g. for GDataPicasaWebPhotos).

 docs/reference/gdata-sections.txt |    2 +
 gdata/gdata-entry.c               |  103 ++++++++++++++++++++++++++++++++----
 gdata/gdata-entry.h               |    2 +
 gdata/gdata.symbols               |    2 +
 gdata/tests/common.c              |    2 +
 gdata/tests/general.c             |   41 ++++++++++++++-
 gdata/tests/picasaweb.c           |    3 +-
 7 files changed, 141 insertions(+), 14 deletions(-)
---
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 3022846..eda1a82 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -147,6 +147,8 @@ gdata_entry_get_id
 gdata_entry_get_etag
 gdata_entry_get_content
 gdata_entry_set_content
+gdata_entry_get_content_uri
+gdata_entry_set_content_uri
 gdata_entry_get_published
 gdata_entry_get_updated
 gdata_entry_get_authors
diff --git a/gdata/gdata-entry.c b/gdata/gdata-entry.c
index 8ff5576..bdfc717 100644
--- a/gdata/gdata-entry.c
+++ b/gdata/gdata-entry.c
@@ -65,6 +65,7 @@ struct _GDataEntryPrivate {
 	GTimeVal published;
 	GList *categories; /* GDataCategory */
 	gchar *content;
+	gboolean content_is_uri;
 	GList *links; /* GDataLink */
 	GList *authors; /* GDataAuthor */
 	gchar *rights;
@@ -83,7 +84,8 @@ enum {
 	PROP_PUBLISHED,
 	PROP_CONTENT,
 	PROP_IS_INSERTED,
-	PROP_RIGHTS
+	PROP_RIGHTS,
+	PROP_CONTENT_URI
 };
 
 G_DEFINE_TYPE (GDataEntry, gdata_entry, GDATA_TYPE_PARSABLE)
@@ -204,7 +206,7 @@ gdata_entry_class_init (GDataEntryClass *klass)
 	/**
 	 * GDataEntry:content:
 	 *
-	 * The content of the entry.
+	 * The content of the entry. This is mutually exclusive with #GDataEntry:content.
 	 *
 	 * For more information, see the <ulink type="http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.content";>
 	 * Atom specification</ulink>.
@@ -216,6 +218,22 @@ gdata_entry_class_init (GDataEntryClass *klass)
 	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
 	/**
+	 * GDataEntry:content-uri:
+	 *
+	 * A URI pointing to the location of the content of the entry. This is mutually exclusive with #GDataEntry:content.
+	 *
+	 * For more information, see the
+	 * <ulink type="http" url="http://www.atomenabled.org/developers/syndication/atom-format-spec.php#element.content";>Atom specification</ulink>.
+	 *
+	 * Since: 0.7.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_CONTENT_URI,
+	                                 g_param_spec_string ("content-uri",
+	                                                      "Content URI", "A URI pointing to the location of the content of the entry.",
+	                                                      NULL,
+	                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
 	 * GDataEntry:is-inserted:
 	 *
 	 * Whether the entry has been inserted on the server. This is %FALSE for entries which have just been created using gdata_entry_new() and
@@ -337,7 +355,10 @@ gdata_entry_get_property (GObject *object, guint property_id, GValue *value, GPa
 			g_value_set_boxed (value, &(priv->published));
 			break;
 		case PROP_CONTENT:
-			g_value_set_string (value, priv->content);
+			g_value_set_string (value, (priv->content_is_uri == FALSE) ? priv->content : NULL);
+			break;
+		case PROP_CONTENT_URI:
+			g_value_set_string (value, (priv->content_is_uri == TRUE) ? priv->content : NULL);
 			break;
 		case PROP_IS_INSERTED:
 			g_value_set_boolean (value, gdata_entry_is_inserted (GDATA_ENTRY (object)));
@@ -375,6 +396,9 @@ gdata_entry_set_property (GObject *object, guint property_id, const GValue *valu
 		case PROP_CONTENT:
 			gdata_entry_set_content (self, g_value_get_string (value));
 			break;
+		case PROP_CONTENT_URI:
+			gdata_entry_set_content_uri (self, g_value_get_string (value));
+			break;
 		case PROP_RIGHTS:
 			gdata_entry_set_rights (self, g_value_get_string (value));
 			break;
@@ -416,10 +440,13 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			return success;
 		} else if (xmlStrcmp (node->name, (xmlChar*) "content") == 0) {
 			/* atom:content */
-			xmlChar *content = xmlNodeListGetString (doc, node->children, TRUE);
-			if (content == NULL)
-				content = xmlGetProp (node, (xmlChar*) "src");
-			priv->content = (gchar*) content;
+			priv->content = (gchar*) xmlGetProp (node, (xmlChar*) "src");
+			priv->content_is_uri = TRUE;
+
+			if (priv->content == NULL) {
+				priv->content = (gchar*) xmlNodeListGetString (doc, node->children, TRUE);
+				priv->content_is_uri = FALSE;
+			}
 
 			return TRUE;
 		}
@@ -496,8 +523,12 @@ get_xml (GDataParsable *parsable, GString *xml_string)
 	if (priv->rights != NULL)
 		gdata_parser_string_append_escaped (xml_string, "<rights>", priv->rights, "</rights>");
 
-	if (priv->content != NULL)
-		gdata_parser_string_append_escaped (xml_string, "<content type='text'>", priv->content, "</content>");
+	if (priv->content != NULL) {
+		if (priv->content_is_uri == TRUE)
+			gdata_parser_string_append_escaped (xml_string, "<content type='text/plain' src='", priv->content, "'/>");
+		else
+			gdata_parser_string_append_escaped (xml_string, "<content type='text'>", priv->content, "</content>");
+	}
 
 	for (categories = priv->categories; categories != NULL; categories = categories->next)
 		_gdata_parsable_get_xml (GDATA_PARSABLE (categories->data), xml_string, FALSE);
@@ -782,7 +813,8 @@ gdata_entry_get_authors (GDataEntry *self)
  * gdata_entry_get_content:
  * @self: a #GDataEntry
  *
- * Returns the textual content in this entry.
+ * Returns the textual content in this entry. If the content in this entry is pointed to by a URI, %NULL will be returned; the content URI will be
+ * returned by gdata_entry_get_content_uri().
  *
  * Return value: the entry's content, or %NULL
  **/
@@ -790,7 +822,7 @@ const gchar *
 gdata_entry_get_content (GDataEntry *self)
 {
 	g_return_val_if_fail (GDATA_IS_ENTRY (self), NULL);
-	return self->priv->content;
+	return (self->priv->content_is_uri == FALSE) ? self->priv->content : NULL;
 }
 
 /**
@@ -798,7 +830,7 @@ gdata_entry_get_content (GDataEntry *self)
  * @self: a #GDataEntry
  * @content: (allow-none): the new content for the entry, or %NULL
  *
- * Sets the entry's content to @content.
+ * Sets the entry's content to @content. This unsets #GDataEntry:content-uri.
  **/
 void
 gdata_entry_set_content (GDataEntry *self, const gchar *content)
@@ -807,7 +839,54 @@ gdata_entry_set_content (GDataEntry *self, const gchar *content)
 
 	g_free (self->priv->content);
 	self->priv->content = g_strdup (content);
+	self->priv->content_is_uri = FALSE;
+
+	g_object_freeze_notify (G_OBJECT (self));
+	g_object_notify (G_OBJECT (self), "content");
+	g_object_notify (G_OBJECT (self), "content-uri");
+	g_object_thaw_notify (G_OBJECT (self));
+}
+
+/**
+ * gdata_entry_get_content_uri:
+ * @self: a #GDataEntry
+ *
+ * Returns a URI pointing to the content of this entry. If the content in this entry is stored directly, %NULL will be returned; the content will be
+ * returned by gdata_entry_get_content().
+ *
+ * Return value: a URI pointing to the entry's content, or %NULL
+ *
+ * Since: 0.7.0
+ **/
+const gchar *
+gdata_entry_get_content_uri (GDataEntry *self)
+{
+	g_return_val_if_fail (GDATA_IS_ENTRY (self), NULL);
+	return (self->priv->content_is_uri == TRUE) ? self->priv->content : NULL;
+}
+
+/**
+ * gdata_entry_set_content_uri:
+ * @self: a #GDataEntry
+ * @content_uri: (allow-none): the new URI pointing to the content for the entry, or %NULL
+ *
+ * Sets the URI pointing to the entry's content to @content. This unsets #GDataEntry:content.
+ *
+ * Since: 0.7.0
+ **/
+void
+gdata_entry_set_content_uri (GDataEntry *self, const gchar *content_uri)
+{
+	g_return_if_fail (GDATA_IS_ENTRY (self));
+
+	g_free (self->priv->content);
+	self->priv->content = g_strdup (content_uri);
+	self->priv->content_is_uri = TRUE;
+
+	g_object_freeze_notify (G_OBJECT (self));
 	g_object_notify (G_OBJECT (self), "content");
+	g_object_notify (G_OBJECT (self), "content-uri");
+	g_object_thaw_notify (G_OBJECT (self));
 }
 
 /**
diff --git a/gdata/gdata-entry.h b/gdata/gdata-entry.h
index 373775f..c44e746 100644
--- a/gdata/gdata-entry.h
+++ b/gdata/gdata-entry.h
@@ -81,6 +81,8 @@ void gdata_entry_add_category (GDataEntry *self, GDataCategory *category);
 GList *gdata_entry_get_categories (GDataEntry *self) G_GNUC_PURE;
 const gchar *gdata_entry_get_content (GDataEntry *self) G_GNUC_PURE;
 void gdata_entry_set_content (GDataEntry *self, const gchar *content);
+const gchar *gdata_entry_get_content_uri (GDataEntry *self) G_GNUC_PURE;
+void gdata_entry_set_content_uri (GDataEntry *self, const gchar *content_uri);
 void gdata_entry_add_link (GDataEntry *self, GDataLink *_link);
 GDataLink *gdata_entry_look_up_link (GDataEntry *self, const gchar *rel) G_GNUC_PURE;
 GList *gdata_entry_look_up_links (GDataEntry *self, const gchar *rel) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index 115cf4b..a11bf05 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -15,6 +15,8 @@ gdata_entry_add_category
 gdata_entry_get_categories
 gdata_entry_get_content
 gdata_entry_set_content
+gdata_entry_get_content_uri
+gdata_entry_set_content_uri
 gdata_entry_add_link
 gdata_entry_look_up_link
 gdata_entry_look_up_links
diff --git a/gdata/tests/common.c b/gdata/tests/common.c
index 1de14f4..9b7411c 100644
--- a/gdata/tests/common.c
+++ b/gdata/tests/common.c
@@ -138,6 +138,7 @@ test_batch_operation_query_cb (guint operation_id, GDataBatchOperationType opera
 			g_assert_cmpstr (gdata_entry_get_title (entry), ==, gdata_entry_get_title (data->entry));
 			g_assert_cmpstr (gdata_entry_get_summary (entry), ==, gdata_entry_get_summary (data->entry));
 			g_assert_cmpstr (gdata_entry_get_content (entry), ==, gdata_entry_get_content (data->entry));
+			g_assert_cmpstr (gdata_entry_get_content_uri (entry), ==, gdata_entry_get_content_uri (data->entry));
 			g_assert_cmpstr (gdata_entry_get_rights (entry), ==, gdata_entry_get_rights (data->entry));
 		}
 
@@ -201,6 +202,7 @@ test_batch_operation_insertion_update_cb (guint operation_id, GDataBatchOperatio
 		g_assert_cmpstr (gdata_entry_get_title (entry), ==, gdata_entry_get_title (data->entry));
 		g_assert_cmpstr (gdata_entry_get_summary (entry), ==, gdata_entry_get_summary (data->entry));
 		g_assert_cmpstr (gdata_entry_get_content (entry), ==, gdata_entry_get_content (data->entry));
+		g_assert_cmpstr (gdata_entry_get_content_uri (entry), ==, gdata_entry_get_content_uri (data->entry));
 		g_assert_cmpstr (gdata_entry_get_rights (entry), ==, gdata_entry_get_rights (data->entry));
 
 		/* Copy the inserted entry for the calling test code to prod later */
diff --git a/gdata/tests/general.c b/gdata/tests/general.c
index 93eb792..d863c4c 100644
--- a/gdata/tests/general.c
+++ b/gdata/tests/general.c
@@ -31,7 +31,7 @@ test_entry_get_xml (void)
 	GDataCategory *category;
 	GDataLink *_link; /* stupid unistd.h */
 	GDataAuthor *author;
-	gchar *xml, *title, *summary, *id, *etag, *content, *rights;
+	gchar *xml, *title, *summary, *id, *etag, *content, *content_uri, *rights;
 	gboolean is_inserted;
 	GList *list;
 	GError *error = NULL;
@@ -49,6 +49,7 @@ test_entry_get_xml (void)
 	g_assert_cmpstr (gdata_entry_get_title (entry), ==, "First testing title & escaping");
 	g_assert_cmpstr (gdata_entry_get_summary (entry), ==, "Test summary & escaping.");
 	g_assert_cmpstr (gdata_entry_get_content (entry), ==, "Test <markup> & escaping.");
+	g_assert (gdata_entry_get_content_uri (entry) == NULL);
 	g_assert_cmpstr (gdata_entry_get_rights (entry), ==, "Philip Withnall <philip tecnocode co uk>");
 
 	/* Set the properties more conventionally */
@@ -57,6 +58,26 @@ test_entry_get_xml (void)
 	gdata_entry_set_content (entry, "This is some sample content testing, amongst other things, <markup> & odd charactersâ?½");
 	gdata_entry_set_rights (entry, NULL);
 
+	/* Content URI */
+	g_object_set (G_OBJECT (entry), "content-uri", "http://foo.com/";, NULL);
+
+	g_assert (gdata_entry_get_content (entry) == NULL);
+	g_assert_cmpstr (gdata_entry_get_content_uri (entry), ==, "http://foo.com/";);
+
+	gdata_entry_set_content_uri (entry, "http://bar.com/";);
+
+	/* Check the generated XML's OK */
+	xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
+	g_assert_cmpstr (xml, ==,
+			 "<?xml version='1.0' encoding='UTF-8'?>"
+			 "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'>"
+				 "<title type='text'>Testing title &amp; escaping</title>"
+				 "<content type='text/plain' src='http://bar.com/'/>"
+			 "</entry>");
+
+	/* Reset the content */
+	gdata_entry_set_content (entry, "This is some sample content testing, amongst other things, <markup> & odd charactersâ?½");
+
 	/* Categories */
 	category = gdata_category_new ("test", NULL, NULL);
 	gdata_entry_add_category (entry, category);
@@ -131,6 +152,7 @@ test_entry_get_xml (void)
 	g_assert_cmpstr (gdata_entry_get_title (entry), ==, gdata_entry_get_title (entry2));
 	g_assert_cmpstr (gdata_entry_get_id (entry), ==, gdata_entry_get_id (entry2)); /* should both be NULL */
 	g_assert_cmpstr (gdata_entry_get_content (entry), ==, gdata_entry_get_content (entry2));
+	g_assert_cmpstr (gdata_entry_get_content_uri (entry), ==, gdata_entry_get_content_uri (entry2)); /* should both be NULL */
 
 	gdata_entry_get_updated (entry, &updated);
 	gdata_entry_get_updated (entry2, &updated2);
@@ -225,6 +247,7 @@ test_entry_get_xml (void)
 	              "updated", &updated3,
 	              "published", &published3,
 	              "content", &content,
+	              "content-uri", &content_uri,
 	              "is-inserted", &is_inserted,
 	              "rights", &rights,
 	              NULL);
@@ -238,6 +261,7 @@ test_entry_get_xml (void)
 	g_assert_cmpint (published3->tv_sec, ==, published.tv_sec);
 	g_assert_cmpint (published3->tv_usec, ==, published.tv_usec);
 	g_assert_cmpstr (content, ==, gdata_entry_get_content (entry));
+	g_assert_cmpstr (content_uri, ==, gdata_entry_get_content_uri (entry));
 	g_assert (is_inserted == FALSE);
 	g_assert_cmpstr (rights, ==, gdata_entry_get_rights (entry));
 
@@ -248,8 +272,23 @@ test_entry_get_xml (void)
 	g_free (updated3);
 	g_free (published3);
 	g_free (content);
+	g_free (content_uri);
 	g_free (rights);
 
+	/* Set the content URI and check that */
+	gdata_entry_set_content_uri (entry, "http://baz.net/";);
+
+	g_object_get (G_OBJECT (entry),
+	              "content", &content,
+	              "content-uri", &content_uri,
+	              NULL);
+
+	g_assert_cmpstr (content, ==, gdata_entry_get_content (entry));
+	g_assert_cmpstr (content_uri, ==, gdata_entry_get_content_uri (entry));
+
+	g_free (content);
+	g_free (content_uri);
+
 	g_object_unref (entry);
 	g_object_unref (entry2);
 }
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index c4c78d1..1249e0d 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -810,7 +810,8 @@ test_photo_feed_entry (gconstpointer service)
 	g_assert_cmpstr (str, ==, "2009-04-26T06:55:20Z");
 	g_free (str);
 
-	g_assert_cmpstr (gdata_entry_get_content (photo_entry), ==,
+	g_assert (gdata_entry_get_content (photo_entry) == NULL);
+	g_assert_cmpstr (gdata_entry_get_content_uri (photo_entry), ==,
 			 "http://lh3.ggpht.com/_1kdcGyvOb8c/SfQFWPnuovI/AAAAAAAAAB0/MI0L4Sd11Eg/100_0269.jpg";);
 	g_assert_cmpstr (gdata_parsable_get_xml (GDATA_PARSABLE (photo_entry)), !=, NULL);
 	g_assert_cmpuint (strlen (gdata_parsable_get_xml (GDATA_PARSABLE (photo_entry))), >, 0);



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