[libgdata] Bug 590132 – Unhandled XML for georss



commit 3c735026b6b8d587c48139b3c7e504353192aec9
Author: Richard Schwarting <aquarichy gmail com>
Date:   Sun Aug 2 22:52:16 2009 +0100

    Bug 590132 â?? Unhandled XML for georss
    
    Patch to add GeoRSS support to the PicasaWeb backend, with support for
    getting and setting coordinates of albums and files, including test cases.
    Closes: bgo#590132

 configure.in                                     |    1 +
 docs/reference/Makefile.am                       |    4 +-
 docs/reference/gdata-sections.txt                |    4 +
 gdata/Makefile.am                                |    5 +-
 gdata/gdata.symbols                              |    4 +
 gdata/services/picasaweb/gdata-picasaweb-album.c |  128 +++++++++++++++++++-
 gdata/services/picasaweb/gdata-picasaweb-album.h |    2 +
 gdata/services/picasaweb/gdata-picasaweb-file.c  |  140 +++++++++++++++++++---
 gdata/services/picasaweb/gdata-picasaweb-file.h  |    2 +
 gdata/tests/picasaweb.c                          |   70 +++++++++--
 10 files changed, 328 insertions(+), 32 deletions(-)
---
diff --git a/configure.in b/configure.in
index 830b448..1379836 100644
--- a/configure.in
+++ b/configure.in
@@ -89,6 +89,7 @@ gdata/atom/Makefile
 gdata/gd/Makefile
 gdata/media/Makefile
 gdata/exif/Makefile
+gdata/georss/Makefile
 gdata/services/Makefile
 gdata/services/calendar/Makefile
 gdata/services/contacts/Makefile
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 838f1d4..cb19f14 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -65,7 +65,9 @@ IGNORE_HFILES = \
 	gdata-youtube-control.h	\
 	gdata-picasaweb-enums.h	\
 	gdata-exif-tags.c	\
-	gdata-exif-tags.h
+	gdata-exif-tags.h	\
+	gdata-georss-where.c	\
+	gdata-georss-where.h
 
 # Images to copy into HTML directory.
 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 52eaa68..eb28ccc 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -1217,6 +1217,8 @@ gdata_picasaweb_album_get_description
 gdata_picasaweb_album_set_description
 gdata_picasaweb_album_get_contents
 gdata_picasaweb_album_get_thumbnails
+gdata_picasaweb_album_get_coordinates
+gdata_picasaweb_album_set_coordinates
 <SUBSECTION Standard>
 gdata_picasaweb_album_get_type
 GDATA_IS_PICASAWEB_ALBUM
@@ -1272,6 +1274,8 @@ gdata_picasaweb_file_get_image_unique_id
 gdata_picasaweb_file_get_iso
 gdata_picasaweb_file_get_make
 gdata_picasaweb_file_get_model
+gdata_picasaweb_file_get_coordinates
+gdata_picasaweb_file_set_coordinates
 <SUBSECTION Standard>
 gdata_picasaweb_file_get_type
 GDATA_IS_PICASAWEB_FILE
diff --git a/gdata/Makefile.am b/gdata/Makefile.am
index a176d92..231054d 100644
--- a/gdata/Makefile.am
+++ b/gdata/Makefile.am
@@ -1,5 +1,5 @@
-SUBDIRS = atom gd media exif services . tests
-DIST_SUBDIRS = atom gd media exif services tests
+SUBDIRS = atom gd media exif georss services . tests
+DIST_SUBDIRS = atom gd media exif georss services tests
 
 # Marshalling
 GDATA_MARSHAL_FILES = \
@@ -93,6 +93,7 @@ libgdata_la_LIBADD = \
 	gd/libgdatagd.la			\
 	media/libgdatamedia.la			\
 	exif/libgdataexif.la			\
+	georss/libgdatageorss.la		\
 	services/youtube/libgdatayoutube.la	\
 	services/calendar/libgdatacalendar.la	\
 	services/picasaweb/libgdatapicasaweb.la	\
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index 14fb11e..b658280 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -519,6 +519,8 @@ gdata_picasaweb_album_get_description
 gdata_picasaweb_album_set_description
 gdata_picasaweb_album_get_contents
 gdata_picasaweb_album_get_thumbnails
+gdata_picasaweb_album_get_coordinates
+gdata_picasaweb_album_set_coordinates
 gdata_picasaweb_file_get_type
 gdata_picasaweb_file_new
 gdata_picasaweb_file_get_edited
@@ -558,6 +560,8 @@ gdata_picasaweb_file_get_image_unique_id
 gdata_picasaweb_file_get_iso
 gdata_picasaweb_file_get_make
 gdata_picasaweb_file_get_model
