/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/*
* GData Client
* Copyright (C) Richard Schwarting 2009 <aquarichy@gmail.com>
* Copyright (C) Philip Withnall 2009–2010 <philip@tecnocode.co.uk>
*
* GData Client is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* GData Client is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with GData Client. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* SECTION:gdata-picasaweb-album
* @short_description: GData PicasaWeb album object
* @stability: Stable
* @include: gdata/services/picasaweb/gdata-picasaweb-album.h
*
* #GDataPicasaWebAlbum is a subclass of #GDataEntry to represent an album from Google PicasaWeb.
*
* For more details of Google PicasaWeb's GData API, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html">
* online documentation</ulink>.
*
* <example>
* <title>Getting Basic Album Data</title>
* <programlisting>
* GDataFeed *album_feed;
* GList *album_entries;
*
* /<!-- -->* Query for a feed of GDataPicasaWebAlbum<!-- -->s owned by user "libgdata.picasaweb" *<!-- -->/
* album_feed = gdata_picasaweb_service_query_all_albums (service, NULL, "libgdata.picasaweb", NULL, NULL, NULL, NULL);
*
* /<!-- -->* Get a list of GDataPicasaWebAlbum<!-- -->s from the query's feed *<!-- -->/
* for (album_entries = gdata_feed_get_entries (album_feed); album_entries != NULL; album_entries = album_entries->next) {
* GDataPicasaWebAlbum *album;
* guint num_photos;
* const gchar *owner_nickname, *title, *summary;
* gint64 timestamp;
* GList *thumbnails;
*
* album = GDATA_PICASAWEB_ALBUM (album_entries->data);
*
* /<!-- -->* Get various bits of information about the album *<!-- -->/
* num_photos = gdata_picasaweb_album_get_num_photos (album);
* owner_nickname = gdata_picasaweb_album_get_nickname (album);
* title = gdata_entry_get_title (GDATA_ENTRY (album));
* summary = gdata_entry_get_summary (GDATA_ENTRY (album));
* /<!-- -->* Get the day the album was shot on or, if not set, when it was uploaded. This is in milliseconds since the epoch. *<!-- -->/
* timestamp = gdata_picasaweb_album_get_timestamp (album);
*
* for (thumbnails = gdata_picasaweb_album_get_thumbnails (album); thumbnails != NULL; thumbnails = thumbnails->next) {
* GDataMediaThumbnail *thumbnail;
* GDataDownloadStream *download_stream;
* GdkPixbuf *pixbuf;
*
* thumbnail = GDATA_MEDIA_THUMBNAIL (thumbnails->data);
* /<!-- -->* Do something fun with the thumbnails, like download and display them. We could just as easily download them into
* * files using g_file_create() and g_output_stream_splice(), rather than create GdkPixbuf<!-- -->s directly from them.
* * Note that this is a blocking operation. *<!-- -->/
* download_stream = gdata_media_thumbnail_download (thumbnail, GDATA_SERVICE (service), NULL, NULL);
* pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (download_stream), NULL, NULL);
* g_object_unref (download_stream);
* /<!-- -->* ... *<!-- -->/
* g_object_unref (pixbuf);
* }
*
* /<!-- -->* Do something worthwhile with your album data *<!-- -->/
* }
*
* g_object_unref (album_feed);
* </programlisting>
* </example>
*
* Since: 0.4.0
*/
/* TODO: support the album cover/icon ? I think this is already done with the thumbnails, but we don't set it yet :( */
#include <config.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <libxml/parser.h>
#include <string.h>
#include "gdata-picasaweb-album.h"
#include "gdata-private.h"
#include "gdata-service.h"
#include "gdata-parsable.h"
#include "gdata-parser.h"
#include "gdata-types.h"
#include "media/gdata-media-group.h"
#include "gdata-picasaweb-enums.h"
#include "georss/gdata-georss-where.h"
static GObject *gdata_picasaweb_album_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params);
static void gdata_picasaweb_album_dispose (GObject *object);
static void gdata_picasaweb_album_finalize (GObject *object);
static void gdata_picasaweb_album_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static void gdata_picasaweb_album_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
static void get_xml (GDataParsable *parsable, GString *xml_string);
static gboolean parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error);
static void get_namespaces (GDataParsable *parsable, GHashTable *namespaces);
struct _GDataPicasaWebAlbumPrivate {
gchar *album_id;
gchar *user;
gchar *nickname;
gint64 edited;
gchar *location;
GDataPicasaWebVisibility visibility;
gint64 timestamp; /* in milliseconds! */
guint num_photos;
guint num_photos_remaining;
glong bytes_used;
gboolean is_commenting_enabled;
guint comment_count;
/* media:group */
GDataMediaGroup *media_group;
/* georss:where */
GDataGeoRSSWhere *georss_where;
};
enum {
PROP_USER = 1,
PROP_NICKNAME,
PROP_EDITED,
PROP_LOCATION,
PROP_VISIBILITY,
PROP_TIMESTAMP,
PROP_NUM_PHOTOS,
PROP_NUM_PHOTOS_REMAINING,
PROP_BYTES_USED,
PROP_IS_COMMENTING_ENABLED,
PROP_COMMENT_COUNT,
PROP_TAGS,
PROP_LATITUDE,
PROP_LONGITUDE,
PROP_ALBUM_ID
};
G_DEFINE_TYPE (GDataPicasaWebAlbum, gdata_picasaweb_album, GDATA_TYPE_ENTRY)
static void
gdata_picasaweb_album_class_init (GDataPicasaWebAlbumClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GDataParsableClass *parsable_class = GDATA_PARSABLE_CLASS (klass);
GDataEntryClass *entry_class = GDATA_ENTRY_CLASS (klass);
g_type_class_add_private (klass, sizeof (GDataPicasaWebAlbumPrivate));
gobject_class->constructor = gdata_picasaweb_album_constructor;
gobject_class->get_property = gdata_picasaweb_album_get_property;
gobject_class->set_property = gdata_picasaweb_album_set_property;
gobject_class->dispose = gdata_picasaweb_album_dispose;
gobject_class->finalize = gdata_picasaweb_album_finalize;
parsable_class->parse_xml = parse_xml;
parsable_class->get_xml = get_xml;
parsable_class->get_namespaces = get_namespaces;
entry_class->kind_term = "http://schemas.google.com/photos/2007#album";
/**
* GDataPicasaWebAlbum:album-id:
*
* The ID of the album. This is a substring of the ID returned by gdata_entry_get_id() for #GDataPicasaWebAlbum<!-- -->s; for example,
* if gdata_entry_get_id() returned "http://picasaweb.google.com/data/entry/user/libgdata.picasaweb/albumid/5328889949261497249" for a
* particular #GDataPicasaWebAlbum, the #GDataPicasaWebAlbum:album-id property would be "5328889949261497249".
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_id">
* gphoto specification</ulink>.
*
* Since: 0.7.0
*/
g_object_class_install_property (gobject_class, PROP_ALBUM_ID,
g_param_spec_string ("album-id",
"Album ID", "The ID of the album.",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:user:
*
* The username of the album owner.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_user">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_USER,
g_param_spec_string ("user",
"User", "The username of the album owner.",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:nickname:
*
* The user's nickname. This is a user-specified value that should be used when referring to the user by name.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_nickname">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_NICKNAME,
g_param_spec_string ("nickname",
"Nickname", "The user's nickname.",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:edited:
*
* The time this album was last edited. If the album has not been edited yet, the content indicates the time it was created.
*
* For more information, see the <ulink type="http" url="http://www.atomenabled.org/developers/protocol/#appEdited">
* Atom Publishing Protocol specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_EDITED,
g_param_spec_int64 ("edited",
"Edited", "The time this album was last edited.",
-1, G_MAXINT64, -1,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:location:
*
* The user-specified location associated with the album. A place name.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_location">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_LOCATION,
g_param_spec_string ("location",
"Location", "The user-specified location associated with the album.",
NULL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:visibility:
*
* The visibility (or access rights) of the album.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_access">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_VISIBILITY,
g_param_spec_enum ("visibility",
"Visibility", "The visibility (or access rights) of the album.",
GDATA_TYPE_PICASAWEB_VISIBILITY, GDATA_PICASAWEB_PRIVATE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:timestamp:
*
* The timestamp of when the album occurred, settable by the user. This a UNIX timestamp in milliseconds (not seconds) since the epoch.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_timestamp">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_TIMESTAMP,
g_param_spec_int64 ("timestamp",
"Timestamp", "The timestamp of when the album occurred, settable by the user.",
-1, G_MAXINT64, -1,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/* TODO: Change to photo-count? */
/**
* GDataPicasaWebAlbum:num-photos:
*
* The number of photos and videos in the album.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_numphotos">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_NUM_PHOTOS,
g_param_spec_uint ("num-photos",
"Number of photos", "The number of photos and videos in the album.",
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/* TODO: Change to remaining-photos-count? */
/**
* GDataPicasaWebAlbum:num-photos-remaining:
*
* The number of photos and videos that can still be uploaded to this album.
* This doesn't account for quota, just a hardcoded maximum number per album set by Google.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_numphotosremaining">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_NUM_PHOTOS_REMAINING,
g_param_spec_uint ("num-photos-remaining",
"Number of photo spaces remaining", "The number of files spaces still free for uploads.",
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:bytes-used:
*
* The number of bytes consumed by this album and its contents. Note that this is only set if the authenticated user is the owner of the
* album; it's otherwise <code class="literal">-1</code>.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_bytesUsed">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_BYTES_USED,
g_param_spec_long ("bytes-used",
"Number of bytes used", "The number of bytes consumed by this album and its contents.",
-1, G_MAXLONG, -1,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:commenting-enabled:
*
* Whether commenting is enabled for this album.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_IS_COMMENTING_ENABLED,
g_param_spec_boolean ("is-commenting-enabled",
"Commenting enabled?", "Whether commenting is enabled for this album.",
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:comment-count:
*
* The number of comments on the album.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#gphoto_commentCount">
* gphoto specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_COMMENT_COUNT,
g_param_spec_uint ("comment-count",
"Comment count", "The number of comments on the album.",
0, G_MAXUINT, 0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:tags:
*
* A %NULL-terminated array of tags associated with the album; all the tags associated with the individual photos in the album.
*
* For more information, see the <ulink type="http" url="http://code.google.com/apis/picasaweb/reference.html#media_keywords">
* Media RSS specification</ulink>.
*
* Since: 0.4.0
*/
g_object_class_install_property (gobject_class, PROP_TAGS,
g_param_spec_boxed ("tags",
"Tags", "A NULL-terminated array of tags associated with the album",
G_TYPE_STRV,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GDataPicasaWebAlbum:latitude:
*
* The location as a latitude coordinate associated with this album. Valid latitudes range from <code class="literal">-90.0</code>
* to <code class="literal">90.0</code> 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 <code class="literal">-180.0</code>
* to <code class="literal">180.0</code> 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
notify_title_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_data)
{
/* Update our media:group title */
if (self->priv->media_group != NULL)
gdata_media_group_set_title (self->priv->media_group, gdata_entry_get_title (GDATA_ENTRY (self)));
}
static void
notify_summary_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_data)
{
/* Update our media:group description */
if (self->priv->media_group != NULL)
gdata_media_group_set_description (self->priv->media_group, gdata_entry_get_summary (GDATA_ENTRY (self)));
}
static void notify_visibility_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_data);
static void
notify_rights_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_data)
{
const gchar *rights = gdata_entry_get_rights (GDATA_ENTRY (self));
/* Update our gphoto:visibility */
g_signal_handlers_block_by_func (self, notify_visibility_cb, NULL);
if (rights == NULL || strcmp (rights, "public") == 0) {
gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PUBLIC);
} else if (strcmp (rights, "private") == 0) {
gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PRIVATE);
} else {
/* Print out a warning and leave the visibility as it is */
g_warning ("Unknown <rights> or <gd:access> value: %s", rights);
}
g_signal_handlers_unblock_by_func (self, notify_visibility_cb, NULL);
}
static void
notify_visibility_cb (GDataPicasaWebAlbum *self, GParamSpec *pspec, gpointer user_data)
{
/* Update our GDataEntry's atom:rights */
g_signal_handlers_block_by_func (self, notify_rights_cb, NULL);
switch (self->priv->visibility) {
case GDATA_PICASAWEB_PUBLIC:
gdata_entry_set_rights (GDATA_ENTRY (self), "public");
break;
case GDATA_PICASAWEB_PRIVATE:
gdata_entry_set_rights (GDATA_ENTRY (self), "private");
break;
default:
g_assert_not_reached ();
}
g_signal_handlers_unblock_by_func (self, notify_rights_cb, NULL);
}
static void
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);
self->priv->edited = -1;
self->priv->timestamp = -1;
/* Set the initial visibility */
self->priv->visibility = GDATA_PICASAWEB_PRIVATE;
gdata_entry_set_rights (GDATA_ENTRY (self), "private");
/* Connect to the notify::title signal from GDataEntry so our media:group title can be kept in sync
* (the title of an album is duplicated in atom:title and media:group/media:title) */
g_signal_connect (GDATA_ENTRY (self), "notify::title", G_CALLBACK (notify_title_cb), NULL);
/* Connect to the notify::description signal from GDataEntry so our media:group description can be kept in sync
* (the description of an album is duplicated in atom:summary and media:group/media:description) */
g_signal_connect (GDATA_ENTRY (self), "notify::summary", G_CALLBACK (notify_summary_cb), NULL);
/* Connect to the notify::rights signal from GDataEntry so our gphoto:visibility can be kept in sync (and vice-versa)
* (visibility settings are duplicated in atom:rights and gphoto:visibility) */
g_signal_connect (GDATA_ENTRY (self), "notify::rights", G_CALLBACK (notify_rights_cb), NULL);
g_signal_connect (self, "notify::visibility", G_CALLBACK (notify_visibility_cb), NULL);
}
static GObject *
gdata_picasaweb_album_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params)
{
GObject *object;
/* Chain up to the parent class */
object = G_OBJECT_CLASS (gdata_picasaweb_album_parent_class)->constructor (type, n_construct_params, construct_params);
if (_gdata_parsable_is_constructed_from_xml (GDATA_PARSABLE (object)) == FALSE) {
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (object)->priv;
GTimeVal time_val;
/* Set the edited and timestamp properties to the current time (creation time). bgo#599140
* We don't do this in *_init() since that would cause setting it from parse_xml() to fail (duplicate element). */
g_get_current_time (&time_val);
priv->timestamp = (gint64) time_val.tv_sec * 1000;
priv->edited = time_val.tv_sec;
}
return object;
}
static void
gdata_picasaweb_album_dispose (GObject *object)
{
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (object)->priv;
if (priv->media_group != NULL)
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);
}
static void
gdata_picasaweb_album_finalize (GObject *object)
{
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (object)->priv;
g_free (priv->album_id);
g_free (priv->user);
g_free (priv->nickname);
g_free (priv->location);
/* Chain up to the parent class */
G_OBJECT_CLASS (gdata_picasaweb_album_parent_class)->finalize (object);
}
static void
gdata_picasaweb_album_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
{
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (object)->priv;
switch (property_id) {
case PROP_ALBUM_ID:
g_value_set_string (value, priv->album_id);
break;
case PROP_USER:
g_value_set_string (value, priv->user);
break;
case PROP_NICKNAME:
g_value_set_string (value, priv->nickname);
break;
case PROP_EDITED:
g_value_set_int64 (value, priv->edited);
break;
case PROP_LOCATION:
g_value_set_string (value, priv->location);
break;
case PROP_VISIBILITY:
g_value_set_enum (value, priv->visibility);
break;
case PROP_TIMESTAMP:
g_value_set_int64 (value, priv->timestamp);
break;
case PROP_NUM_PHOTOS:
g_value_set_uint (value, priv->num_photos);
break;
case PROP_NUM_PHOTOS_REMAINING:
g_value_set_uint (value, priv->num_photos_remaining);
break;
case PROP_BYTES_USED:
g_value_set_long (value, priv->bytes_used);
break;
case PROP_IS_COMMENTING_ENABLED:
g_value_set_boolean (value, priv->is_commenting_enabled);
break;
case PROP_COMMENT_COUNT:
g_value_set_uint (value, priv->comment_count);
break;
case PROP_TAGS:
g_value_set_boxed (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);
break;
}
}
static void
gdata_picasaweb_album_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
{
GDataPicasaWebAlbum *self = GDATA_PICASAWEB_ALBUM (object);
switch (property_id) {
case PROP_ALBUM_ID:
/* Construct only */
g_free (self->priv->album_id);
self->priv->album_id = g_value_dup_string (value);
break;
case PROP_LOCATION:
gdata_picasaweb_album_set_location (self, g_value_get_string (value));
break;
case PROP_VISIBILITY:
gdata_picasaweb_album_set_visibility (self, g_value_get_enum (value));
break;
case PROP_TIMESTAMP:
gdata_picasaweb_album_set_timestamp (self, g_value_get_int64 (value));
break;
case PROP_IS_COMMENTING_ENABLED:
gdata_picasaweb_album_set_is_commenting_enabled (self, g_value_get_boolean (value));
break;
case PROP_TAGS:
gdata_picasaweb_album_set_tags (self, g_value_get_boxed (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);
break;
}
}
static gboolean
parse_xml (GDataParsable *parsable, xmlDoc *doc, xmlNode *node, gpointer user_data, GError **error)
{
gboolean success;
GDataPicasaWebAlbum *self = GDATA_PICASAWEB_ALBUM (parsable);
/* TODO: media:group should also be P_NO_DUPES, but we can't, as priv->media_group has to be pre-populated
* in order for things like gdata_picasaweb_album_get_tags() to work. */
if (gdata_parser_is_namespace (node, "http://www.w3.org/2007/app") == TRUE &&
gdata_parser_int64_time_from_element (node, "edited", P_REQUIRED | P_NO_DUPES, &(self->priv->edited), &success, error) == TRUE) {
return success;
} else if (gdata_parser_is_namespace (node, "http://search.yahoo.com/mrss/") == TRUE &&
gdata_parser_object_from_element (node, "group", P_REQUIRED, GDATA_TYPE_MEDIA_GROUP,
&(self->priv->media_group), &success, error) == TRUE) {
return success;
} else if (gdata_parser_is_namespace (node, "http://www.georss.org/georss") == TRUE &&
gdata_parser_object_from_element (node, "where", P_REQUIRED, GDATA_TYPE_GEORSS_WHERE,
&(self->priv->georss_where), &success, error) == TRUE) {
return success;
} else if (gdata_parser_is_namespace (node, "http://schemas.google.com/photos/2007") == TRUE) {
if (gdata_parser_string_from_element (node, "user", P_REQUIRED | P_NON_EMPTY, &(self->priv->user), &success, error) == TRUE ||
gdata_parser_string_from_element (node, "nickname", P_REQUIRED | P_NON_EMPTY, &(self->priv->nickname), &success, error) == TRUE ||
gdata_parser_string_from_element (node, "location", P_NONE, &(self->priv->location), &success, error) == TRUE ||
gdata_parser_string_from_element (node, "id", P_REQUIRED | P_NON_EMPTY | P_NO_DUPES,
&(self->priv->album_id), &success, error) == TRUE) {
return success;
} else if (xmlStrcmp (node->name, (xmlChar*) "access") == 0) {
/* gphoto:access */
xmlChar *access_level = xmlNodeListGetString (doc, node->children, TRUE);
if (xmlStrcmp (access_level, (xmlChar*) "public") == 0) {
gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PUBLIC);
} else if (xmlStrcmp (access_level, (xmlChar*) "private") == 0 ||
xmlStrcmp (access_level, (xmlChar*) "protected") == 0) {
gdata_picasaweb_album_set_visibility (self, GDATA_PICASAWEB_PRIVATE);
} else {
gdata_parser_error_unknown_content (node, (gchar*) access_level, error);
xmlFree (access_level);
return FALSE;
}
xmlFree (access_level);
} else if (xmlStrcmp (node->name, (xmlChar*) "timestamp") == 0) {
/* gphoto:timestamp */
xmlChar *timestamp_str;
guint64 milliseconds;
timestamp_str = xmlNodeListGetString (doc, node->children, TRUE);
milliseconds = g_ascii_strtoull ((gchar*) timestamp_str, NULL, 10);
xmlFree (timestamp_str);
gdata_picasaweb_album_set_timestamp (self, (gint64) milliseconds);
} else if (xmlStrcmp (node->name, (xmlChar*) "numphotos") == 0) {
/* gphoto:numphotos */
xmlChar *num_photos = xmlNodeListGetString (doc, node->children, TRUE);
if (num_photos == NULL || *num_photos == '\0') {
xmlFree (num_photos);
return gdata_parser_error_required_content_missing (node, error);
}
self->priv->num_photos = g_ascii_strtoull ((char*) num_photos, NULL, 10);
xmlFree (num_photos);
} else if (xmlStrcmp (node->name, (xmlChar*) "numphotosremaining") == 0) {
/* gphoto:numphotosremaining */
xmlChar *num_photos_remaining = xmlNodeListGetString (doc, node->children, TRUE);
if (num_photos_remaining == NULL || *num_photos_remaining == '\0') {
xmlFree (num_photos_remaining);
return gdata_parser_error_required_content_missing (node, error);
}
self->priv->num_photos_remaining = g_ascii_strtoull ((char*) num_photos_remaining, NULL, 10);
xmlFree (num_photos_remaining);
} else if (xmlStrcmp (node->name, (xmlChar*) "bytesUsed") == 0) {
/* gphoto:bytesUsed */
xmlChar *bytes_used = xmlNodeListGetString (doc, node->children, TRUE);
if (bytes_used == NULL || *bytes_used == '\0') {
xmlFree (bytes_used);
return gdata_parser_error_required_content_missing (node, error);
}
self->priv->bytes_used = g_ascii_strtoll ((char*) bytes_used, NULL, 10);
xmlFree (bytes_used);
} else if (xmlStrcmp (node->name, (xmlChar*) "commentingEnabled") == 0) {
/* gphoto:commentingEnabled */
xmlChar *commenting_enabled = xmlNodeListGetString (doc, node->children, TRUE);
if (commenting_enabled == NULL || *commenting_enabled == '\0') {
xmlFree (commenting_enabled);
return gdata_parser_error_required_content_missing (node, error);
}
gdata_picasaweb_album_set_is_commenting_enabled (self,
(xmlStrcmp (commenting_enabled, (xmlChar*) "true") == 0) ? TRUE : FALSE);
xmlFree (commenting_enabled);
} else if (xmlStrcmp (node->name, (xmlChar*) "commentCount") == 0) {
/* gphoto:commentCount */
xmlChar *comment_count = xmlNodeListGetString (doc, node->children, TRUE);
if (comment_count == NULL || *comment_count == '\0') {
xmlFree (comment_count);
return gdata_parser_error_required_content_missing (node, error);
}
self->priv->comment_count = g_ascii_strtoull ((char*) comment_count, NULL, 10);
xmlFree (comment_count);
} else {
return GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->parse_xml (parsable, doc, node, user_data, error);
}
} else {
return GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->parse_xml (parsable, doc, node, user_data, error);
}
return TRUE;
}
static void
get_xml (GDataParsable *parsable, GString *xml_string)
{
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (parsable)->priv;
/* Chain up to the parent class */
GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->get_xml (parsable, xml_string);
/* Add all the album-specific XML */
if (priv->album_id != NULL)
gdata_parser_string_append_escaped (xml_string, "<gphoto:id>", priv->album_id, "</gphoto:id>");
if (priv->location != NULL)
gdata_parser_string_append_escaped (xml_string, "<gphoto:location>", priv->location, "</gphoto:location>");
switch (priv->visibility) {
case GDATA_PICASAWEB_PUBLIC:
g_string_append (xml_string, "<gphoto:access>public</gphoto:access>");
break;
case GDATA_PICASAWEB_PRIVATE:
g_string_append (xml_string, "<gphoto:access>private</gphoto:access>");
break;
default:
g_assert_not_reached ();
}
if (priv->timestamp != -1) {
/* in milliseconds */
g_string_append_printf (xml_string, "<gphoto:timestamp>%" G_GINT64_FORMAT "</gphoto:timestamp>", priv->timestamp);
}
if (priv->is_commenting_enabled == FALSE)
g_string_append (xml_string, "<gphoto:commentingEnabled>false</gphoto:commentingEnabled>");
else
g_string_append (xml_string, "<gphoto:commentingEnabled>true</gphoto:commentingEnabled>");
/* 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
*/
}
static void
get_namespaces (GDataParsable *parsable, GHashTable *namespaces)
{
GDataPicasaWebAlbumPrivate *priv = GDATA_PICASAWEB_ALBUM (parsable)->priv;
/* Chain up to the parent class */
GDATA_PARSABLE_CLASS (gdata_picasaweb_album_parent_class)->get_namespaces (parsable, namespaces);
g_hash_table_insert (namespaces, (gchar*) "gphoto", (gchar*) "http://schemas.google.com/photos/2007");
g_hash_table_insert (namespaces, (gchar*) "app", (gchar*) "http://www.w3.org/2007/app");
/* 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);
}
/**
* gdata_picasaweb_album_new:
* @id: (allow-none): the album's entry ID, or %NULL
*
* Creates a new #GDataPicasaWebAlbum with the given ID and default properties. @id is the ID which would be returned by gdata_entry_get_id(),
* not gdata_picasaweb_album_get_id().
*
* If @id is not %NULL and can't be parsed to extract an album ID, %NULL will be returned.
*
* Return value: a new #GDataPicasaWebAlbum, or %NULL; unref with g_object_unref()
*
* Since: 0.4.0
*/
GDataPicasaWebAlbum *
gdata_picasaweb_album_new (const gchar *id)
{
const gchar *album_id = NULL, *i;
if (id != NULL) {
album_id = g_strrstr (id, "/");
if (album_id == NULL)
return NULL;
album_id++; /* skip the slash */
/* Ensure the @album_id is entirely numeric */
for (i = album_id; *i != '\0'; i = g_utf8_next_char (i)) {
if (g_unichar_isdigit (g_utf8_get_char (i)) == FALSE)
return NULL;
}
}
return GDATA_PICASAWEB_ALBUM (g_object_new (GDATA_TYPE_PICASAWEB_ALBUM, "id", id, "album-id", album_id, NULL));
}
/**
* gdata_picasaweb_album_get_id:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:album-id property.
*
* Return value: the album's ID
*
* Since: 0.7.0
*/
const gchar *
gdata_picasaweb_album_get_id (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return self->priv->album_id;
}
/**
* gdata_picasaweb_album_get_user:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:user property.
*
* Return value: the album owner's username
*
* Since: 0.4.0
*/
const gchar *
gdata_picasaweb_album_get_user (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return self->priv->user;
}
/**
* gdata_picasaweb_album_get_nickname:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:nickname property.
*
* Return value: the album owner's nickname
*
* Since: 0.4.0
*/
const gchar *
gdata_picasaweb_album_get_nickname (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return self->priv->nickname;
}
/**
* gdata_picasaweb_album_get_edited:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:edited property. If the property is unset, <code class="literal">-1</code> will be returned.
*
* Return value: the UNIX timestamp for the time the album was last edited, or <code class="literal">-1</code>
*
* Since: 0.4.0
*/
gint64
gdata_picasaweb_album_get_edited (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), -1);
return self->priv->edited;
}
/**
* gdata_picasaweb_album_get_location:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:location property.
*
* Return value: the album's location, or %NULL
*
* Since: 0.4.0
*/
const gchar *
gdata_picasaweb_album_get_location (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return self->priv->location;
}
/**
* gdata_picasaweb_album_set_location:
* @self: a #GDataPicasaWebAlbum
* @location: (allow-none): the new album location, or %NULL
*
* Sets the #GDataPicasaWebAlbum:location property to @location.
*
* Set @location to %NULL to unset the property.
*
* Since: 0.4.0
*/
void
gdata_picasaweb_album_set_location (GDataPicasaWebAlbum *self, const gchar *location)
{
g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
g_free (self->priv->location);
self->priv->location = g_strdup (location);
g_object_notify (G_OBJECT (self), "location");
}
/**
* gdata_picasaweb_album_get_visibility:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:visibility property.
*
* Return value: the album's visibility level
*
* Since: 0.4.0
*/
GDataPicasaWebVisibility
gdata_picasaweb_album_get_visibility (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), GDATA_PICASAWEB_PUBLIC);
return self->priv->visibility;
}
/**
* gdata_picasaweb_album_set_visibility:
* @self: a #GDataPicasaWebAlbum
* @visibility: the new album visibility level
*
* Sets the #GDataPicasaWebAlbum:visibility property to @visibility.
*
* Since: 0.4.0
*/
void
gdata_picasaweb_album_set_visibility (GDataPicasaWebAlbum *self, GDataPicasaWebVisibility visibility)
{
g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
self->priv->visibility = visibility;
g_object_notify (G_OBJECT (self), "visibility");
}
/**
* gdata_picasaweb_album_get_timestamp:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:timestamp property. This value usually holds either the date that best corresponds to the album of photos, or to the
* day it was uploaded. It's a UNIX timestamp in milliseconds (not seconds) since the epoch. If the property is unset, <code class="literal">-1</code>
* will be returned.
*
* Return value: the UNIX timestamp for the timestamp property in milliseconds, or <code class="literal">-1</code>
*
* Since: 0.4.0
*/
gint64
gdata_picasaweb_album_get_timestamp (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), -1);
return self->priv->timestamp;
}
/**
* gdata_picasaweb_album_set_timestamp:
* @self: a #GDataPicasaWebAlbum
* @timestamp: a UNIX timestamp, or <code class="literal">-1</code>
*
* Sets the #GDataPicasaWebAlbum:timestamp property from @timestamp. This should be a UNIX timestamp in milliseconds (not seconds) since the epoch.
*
* Set @timestamp to <code class="literal">-1</code> to unset the property.
*
* Since: 0.4.0
*/
void
gdata_picasaweb_album_set_timestamp (GDataPicasaWebAlbum *self, gint64 timestamp)
{
g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
g_return_if_fail (timestamp >= -1);
self->priv->timestamp = timestamp;
g_object_notify (G_OBJECT (self), "timestamp");
}
/**
* gdata_picasaweb_album_get_num_photos:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:num-photos property.
*
* Return value: the number of photos currently in the album
*
* Since: 0.4.0
*/
guint
gdata_picasaweb_album_get_num_photos (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), 0);
return self->priv->num_photos;
}
/**
* gdata_picasaweb_album_get_num_photos_remaining:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:num-photos-remaining property.
*
* Return value: the number of photos that can still be uploaded to the album
*
* Since: 0.4.0
*/
guint
gdata_picasaweb_album_get_num_photos_remaining (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), 0);
return self->priv->num_photos_remaining;
}
/**
* gdata_picasaweb_album_get_bytes_used:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:bytes-used property. It will return <code class="literal">-1</code> if the current authenticated
* user is not the owner of the album.
*
* Return value: the number of bytes used by the album and its contents, or <code class="literal">-1</code>
*
* Since: 0.4.0
*/
glong
gdata_picasaweb_album_get_bytes_used (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), -1);
return self->priv->bytes_used;
}
/**
* gdata_picasaweb_album_is_commenting_enabled:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:is-commenting-enabled property.
*
* Return value: %TRUE if commenting is enabled for the album, %FALSE otherwise
*
* Since: 0.4.0
*/
gboolean
gdata_picasaweb_album_is_commenting_enabled (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), FALSE);
return self->priv->is_commenting_enabled;
}
/**
* gdata_picasaweb_album_set_is_commenting_enabled:
* @self: a #GDataPicasaWebAlbum
* @is_commenting_enabled: %TRUE if commenting should be enabled for the album, %FALSE otherwise
*
* Sets the #GDataPicasaWebAlbum:is-commenting-enabled property to @is_commenting_enabled.
*
* Since: 0.4.0
*/
void
gdata_picasaweb_album_set_is_commenting_enabled (GDataPicasaWebAlbum *self, gboolean is_commenting_enabled)
{
g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
self->priv->is_commenting_enabled = is_commenting_enabled;
g_object_notify (G_OBJECT (self), "is-commenting-enabled");
}
/**
* gdata_picasaweb_album_get_comment_count:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:comment-count property.
*
* Return value: the number of comments on the album
*
* Since: 0.4.0
*/
guint
gdata_picasaweb_album_get_comment_count (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), 0);
return self->priv->comment_count;
}
/**
* gdata_picasaweb_album_get_tags:
* @self: a #GDataPicasaWebAlbum
*
* Gets the #GDataPicasaWebAlbum:tags property.
*
* Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of tags associated with all the photos in the album, or %NULL
*
* Since: 0.4.0
*/
const gchar * const *
gdata_picasaweb_album_get_tags (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return gdata_media_group_get_keywords (self->priv->media_group);
}
/**
* gdata_picasaweb_album_set_tags:
* @self: a #GDataPicasaWebAlbum
* @tags: (array zero-terminated=1) (allow-none): the new %NULL-terminated array of tags, or %NULL
*
* Sets the #GDataPicasaWebAlbum:tags property to @tags.
*
* Set @tags to %NULL to unset the album's tag list.
*
* Since: 0.4.0
*/
void
gdata_picasaweb_album_set_tags (GDataPicasaWebAlbum *self, const gchar * const *tags)
{
g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (self));
gdata_media_group_set_keywords (self->priv->media_group, tags);
g_object_notify (G_OBJECT (self), "tags");
}
/**
* gdata_picasaweb_album_get_contents:
* @self: a #GDataPicasaWebAlbum
*
* Returns a list of media content, such as the cover image for the album.
*
* Return value: (element-type GData.MediaContent) (transfer none): a #GList of #GDataMediaContent items
*
* Since: 0.4.0
*/
GList *
gdata_picasaweb_album_get_contents (GDataPicasaWebAlbum *self)
{
g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (self), NULL);
return gdata_media_group_get_contents (self->priv->media_group);
}
/**
* gdata_picasaweb_album_get_thumbnails:
* @self: a #GDataPicasaWebAlbum
*
* Returns a list of thumbnails, often at different sizes, for this album.
*
* Return value: (element-type GData.MediaThumbnail) (transfer none): a #GList of #GDataMediaThumbnail<!-- -->s, or %NULL
*
* Since: 0.4.0
*/
GList *
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: (out caller-allocates) (allow-none): return location for the latitude, or %NULL
* @longitude: (out caller-allocates) (allow-none): 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));
}