+gdata_picasaweb_file_get_coordinates
+gdata_picasaweb_file_set_coordinates
 gdata_picasaweb_query_get_type
 gdata_picasaweb_query_new
 gdata_picasaweb_query_new_with_limits
diff --git a/gdata/services/picasaweb/gdata-picasaweb-album.c b/gdata/services/picasaweb/gdata-picasaweb-album.c
index 856506f..19fe8f0 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-album.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-album.c
@@ -46,6 +46,7 @@
 #include "gdata-types.h"
 #include "media/gdata-media-group.h"
 #include "gdata-picasaweb-enums.h"
+#include "georss/gdata-georss-where.h"
 
 static void gdata_picasaweb_album_dispose (GObject *object);
 static void gdata_picasaweb_album_finalize (GObject *object);
@@ -71,6 +72,8 @@ struct _GDataPicasaWebAlbumPrivate {
 
 	/* media:group */
 	GDataMediaGroup *media_group;
+	/* georss:where */
+	GDataGeoRSSWhere *georss_where;
 };
 
 enum {
@@ -87,7 +90,9 @@ enum {
 	PROP_IS_COMMENTING_ENABLED,
 	PROP_COMMENT_COUNT,
 	PROP_DESCRIPTION,
-	PROP_TAGS
+	PROP_TAGS,
+	PROP_LATITUDE,
+	PROP_LONGITUDE
 };
 
 G_DEFINE_TYPE (GDataPicasaWebAlbum, gdata_picasaweb_album, GDATA_TYPE_ENTRY)
@@ -335,6 +340,38 @@ gdata_picasaweb_album_class_init (GDataPicasaWebAlbumClass *klass)
 							      "Tags", "A comma-separated list of tags associated with the album",
 							      NULL,
 							      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataPicasaWebAlbum:latitude:
+	 *
+	 * The location as a latitude coordinate associated with this album. Valid latitudes range from %-90.0 to %90.0 inclusive.
+	 *
+	 * For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/docs/2.0/reference.html#georss_where";>
+	 * GeoRSS specification</ulink>.
+	 *
+	 * Since: 0.5.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_LATITUDE,
+					 g_param_spec_double ("latitude",
+							      "Latitude", "The location as a latitude coordinate associated with this album.",
+							      -90.0, 90.0, 0.0,
+							      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataPicasaWebAlbum:longitude:
+	 *
+	 * The location as a longitude coordinate associated with this album. Valid longitudes range from %-180.0 to %180.0 inclusive.
+	 *
+	 * For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/docs/2.0/reference.html#georss_where";>
+	 * GeoRSS specification</ulink>.
+	 *
+	 * Since: 0.5.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_LONGITUDE,
+					 g_param_spec_double ("longitude",
+							      "Longitude", "The location as a longitude coordinate associated with this album.",
+							      -180.0, 180.0, 0.0,
+							      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -361,7 +398,7 @@ notify_rights_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_da
 		gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PRIVATE);
 	} else {
 		/* Print out a warning and leave the visibility as it is */
-		g_message ("Unknown <rights> or <gd:access> value: %s", rights);
+		g_warning ("Unknown <rights> or <gd:access> value: %s", rights);
 	}
 
 	g_signal_handlers_unblock_by_func (self, notify_visibility_cb, NULL);
@@ -392,6 +429,7 @@ gdata_picasaweb_album_init (GDataPicasaWebAlbum *self)
 {
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_PICASAWEB_ALBUM, GDataPicasaWebAlbumPrivate);
 	self->priv->media_group = g_object_new (GDATA_TYPE_MEDIA_GROUP, NULL);
+	self->priv->georss_where = g_object_new (GDATA_TYPE_GEORSS_WHERE, NULL);
 
 	/* Connect to the notify::title signal from GDataEntry so our media:group title can be kept in sync */
 	g_signal_connect (GDATA_ENTRY (self), "notify::title", G_CALLBACK (notify_title_cb), NULL);
@@ -410,6 +448,10 @@ gdata_picasaweb_album_dispose (GObject *object)
 		g_object_unref (priv->media_group);
 	priv->media_group = NULL;
 
+	if (priv->georss_where != NULL)
+		g_object_unref (priv->georss_where);
+	priv->georss_where = NULL;
+
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_picasaweb_album_parent_class)->dispose (object);
 }
@@ -476,6 +518,12 @@ gdata_picasaweb_album_get_property (GObject *object, guint property_id, GValue *
 		case PROP_TAGS:
 			g_value_set_string (value, gdata_media_group_get_keywords (priv->media_group));
 			break;
+		case PROP_LATITUDE:
+			g_value_set_double (value, gdata_georss_where_get_latitude (priv->georss_where));
+			break;
+		case PROP_LONGITUDE:
+			g_value_set_double (value, gdata_georss_where_get_longitude (priv->georss_where));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -507,6 +555,14 @@ gdata_picasaweb_album_set_property (GObject *object, guint property_id, const GV
 		case PROP_TAGS:
 			gdata_picasaweb_album_set_tags (self, g_value_get_string (value));
 			break;
+		case PROP_LATITUDE:
+			gdata_picasaweb_album_set_coordinates (self, g_value_get_double (value),
+							       gdata_georss_where_get_longitude (self->priv->georss_where));
+			break;
+		case PROP_LONGITUDE:
+			gdata_picasaweb_album_set_coordinates (self, gdata_georss_where_get_latitude (self->priv->georss_where),
+							       g_value_get_double (value));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -531,6 +587,16 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->media_group);
 
 		self->priv->media_group = group;
+	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+		/* georss:where */
+		GDataGeoRSSWhere *where = GDATA_GEORSS_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GEORSS_WHERE, doc, node, NULL, error));
+		if (where == NULL)
+			return FALSE;
+
+		if (self->priv->georss_where != NULL)
+			g_object_unref (self->priv->georss_where);
+
+		self->priv->georss_where = where;
 	} else if (xmlStrcmp (node->name, (xmlChar*) "user") == 0) {
 		/* gphoto:user */
 		xmlChar *user = xmlNodeListGetString (doc, node->children, TRUE);
@@ -685,13 +751,19 @@ get_xml (GDataParsable *parsable, GString *xml_string)
 	/* media:group */
 	_gdata_parsable_get_xml (GDATA_PARSABLE (priv->media_group), xml_string, FALSE);
 
-	/* TODO: add GML support */
+	/* georss:where */
+	if (priv->georss_where != NULL && gdata_georss_where_get_latitude (priv->georss_where) != G_MAXDOUBLE &&
+	    gdata_georss_where_get_longitude (priv->georss_where) != G_MAXDOUBLE) {
+		_gdata_parsable_get_xml (GDATA_PARSABLE (priv->georss_where), xml_string, FALSE);
+	}
+
 	/* TODO:
 	 * - Finish supporting all tags
 	 * - Check all tags here are valid for insertions and updates
 	 * - Check things are escaped (or not) as appropriate
 	 * - Write a function to encapsulate g_markup_escape_text and
 	 *   g_string_append_printf to reduce the number of allocations
+	 * - add GML support
 	 */
 }
 
@@ -708,6 +780,8 @@ get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
 
 	/* Add the media:group namespaces */
 	GDATA_PARSABLE_GET_CLASS (priv->media_group)->get_namespaces (GDATA_PARSABLE (priv->media_group), namespaces);
+	/* Add the georss:where namespaces */
+	GDATA_PARSABLE_GET_CLASS (priv->georss_where)->get_namespaces (GDATA_PARSABLE (priv->georss_where), namespaces);
 }
 
 /**
@@ -1120,3 +1194,51 @@ gdata_picasaweb_album_get_thumbnails (GDataPicasaWebAlbum *self)
 	g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
 	return gdata_media_group_get_thumbnails (self->priv->media_group);
 }
+
+/**
+ * gdata_picasaweb_album_get_coordinates:
+ * @self: a #GDataPicasaWebAlbum
+ * @latitude: return location for the latitude, or %NULL
+ * @longitude: return location for the longitude, or %NULL
+ *
+ * Gets the #GDataPicasaWebAlbum:latitude and #GDataPicasaWebAlbum:longitude properties,
+ * setting the out parameters to them. If either latitude or longitude is %NULL, that parameter will not be set.
+ * If the coordinates are unset, @latitude and @longitude will be set to %G_MAXDOUBLE.
+ *
+ * Since: 0.5.0
+ **/
+void
+gdata_picasaweb_album_get_coordinates (GDataPicasaWebAlbum *self, gdouble *latitude, gdouble *longitude)
+{
+	g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
+
+	if (latitude != NULL)
+		*latitude = gdata_georss_where_get_latitude (self->priv->georss_where);
+	if (longitude != NULL)
+		*longitude = gdata_georss_where_get_longitude (self->priv->georss_where);
+}
+
+/**
+ * gdata_picasaweb_album_set_coordinates:
+ * @self: a #GDataPicasaWebAlbum
+ * @latitude: the album's new latitude coordinate, or %G_MAXDOUBLE
+ * @longitude: the album's new longitude coordinate, or %G_MAXDOUBLE
+ *
+ * Sets the #GDataPicasaWebAlbum:latitude and #GDataPicasaWebAlbum:longitude properties to
+ * @latitude and @longitude respectively.
+ *
+ * Since: 0.5.0
+ **/
+void
+gdata_picasaweb_album_set_coordinates (GDataPicasaWebAlbum *self, gdouble latitude, gdouble longitude)
+{
+	g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
+
+	gdata_georss_where_set_latitude (self->priv->georss_where, latitude);
+	gdata_georss_where_set_longitude (self->priv->georss_where, longitude);
+
+	g_object_freeze_notify (G_OBJECT (self));
+	g_object_notify (G_OBJECT (self), "latitude");
+	g_object_notify (G_OBJECT (self), "longitude");
+	g_object_thaw_notify (G_OBJECT (self));
+}
diff --git a/gdata/services/picasaweb/gdata-picasaweb-album.h b/gdata/services/picasaweb/gdata-picasaweb-album.h
index 27a04d2..a79c1d3 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-album.h
+++ b/gdata/services/picasaweb/gdata-picasaweb-album.h
@@ -102,6 +102,8 @@ const gchar *gdata_picasaweb_album_get_description (GDataPicasaWebAlbum *self);
 void gdata_picasaweb_album_set_description (GDataPicasaWebAlbum *self, const gchar *description);
 GList *gdata_picasaweb_album_get_contents (GDataPicasaWebAlbum *self);
 GList *gdata_picasaweb_album_get_thumbnails (GDataPicasaWebAlbum *self);
+void gdata_picasaweb_album_get_coordinates (GDataPicasaWebAlbum *self, gdouble *latitude, gdouble *longitude);
+void gdata_picasaweb_album_set_coordinates (GDataPicasaWebAlbum *self, gdouble latitude, gdouble longitude);
 
 G_END_DECLS
 
diff --git a/gdata/services/picasaweb/gdata-picasaweb-file.c b/gdata/services/picasaweb/gdata-picasaweb-file.c
index 187b46f..59e0169 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-file.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-file.c
@@ -43,6 +43,7 @@
 #include "gdata-types.h"
 #include "media/gdata-media-group.h"
 #include "exif/gdata-exif-tags.h"
+#include "georss/gdata-georss-where.h"
 
 static void gdata_picasaweb_file_dispose (GObject *object);
 static void gdata_picasaweb_file_finalize (GObject *object);
@@ -72,20 +73,8 @@ struct _GDataPicasaWebFilePrivate {
 	GDataMediaGroup *media_group;
 	/* exif:tags */
 	GDataExifTags *exif_tags;
-
-	/* georss:where properties */
-	/* TODO these specify a location, like the following example.
-	 * Perhaps investigate whether we can do anything with geoclue/libchamplain
-<georss:where>
-	<gml:Envelope>
-		<gml:lowerCorner>45.2404179 11.7382049</gml:lowerCorner>
-		<gml:upperCorner>45.6278166 12.5196074</gml:upperCorner>
-	</gml:Envelope>
-	<gml:Point>
-		<gml:pos>45.4341173 12.1289062</gml:pos>
-	</gml:Point>
-</georss:where>
-	*/
+	/* georss:where */
+	GDataGeoRSSWhere *georss_where;
 };
 
 enum {
@@ -114,7 +103,9 @@ enum {
 	PROP_IMAGE_UNIQUE_ID,
 	PROP_ISO,
 	PROP_MAKE,
-	PROP_MODEL
+	PROP_MODEL,
+	PROP_LATITUDE,
+	PROP_LONGITUDE
 };
 
 G_DEFINE_TYPE (GDataPicasaWebFile, gdata_picasaweb_file, GDATA_TYPE_ENTRY)
@@ -540,6 +531,38 @@ gdata_picasaweb_file_class_init (GDataPicasaWebFileClass *klass)
 							      "Model", "The model of the camera.",
 							      NULL,
 							      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataPicasaWebFile:latitude:
+	 *
+	 * The location as a latitude coordinate associated with this file. Valid latitudes range from %-90.0 to %90.0 inclusive.
+	 *
+	 * For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/docs/2.0/reference.html#georss_where";>
+	 * GeoRSS specification</ulink>.
+	 *
+	 * Since: 0.5.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_LATITUDE,
+					 g_param_spec_double ("latitude",
+							      "Latitude", "The location as a latitude coordinate associated with this file.",
+							      -90.0, 90.0, 0.0,
+							      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+	/**
+	 * GDataPicasaWebFile:longitude:
+	 *
+	 * The location as a longitude coordinate associated with this file. Valid longitudes range from %-180.0 to %180.0 inclusive.
+	 *
+	 * For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/docs/2.0/reference.html#georss_where";>
+	 * GeoRSS specification</ulink>.
+	 *
+	 * Since: 0.5.0
+	 **/
+	g_object_class_install_property (gobject_class, PROP_LONGITUDE,
+					 g_param_spec_double ("longitude",
+							      "Longitude", "The location as a longitude coordinate associated with this file.",
+							      -180.0, 180.0, 0.0,
+							      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -564,6 +587,7 @@ gdata_picasaweb_file_init (GDataPicasaWebFile *self)
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_PICASAWEB_FILE, GDataPicasaWebFilePrivate);
 	self->priv->media_group = g_object_new (GDATA_TYPE_MEDIA_GROUP, NULL);
 	self->priv->exif_tags = g_object_new (GDATA_TYPE_EXIF_TAGS, NULL);
+	self->priv->georss_where = g_object_new (GDATA_TYPE_GEORSS_WHERE, NULL);
 	self->priv->is_commenting_enabled = TRUE;
 
 	/* We need to keep atom:title (the canonical title for the file) in sync with media:group/media:title */
@@ -585,6 +609,10 @@ gdata_picasaweb_file_dispose (GObject *object)
 		g_object_unref (priv->exif_tags);
 	priv->exif_tags = NULL;
 
+	if (priv->georss_where != NULL)
+		g_object_unref (priv->georss_where);
+	priv->georss_where = NULL;
+
 	/* Chain up to the parent class */
 	G_OBJECT_CLASS (gdata_picasaweb_file_parent_class)->dispose (object);
 }
@@ -689,6 +717,12 @@ gdata_picasaweb_file_get_property (GObject *object, guint property_id, GValue *v
 		case PROP_MODEL:
 			g_value_set_string (value, gdata_exif_tags_get_model (priv->exif_tags));
 			break;
+		case PROP_LATITUDE:
+			g_value_set_double (value, gdata_georss_where_get_latitude (priv->georss_where));
+			break;
+		case PROP_LONGITUDE:
+			g_value_set_double (value, gdata_georss_where_get_longitude (priv->georss_where));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -735,6 +769,14 @@ gdata_picasaweb_file_set_property (GObject *object, guint property_id, const GVa
 		case PROP_TAGS:
 			gdata_picasaweb_file_set_tags (self, g_value_get_string (value));
 			break;
+		case PROP_LATITUDE:
+			gdata_picasaweb_file_set_coordinates (self, g_value_get_double (value),
+							      gdata_georss_where_get_longitude (self->priv->georss_where));
+			break;
+		case PROP_LONGITUDE:
+			gdata_picasaweb_file_set_coordinates (self, gdata_georss_where_get_latitude (self->priv->georss_where),
+							      g_value_get_double (value));
+			break;
 		default:
 			/* We don't have any other property... */
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -759,6 +801,16 @@ parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_da
 			g_object_unref (self->priv->media_group);
 
 		self->priv->media_group = group;
+	} else if (xmlStrcmp (node->name, (xmlChar*) "where") == 0) {
+		/* georss:where */
+		GDataGeoRSSWhere *where = GDATA_GEORSS_WHERE (_gdata_parsable_new_from_xml_node (GDATA_TYPE_GEORSS_WHERE, doc, node, NULL, error));
+		if (where == NULL)
+			return FALSE;
+
+		if (self->priv->georss_where != NULL)
+			g_object_unref (self->priv->georss_where);
+
+		self->priv->georss_where = where;
 	} else if (xmlStrcmp (node->name, (xmlChar*) "tags") == 0) {
 		/* exif:tags */
 		GDataExifTags *tags = GDATA_EXIF_TAGS (_gdata_parsable_new_from_xml_node (GDATA_TYPE_EXIF_TAGS, doc, node, NULL, error));
@@ -917,6 +969,12 @@ get_xml (GDataParsable *parsable, GString *xml_string)
 	/* media:group */
 	_gdata_parsable_get_xml (GDATA_PARSABLE (priv->media_group), xml_string, FALSE);
 
+	/* georss:where */
+	if (priv->georss_where != NULL && gdata_georss_where_get_latitude (priv->georss_where) != G_MAXDOUBLE &&
+	    gdata_georss_where_get_longitude (priv->georss_where) != G_MAXDOUBLE) {
+		_gdata_parsable_get_xml (GDATA_PARSABLE (priv->georss_where), xml_string, FALSE);
+	}
+
 	/* TODO:
 	 * - Finish supporting all tags
 	 * - Check all tags here are valid for insertions and updates
@@ -941,6 +999,8 @@ get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
 	GDATA_PARSABLE_GET_CLASS (priv->media_group)->get_namespaces (GDATA_PARSABLE (priv->media_group), namespaces);
 	/* Add the exif:tags namespaces */
 	GDATA_PARSABLE_GET_CLASS (priv->exif_tags)->get_namespaces (GDATA_PARSABLE (priv->exif_tags), namespaces);
+	/* Add the georss:where namespaces */
+	GDATA_PARSABLE_GET_CLASS (priv->georss_where)->get_namespaces (GDATA_PARSABLE (priv->georss_where), namespaces);
 }
 
 /**
@@ -1478,7 +1538,7 @@ gdata_picasaweb_file_get_thumbnails (GDataPicasaWebFile *self)
  *
  * Gets the #GDataPicasaWebFile:distance property.
  *
- * Return value: the distance recorded in the photo's EXIF, or %-1 if unknown 
+ * Return value: the distance recorded in the photo's EXIF, or %-1 if unknown
  *
  * Since: 0.5.0
  **/
@@ -1624,3 +1684,51 @@ gdata_picasaweb_file_get_model (GDataPicasaWebFile *self)
 	g_return_val_if_fail (GDATA_IS_PICASAWEB_FILE (self), NULL);
 	return gdata_exif_tags_get_model (self->priv->exif_tags);
 }
+
+/**
+ * gdata_picasaweb_file_get_coordinates:
+ * @self: a #GDataPicasaWebFile
+ * @latitude: return location for the latitude, or %NULL
+ * @longitude: return location for the longitude, or %NULL
+ *
+ * Gets the #GDataPicasaWebFile:latitude and #GDataPicasaWebFile:longitude properties, setting the out parameters to them.
+ * If either latitude or longitude is %NULL, that parameter will not be set. If the coordinates are unset,
+ * @latitude and @longitude will be set to %G_MAXDOUBLE.
+ *
+ * Since: 0.5.0
+ **/
+void
+gdata_picasaweb_file_get_coordinates (GDataPicasaWebFile *self, gdouble *latitude, gdouble *longitude)
+{
+	g_return_if_fail (GDATA_IS_PICASAWEB_FILE (self));
+
+	if (latitude != NULL)
+		*latitude = gdata_georss_where_get_latitude (self->priv->georss_where);
+	if (longitude != NULL)
+		*longitude = gdata_georss_where_get_longitude (self->priv->georss_where);
+}
+
+/**
+ * gdata_picasaweb_file_set_coordinates:
+ * @self: a #GDataPicasaWebFile
+ * @latitude: the file's new latitude coordinate, or %G_MAXDOUBLE
+ * @longitude: the file's new longitude coordinate, or %G_MAXDOUBLE
+ *
+ * Sets the #GDataPicasaWebFile:latitude and #GDataPicasaWebFile:longitude properties to
+ * @latitude and @longitude respectively.
+ *
+ * Since: 0.5.0
+ **/
+void
+gdata_picasaweb_file_set_coordinates (GDataPicasaWebFile *self, gdouble latitude, gdouble longitude)
+{
+	g_return_if_fail (GDATA_IS_PICASAWEB_FILE (self));
+
+	gdata_georss_where_set_latitude (self->priv->georss_where, latitude);
+	gdata_georss_where_set_longitude (self->priv->georss_where, longitude);
+
+	g_object_freeze_notify (G_OBJECT (self));
+	g_object_notify (G_OBJECT (self), "latitude");
+	g_object_notify (G_OBJECT (self), "longitude");
+	g_object_thaw_notify (G_OBJECT (self));
+}
diff --git a/gdata/services/picasaweb/gdata-picasaweb-file.h b/gdata/services/picasaweb/gdata-picasaweb-file.h
index 0d9a391..abfaacd 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-file.h
+++ b/gdata/services/picasaweb/gdata-picasaweb-file.h
@@ -103,6 +103,8 @@ const gchar *gdata_picasaweb_file_get_image_unique_id (GDataPicasaWebFile *self)
 gint gdata_picasaweb_file_get_iso (GDataPicasaWebFile *self);
 const gchar *gdata_picasaweb_file_get_make (GDataPicasaWebFile *self);
 const gchar *gdata_picasaweb_file_get_model (GDataPicasaWebFile *self);
+void gdata_picasaweb_file_get_coordinates (GDataPicasaWebFile *self, gdouble *latitude, gdouble *longitude);
+void gdata_picasaweb_file_set_coordinates (GDataPicasaWebFile *self, gdouble latitude, gdouble longitude);
 
 /* TODO implement is video */
 /* TODO implement get comments */
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index 51e5853..3565412 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -124,8 +124,10 @@ test_upload_simple (GDataService *service)
 				"xmlns:gphoto='http://schemas.google.com/photos/2007' "
 				"xmlns:media='http://video.search.yahoo.com/mrss' "
 				"xmlns:gd='http://schemas.google.com/g/2005' "
-			        "xmlns:exif='http://schemas.google.com/photos/exif/2007' "
-				"xmlns:app='http://www.w3.org/2007/app'>"
+				"xmlns:exif='http://schemas.google.com/photos/exif/2007' "
+				"xmlns:app='http://www.w3.org/2007/app' "
+				"xmlns:georss='http://www.georss.org/georss' "
+				"xmlns:gml='http://www.opengis.net/gml'>"
 				"<title type='text'>Photo Entry Title</title>"
 				"<summary type='text'>Photo Summary</summary>"
 				"<category term='http://schemas.google.com/photos/2007#photo' scheme='http://schemas.google.com/g/2005#kind'/>"
@@ -138,6 +140,8 @@ test_upload_simple (GDataService *service)
 			 "</entry>");
 	g_free(xml);
 
+	gdata_picasaweb_file_set_coordinates (photo, 17.127, -110.35);
+
 	/* File is public domain: http://en.wikipedia.org/wiki/File:German_garden_gnome_cropped.jpg */
 	photo_file = g_file_new_for_path (TEST_FILE_DIR "photo.jpg");
 
@@ -173,6 +177,10 @@ test_photo (GDataService *service)
 	GTimeVal _time;
 	gchar *str;
 	gchar *timestamp;
+	gdouble latitude;
+	gdouble longitude;
+	gdouble original_latitude;
+	gdouble original_longitude;
 
 	album_feed = gdata_picasaweb_service_query_all_albums (GDATA_PICASAWEB_SERVICE (service), NULL, NULL, NULL, NULL, NULL, &error);
 	g_assert_no_error (error);
@@ -257,7 +265,27 @@ test_photo (GDataService *service)
 	g_assert_cmpint (gdata_picasaweb_file_get_iso (photo), ==, 80);
 	g_assert_cmpstr (gdata_picasaweb_file_get_make (photo), ==, "EASTMAN KODAK COMPANY");
 	g_assert_cmpstr (gdata_picasaweb_file_get_model (photo), ==, "KODAK Z740 ZOOM DIGITAL CAMERA");
-	
+
+	/* Check GeoRSS coordinates */
+	gdata_picasaweb_file_get_coordinates (photo, &original_latitude, &original_longitude);
+	g_assert_cmpfloat (original_latitude, ==, 45.4341173);
+	g_assert_cmpfloat (original_longitude, ==, 12.1289062);
+
+	gdata_picasaweb_file_get_coordinates (photo, NULL, &longitude);
+	g_assert_cmpfloat (longitude, ==, 12.1289062);
+	gdata_picasaweb_file_get_coordinates (photo, &latitude, NULL);
+	g_assert_cmpfloat (latitude, ==, 45.4341173);
+	gdata_picasaweb_file_get_coordinates (photo, NULL, NULL);
+
+	gdata_picasaweb_file_set_coordinates (photo, original_longitude, original_latitude);
+	gdata_picasaweb_file_get_coordinates (photo, &latitude, &longitude);
+	g_assert_cmpfloat (latitude, ==, original_longitude);
+	g_assert_cmpfloat (longitude, ==, original_latitude);
+	gdata_picasaweb_file_set_coordinates (photo, original_latitude, original_longitude);
+	gdata_picasaweb_file_get_coordinates (photo, &latitude, &longitude);
+	g_assert_cmpfloat (latitude, ==, 45.4341173);
+	g_assert_cmpfloat (longitude, ==, 12.1289062);
+
 	g_free (timestamp);
 }
 
@@ -362,6 +390,10 @@ test_album (GDataService *service)
 	GList *albums;
 	GTimeVal _time;
 	gchar *str;
+	gdouble latitude;
+	gdouble longitude;
+	gdouble original_latitude;
+	gdouble original_longitude;
 	gchar *original_rights;
 
 	album_feed = gdata_picasaweb_service_query_all_albums (GDATA_PICASAWEB_SERVICE (service), NULL, NULL, NULL, NULL, NULL, &error);
@@ -383,7 +415,7 @@ test_album (GDataService *service)
 
 	g_assert_cmpstr (gdata_picasaweb_album_get_description (album), ==, "This is the test description.  This album should be in Venice.");
 	g_assert_cmpint (gdata_picasaweb_album_get_visibility (album), ==, GDATA_PICASAWEB_PUBLIC);
-	/* Google doesn't seem to be returning this one any more */
+	/* TODO: Google doesn't seem to be returning this one any more; investigate */
 	/*g_assert_cmpstr (gdata_picasaweb_album_get_name (album), ==, "TestAlbum1VenicePublic");*/
 	g_assert_cmpstr (gdata_picasaweb_album_get_location (album), ==, "Venice");
 
@@ -396,6 +428,27 @@ test_album (GDataService *service)
 	g_assert_cmpuint (gdata_picasaweb_album_get_num_photos_remaining (album), ==, 499);
 	g_assert_cmpuint (gdata_picasaweb_album_get_bytes_used (album), ==, 1124730);
 
+	gdata_picasaweb_album_get_coordinates (album, &latitude, &longitude);
+	g_assert_cmpfloat (latitude, ==, 45.434336);
+	gdata_picasaweb_album_get_coordinates (album, &original_latitude, &original_longitude);
+	g_assert_cmpfloat (original_latitude, ==, 45.434336);
+	g_assert_cmpfloat (original_longitude, ==, 12.338784);
+
+	gdata_picasaweb_album_get_coordinates (album, NULL, &longitude);
+	g_assert_cmpfloat (longitude, ==, 12.338784);
+	gdata_picasaweb_album_get_coordinates (album, &latitude, NULL);
+	g_assert_cmpfloat (latitude, ==, 45.434336);
+	gdata_picasaweb_album_get_coordinates (album, NULL, NULL);
+
+	gdata_picasaweb_album_set_coordinates (album, original_longitude, original_latitude);
+	gdata_picasaweb_album_get_coordinates (album, &latitude, &longitude);
+	g_assert_cmpfloat (latitude, ==, original_longitude);
+	g_assert_cmpfloat (longitude, ==, original_latitude);
+	gdata_picasaweb_album_set_coordinates (album, original_latitude, original_longitude);
+	gdata_picasaweb_album_get_coordinates (album, &original_latitude, &original_longitude);
+	g_assert_cmpfloat (original_latitude, ==, 45.434336);
+	g_assert_cmpfloat (original_longitude, ==, 12.338784);
+
 	/* Test visibility and its synchronisation with its GDataEntry's rights */
 	original_rights = g_strdup (gdata_entry_get_rights (GDATA_ENTRY (album)));
 
@@ -406,12 +459,12 @@ test_album (GDataService *service)
 	gdata_entry_set_rights (GDATA_ENTRY (album), "public");
 	g_assert_cmpstr (gdata_entry_get_rights (GDATA_ENTRY (album)), ==, "public");
 	g_assert_cmpint (gdata_picasaweb_album_get_visibility (album), ==, GDATA_PICASAWEB_PUBLIC);
-	
-	gdata_picasaweb_album_set_visibility (album, GDATA_PICASAWEB_PRIVATE);   
+
+	gdata_picasaweb_album_set_visibility (album, GDATA_PICASAWEB_PRIVATE);
 	g_assert_cmpstr (gdata_entry_get_rights (GDATA_ENTRY (album)), ==, "private");
 	g_assert_cmpint (gdata_picasaweb_album_get_visibility (album), ==, GDATA_PICASAWEB_PRIVATE);
 
-	gdata_picasaweb_album_set_visibility (album, GDATA_PICASAWEB_PUBLIC);    
+	gdata_picasaweb_album_set_visibility (album, GDATA_PICASAWEB_PUBLIC);
 	g_assert_cmpstr (gdata_entry_get_rights (GDATA_ENTRY (album)), ==, "public");
 	g_assert_cmpint (gdata_picasaweb_album_get_visibility (album), ==, GDATA_PICASAWEB_PUBLIC);
 
@@ -461,9 +514,6 @@ test_album_feed_entry (GDataService *service)
 	g_assert_cmpstr (str, ==, "2009-04-26T07:00:00Z");
 	g_free (str);
 
-	/* g_assert_cmpstr (gdata_entry_get_content (entry), !=, NULL); */
-	/* TODO */
-	printf("** WARNING:%s:%d: gdata_entry_get_content(entry) returns null; valid?\n", __FILE__, __LINE__);
 	xml = gdata_parsable_get_xml (GDATA_PARSABLE (entry));
 	g_assert_cmpstr (xml, !=, NULL);
 	g_assert_cmpuint (strlen (xml), >, 0);



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