[libgdata] Bug 598752 — Support comments



commit e6fe52a83786e87559ff4878bef0fc9ca451baa0
Author: Richard Schwarting <aquarichy gmail com>
Date:   Sat Jul 9 15:07:14 2011 +0100

    Bug 598752 â Support comments
    
    This adds GDataCommentable, an interface to be implemented by GDataEntry
    subclasses which support comments being added to them; and GDataComment,
    an abstract base class for all types of comments to inherit from.
    
    This adds the following API:
     â GDataCommentable
     â GDataComment
    
    Closes: bgo#598752

 Makefile.am                       |    4 +
 docs/reference/gdata-docs.xml     |    6 +
 docs/reference/gdata-sections.txt |   40 +++
 gdata/gdata-comment.c             |   54 ++++
 gdata/gdata-comment.h             |   67 ++++
 gdata/gdata-commentable.c         |  636 +++++++++++++++++++++++++++++++++++++
 gdata/gdata-commentable.h         |  101 ++++++
 gdata/gdata.h                     |    2 +
 gdata/gdata.symbols               |   11 +
 9 files changed, 921 insertions(+), 0 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 13d6f82..ae425c8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -153,6 +153,8 @@ gdata_headers = \
 	gdata/gdata-feed.h		\
 	gdata/gdata-service.h		\
 	gdata/gdata-query.h		\
+	gdata/gdata-commentable.h	\
+	gdata/gdata-comment.h		\
 	gdata/gdata-access-handler.h	\
 	gdata/gdata-access-rule.h	\
 	gdata/gdata-parsable.h		\
@@ -290,6 +292,8 @@ gdata_sources = \
 	gdata/gdata-types.c		\
 	gdata/gdata-query.c		\
 	gdata/gdata-parser.c		\
+	gdata/gdata-commentable.c	\
+	gdata/gdata-comment.c		\
 	gdata/gdata-access-handler.c	\
 	gdata/gdata-access-rule.c	\
 	gdata/gdata-parsable.c		\
diff --git a/docs/reference/gdata-docs.xml b/docs/reference/gdata-docs.xml
index a441968..2cdcf0d 100644
--- a/docs/reference/gdata-docs.xml
+++ b/docs/reference/gdata-docs.xml
@@ -55,6 +55,12 @@
 			<xi:include href="xml/gdata-client-login-authorizer.xml"/>
 			<xi:include href="xml/gdata-oauth1-authorizer.xml"/>
 		</chapter>
+
+		<chapter>
+			<title>Comment API</title>
+			<xi:include href="xml/gdata-commentable.xml"/>
+			<xi:include href="xml/gdata-comment.xml"/>
+		</chapter>
 	</part>
 
 	<part>
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index 335b8d2..84db5bc 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -2264,3 +2264,43 @@ gdata_oauth1_authorizer_get_type
 <SUBSECTION Private>
 GDataOAuth1AuthorizerPrivate
 </SECTION>
+
+<SECTION>
+<FILE>gdata-commentable</FILE>
+<TITLE>GDataCommentable</TITLE>
+GDataCommentable
+GDataCommentableInterface
+gdata_commentable_query_comments
+gdata_commentable_query_comments_async
+gdata_commentable_query_comments_finish
+gdata_commentable_insert_comment
+gdata_commentable_insert_comment_async
+gdata_commentable_insert_comment_finish
+gdata_commentable_delete_comment
+gdata_commentable_delete_comment_async
+gdata_commentable_delete_comment_finish
+<SUBSECTION Standard>
+gdata_commentable_get_type
+GDATA_COMMENTABLE
+GDATA_COMMENTABLE_CLASS
+GDATA_COMMENTABLE_GET_IFACE
+GDATA_IS_COMMENTABLE
+GDATA_TYPE_COMMENTABLE
+</SECTION>
+
+<SECTION>
+<FILE>gdata-comment</FILE>
+<TITLE>GDataComment</TITLE>
+GDataComment
+GDataCommentClass
+<SUBSECTION Standard>
+GDATA_TYPE_COMMENT
+GDATA_COMMENT
+GDATA_COMMENT_CLASS
+GDATA_IS_COMMENT
+GDATA_IS_COMMENT_CLASS
+GDATA_COMMENT_GET_CLASS
+gdata_comment_get_type
+<SUBSECTION Private>
+GDataCommentPrivate
+</SECTION>
diff --git a/gdata/gdata-comment.c b/gdata/gdata-comment.c
new file mode 100644
index 0000000..b201c9b
--- /dev/null
+++ b/gdata/gdata-comment.c
@@ -0,0 +1,54 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2011 <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-comment
+ * @short_description: GData comment object
+ * @stability: Unstable
+ * @include: gdata/gdata-comment.h
+ *
+ * #GDataComment is a subclass of #GDataEntry to represent a generic comment on an entry. It is returned by the methods implemented in the
+ * #GDataCommentable interface.
+ *
+ * Any class which implements #GDataCommentable should have its own concrete subclass of #GDataComment which provides service-specific functionality.
+ *
+ * All subclasses of #GDataComment should ensure that the body of a comment is accessible using gdata_entry_get_content(), and that each comment has
+ * at least one #GDataAuthor object representing the person who wrote the comment, accessible using gdata_entry_get_authors().
+ *
+ * Since: 0.9.2
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include "gdata-comment.h"
+
+G_DEFINE_ABSTRACT_TYPE (GDataComment, gdata_comment, GDATA_TYPE_ENTRY)
+
+static void
+gdata_comment_class_init (GDataCommentClass *klass)
+{
+	/* Nothing to see here */
+}
+
+static void
+gdata_comment_init (GDataComment *self)
+{
+	/* Nothing to see here */
+}
diff --git a/gdata/gdata-comment.h b/gdata/gdata-comment.h
new file mode 100644
index 0000000..1cd83ee
--- /dev/null
+++ b/gdata/gdata-comment.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2011 <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/>.
+ */
+
+#ifndef GDATA_COMMENT_H
+#define GDATA_COMMENT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-entry.h>
+
+G_BEGIN_DECLS
+
+#define GDATA_TYPE_COMMENT		(gdata_comment_get_type ())
+#define GDATA_COMMENT(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_COMMENT, GDataComment))
+#define GDATA_COMMENT_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_COMMENT, GDataCommentClass))
+#define GDATA_IS_COMMENT(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_COMMENT))
+#define GDATA_IS_COMMENT_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), GDATA_TYPE_COMMENT))
+#define GDATA_COMMENT_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), GDATA_TYPE_COMMENT, GDataCommentClass))
+
+typedef struct _GDataCommentPrivate	GDataCommentPrivate;
+
+/**
+ * GDataComment:
+ *
+ * All the fields in the #GDataComment structure are private and should never be accessed directly.
+ *
+ * Since: 0.9.2
+ */
+typedef struct {
+	GDataEntry parent;
+	GDataCommentPrivate *priv;
+} GDataComment;
+
+/**
+ * GDataCommentClass:
+ *
+ * All the fields in the #GDataCommentClass structure are private and should never be accessed directly.
+ *
+ * Since: 0.9.2
+ */
+typedef struct {
+	/*< private >*/
+	GDataEntryClass parent;
+} GDataCommentClass;
+
+GType gdata_comment_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* !GDATA_COMMENT_H */
diff --git a/gdata/gdata-commentable.c b/gdata/gdata-commentable.c
new file mode 100644
index 0000000..31e515e
--- /dev/null
+++ b/gdata/gdata-commentable.c
@@ -0,0 +1,636 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2008â2010 <philip tecnocode co uk>
+ * Copyright (C) Richard Schwarting 2010 <aquarichy gmail com>
+ *
+ * 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-commentable
+ * @short_description: GData commentable interface
+ * @stability: Unstable
+ * @include: gdata/gdata-commentable.h
+ *
+ * #GDataCommentable is an interface which can be implemented by commentable objects: objects which support having comments added to them by users,
+ * such as videos and photos.
+ *
+ * Comments may be queried, added and deleted. Note that they may not be edited.
+ *
+ * #GDataCommentable objects may not support all operations on comments, on an instance-by-instance basis (i.e. it's an invalid assumption that if,
+ * for example, one #GDataYouTubeVideo doesn't support adding comments all other #GDataYouTubeVideo<!-- -->s don't support adding comments either).
+ * Specific documentation for a particular type of #GDataCommentable may state otherwise, though.
+ *
+ * <example>
+ * 	<title>Querying for Comments</title>
+ * 	<programlisting>
+ *	GDataService *service;
+ *	GDataCommentable *commentable;
+ *
+ *	/<!-- -->* Create a service *<!-- -->/
+ *	service = create_service ();
+ *
+ *	/<!-- -->* Retrieve the GDataCommentable which is going to be queried. This may be, for example, a GDataYouTubeVideo. *<!-- -->/
+ *	commentable = get_commentable ();
+ *
+ *	/<!-- -->* Start the async. query for the comments. *<!-- -->/
+ *	gdata_commentable_query_comments_async (commentable, service, NULL, NULL, NULL, NULL, NULL, (GAsyncReadyCallback) query_comments_cb, NULL);
+ *
+ *	g_object_unref (service);
+ *	g_object_unref (commentable);
+ *
+ *	static void
+ *	query_comments_cb (GDataCommentable *commentable, GAsyncResult *result, gpointer user_data)
+ *	{
+ *		GDataFeed *comment_feed;
+ *		GList *comments, *i;
+ *		GError *error = NULL;
+ *
+ *		comment_feed = gdata_commentable_query_comments_finish (commentable, result, &error);
+ *
+ *		if (error != NULL) {
+ *			/<!-- -->* Error! *<!-- -->/
+ *			g_error ("Error querying comments: %s", error->message);
+ *			g_error_free (error);
+ *			return;
+ *		}
+ *
+ *		/<!-- -->* Examine the comments. *<!-- -->/
+ *		comments = gdata_feed_get_entries (comment_feed);
+ *		for (i = comments; i != NULL; i = i->next) {
+ *			/<!-- -->* Note that this will actually be a subclass of GDataComment,
+ *			 * such as GDataYouTubeComment or GDataPicasaWebComment. *<!-- -->/
+ *			GDataComment *comment = GDATA_COMMENT (i->data);
+ *			GDataAuthor *author;
+ *
+ *			/<!-- -->* Note that in practice it might not always be safe to assume that a comment always has an author. *<!-- -->/
+ *			author = GDATA_AUTHOR (gdata_entry_get_authors (GDATA_ENTRY (comment))->data);
+ *
+ *			g_message ("Comment by %s (%s): %s",
+ *			           gdata_author_get_name (author),
+ *			           gdata_author_get_uri (author),
+ *			           gdata_entry_get_content (GDATA_ENTRY (comment)));
+ *		}
+ *
+ *		g_object_unref (comment_feed);
+ *	}
+ * 	</programlisting>
+ * </example>
+ *
+ * Since: 0.9.2
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <string.h>
+
+#include "gdata-commentable.h"
+#include "gdata-service.h"
+
+G_DEFINE_INTERFACE (GDataCommentable, gdata_commentable, GDATA_TYPE_ENTRY)
+
+static void
+gdata_commentable_default_init (GDataCommentableInterface *iface)
+{
+	iface->comment_type = G_TYPE_INVALID;
+	iface->get_authorization_domain = NULL;
+	iface->get_query_comments_uri = NULL;
+	iface->get_insert_comment_uri = NULL;
+	iface->is_comment_deletable = NULL;
+}
+
+static GType
+get_comment_type (GDataCommentableInterface *iface)
+{
+	GType comment_type;
+
+	comment_type = iface->comment_type;
+	g_assert (g_type_is_a (comment_type, GDATA_TYPE_COMMENT) == TRUE);
+
+	return comment_type;
+}
+
+/**
+ * gdata_commentable_query_comments:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService representing the service with which the object's comments will be manipulated
+ * @query: (allow-none): a #GDataQuery with query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (scope call) (closure progress_user_data): a #GDataQueryProgressCallback to call when a comment is loaded, or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @error: a #GError, or %NULL
+ *
+ * Retrieves a #GDataFeed containing the #GDataComment<!-- -->s representing the comments on the #GDataCommentable which match the given @query.
+ *
+ * If the #GDataCommentable doesn't support commenting, %NULL will be returned and @error will be set to %GDATA_SERVICE_ERROR_FORBIDDEN. This is in
+ * contrast to if it does support commenting but hasn't had any comments added yet, in which case an empty #GDataFeed will be returned and no error
+ * will be set.
+ *
+ * Return value: (transfer full) (allow-none): a #GDataFeed of #GDataComment<!-- -->s, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.9.2
+ */
+GDataFeed *
+gdata_commentable_query_comments (GDataCommentable *self, GDataService *service, GDataQuery *query,
+                                  GCancellable *cancellable, GDataQueryProgressCallback progress_callback,
+                                  gpointer progress_user_data, GError **error)
+{
+	GDataCommentableInterface *iface;
+	gchar *uri;
+	GDataFeed *feed;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), NULL);
+	g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
+	g_return_val_if_fail (query == NULL || GDATA_IS_QUERY (query), NULL);
+	g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	/* Get the comment feed URI. */
+	g_assert (iface->get_query_comments_uri != NULL);
+	uri = iface->get_query_comments_uri (self);
+
+	/* The URI can be NULL when no comments and thus no feedLink is present in a GDataCommentable */
+	if (uri == NULL) {
+		/* Translators: This is an error message for if a user attempts to retrieve comments from an entry (such as a video) which doesn't
+		 * support comments. */
+		g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN, _("This entry does not support comments."));
+		return NULL;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Get the comment feed. */
+	feed = gdata_service_query (service, domain, uri, query, get_comment_type (iface), cancellable, progress_callback, progress_user_data, error);
+	g_free (uri);
+
+	return feed;
+}
+
+static void
+query_comments_async_cb (GDataService *service, GAsyncResult *service_result, GSimpleAsyncResult *commentable_result)
+{
+	GDataFeed *feed;
+	GError *error = NULL;
+
+	feed = gdata_service_query_finish (service, service_result, &error);
+
+	if (error != NULL) {
+		/* Error. */
+		g_simple_async_result_take_error (commentable_result, error);
+	} else {
+		g_simple_async_result_set_op_res_gpointer (commentable_result, g_object_ref (feed), (GDestroyNotify) g_object_unref);
+	}
+
+	g_simple_async_result_complete (commentable_result);
+
+	g_object_unref (commentable_result);
+}
+
+/**
+ * gdata_commentable_query_comments_async:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService representing the service with which the object's comments will be manipulated
+ * @query: (allow-none): a #GDataQuery with query parameters, or %NULL
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @progress_callback: (allow-none) (scope notified) (closure progress_user_data): a #GDataQueryProgressCallback to call when a comment is loaded,
+ * or %NULL
+ * @progress_user_data: (closure): data to pass to the @progress_callback function
+ * @destroy_progress_user_data: (allow-none): a function to call when @progress_callback will not be called any more, or %NULL; this function will be
+ * called with @progress_user_data as a parameter and can be used to free any memory allocated for it
+ * @callback: a #GAsyncReadyCallback to call when the query is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Retrieves a #GDataFeed containing the #GDataComment<!-- -->s representing the comments on the #GDataCommentable which match the given @query.
+ * @self, @service and @query are all reffed when this method is called, so can safely be freed after this method returns.
+ *
+ * For more details, see gdata_commentable_query_comments(), which is the synchronous version of this method.
+ *
+ * When the operation is finished, @callback will be called. You can then call gdata_commentable_query_comments_finish() to get the results of the
+ * operation.
+ *
+ * Since: 0.9.2
+ */
+void
+gdata_commentable_query_comments_async (GDataCommentable *self, GDataService *service, GDataQuery *query, GCancellable *cancellable,
+                                        GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+                                        GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data)
+{
+	GDataCommentableInterface *iface;
+	gchar *uri;
+	GSimpleAsyncResult *result;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_if_fail (GDATA_IS_COMMENTABLE (self));
+	g_return_if_fail (GDATA_IS_SERVICE (service));
+	g_return_if_fail (query == NULL || GDATA_IS_QUERY (query));
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+	g_return_if_fail (callback != NULL);
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	/* Get the comment feed URI. */
+	g_assert (iface->get_query_comments_uri != NULL);
+	uri = iface->get_query_comments_uri (self);
+
+	/* Build the async result. */
+	result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_commentable_query_comments_async);
+
+	/* The URI can be NULL when no comments and thus no feedLink is present in a GDataCommentable */
+	if (uri == NULL) {
+		/* Translators: This is an error message for if a user attempts to retrieve comments from an entry (such as a video) which doesn't
+		 * support comments. */
+		g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN,
+		                                 _("This entry does not support comments."));
+		g_simple_async_result_complete_in_idle (result);
+		g_object_unref (result);
+		return;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Get the comment feed. */
+	gdata_service_query_async (service, domain, uri, query, get_comment_type (iface), cancellable, progress_callback, progress_user_data,
+	                           destroy_progress_user_data, (GAsyncReadyCallback) query_comments_async_cb, result);
+	g_free (uri);
+}
+
+/**
+ * gdata_commentable_query_comments_finish:
+ * @self: a #GDataCommentable
+ * @result: a #GAsyncResult
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous comment query operation started with gdata_commentable_query_comments_async().
+ *
+ * Return value: (transfer full) (allow-none): a #GDataFeed of #GDataComment<!-- -->s, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.9.2
+ */
+GDataFeed *
+gdata_commentable_query_comments_finish (GDataCommentable *self, GAsyncResult *result, GError **error)
+{
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), NULL);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), gdata_commentable_query_comments_async) == TRUE, NULL);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error) == TRUE) {
+		/* Error. */
+		return NULL;
+	}
+
+	return GDATA_FEED (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+/**
+ * gdata_commentable_insert_comment:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService with which the comment will be added
+ * @comment_: a new comment to be added to the #GDataCommentable
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Adds @comment to the #GDataCommentable.
+ *
+ * If the #GDataCommentable doesn't support commenting, %NULL will be returned and @error will be set to %GDATA_SERVICE_ERROR_FORBIDDEN.
+ *
+ * Return value: (transfer full) (allow-none): the added #GDataComment, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.9.2
+ */
+GDataComment *
+gdata_commentable_insert_comment (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable, GError **error)
+{
+	GDataCommentableInterface *iface;
+	gchar *uri;
+	GDataComment *new_comment;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), NULL);
+	g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
+	g_return_val_if_fail (GDATA_IS_COMMENT (comment_), NULL);
+	g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (comment_), get_comment_type (iface)) == TRUE, NULL);
+
+	/* Get the upload URI. */
+	g_assert (iface->get_insert_comment_uri != NULL);
+	uri = iface->get_insert_comment_uri (self, comment_);
+
+	if (uri == NULL) {
+		/* Translators: This is an error message for if a user attempts to add a comment to an entry (such as a video) which doesn't support
+		 * comments. */
+		g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN, _("Comments may not be added to this entry."));
+		return NULL;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Add the comment. */
+	new_comment = GDATA_COMMENT (gdata_service_insert_entry (service, domain, uri, GDATA_ENTRY (comment_), cancellable, error));
+
+	g_free (uri);
+
+	return new_comment;
+}
+
+static void
+insert_comment_async_cb (GDataService *service, GAsyncResult *service_result, GSimpleAsyncResult *commentable_result)
+{
+	GDataEntry *new_comment;
+	GError *error = NULL;
+
+	new_comment = gdata_service_insert_entry_finish (service, service_result, &error);
+
+	if (error != NULL) {
+		/* Error. */
+		g_simple_async_result_take_error (commentable_result, error);
+	} else {
+		g_simple_async_result_set_op_res_gpointer (commentable_result, g_object_ref (new_comment), (GDestroyNotify) g_object_unref);
+	}
+
+	g_simple_async_result_complete (commentable_result);
+
+	g_object_unref (commentable_result);
+}
+
+/**
+ * gdata_commentable_insert_comment_async:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService with which the comment will be added
+ * @comment_: a new comment to be added to the #GDataCommentable
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Adds @comment to the #GDataCommentable. @self, @service and @comment_ are all reffed when this method is called, so can safely be freed after this
+ * method returns.
+ *
+ * For more details, see gdata_commentable_insert_comment(), which is the synchronous version of this method.
+ *
+ * When the operation is finished, @callback will be called. You can then call gdata_commentable_insert_comment_finish() to get the results of the
+ * operation.
+ *
+ * Since: 0.9.2
+ */
+void
+gdata_commentable_insert_comment_async (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                        GAsyncReadyCallback callback, gpointer user_data)
+{
+	GDataCommentableInterface *iface;
+	gchar *uri;
+	GSimpleAsyncResult *result;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_if_fail (GDATA_IS_COMMENTABLE (self));
+	g_return_if_fail (GDATA_IS_SERVICE (service));
+	g_return_if_fail (GDATA_IS_COMMENT (comment_));
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (comment_), get_comment_type (iface)) == TRUE);
+
+	/* Get the upload URI. */
+	g_assert (iface->get_insert_comment_uri != NULL);
+	uri = iface->get_insert_comment_uri (self, comment_);
+
+	/* Build the async result. */
+	result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_commentable_insert_comment_async);
+
+	/* The URI can be NULL when no comments and thus no feedLink is present in a GDataCommentable */
+	if (uri == NULL) {
+		/* Translators: This is an error message for if a user attempts to add a comment to an entry (such as a video) which doesn't support
+		 * comments. */
+		g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN,
+		                                 _("Comments may not be added to this entry."));
+		g_simple_async_result_complete_in_idle (result);
+		g_object_unref (result);
+		return;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Add the comment. */
+	gdata_service_insert_entry_async (service, domain, uri, GDATA_ENTRY (comment_), cancellable, (GAsyncReadyCallback) insert_comment_async_cb,
+	                                  result);
+
+	g_free (uri);
+}
+
+/**
+ * gdata_commentable_insert_comment_finish:
+ * @self: a #GDataCommentable
+ * @result: a #GAsyncResult
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous comment insertion operation started with gdata_commentable_insert_comment_async().
+ *
+ * Return value: (transfer full) (allow-none): the added #GDataComment, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.9.2
+ */
+GDataComment *
+gdata_commentable_insert_comment_finish (GDataCommentable *self, GAsyncResult *result, GError **error)
+{
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), NULL);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), gdata_commentable_insert_comment_async) == TRUE, NULL);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error) == TRUE) {
+		/* Error. */
+		return NULL;
+	}
+
+	return GDATA_COMMENT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
+}
+
+/**
+ * gdata_commentable_delete_comment:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService with which the comment will be deleted
+ * @comment_: a comment to be deleted
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Deletes @comment from the #GDataCommentable.
+ *
+ * If the given @comment isn't deletable (either because the service doesn't support deleting comments at all, or because this particular comment
+ * is not deletable due to having insufficient permissions), %GDATA_SERVICE_ERROR_FORBIDDEN will be set in @error and %FALSE will be returned.
+ *
+ * Return value: %TRUE if the comment was successfully deleted, %FALSE otherwise
+ *
+ * Since: 0.9.2
+ */
+gboolean
+gdata_commentable_delete_comment (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable, GError **error)
+{
+	GDataCommentableInterface *iface;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), FALSE);
+	g_return_val_if_fail (GDATA_IS_SERVICE (service), FALSE);
+	g_return_val_if_fail (GDATA_IS_COMMENT (comment_), FALSE);
+	g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	g_return_val_if_fail (g_type_is_a (G_OBJECT_TYPE (comment_), get_comment_type (iface)) == TRUE, FALSE);
+
+	g_assert (iface->is_comment_deletable != NULL);
+	if (iface->is_comment_deletable (self, comment_) == FALSE) {
+		/* Translators: This is an error message for if a user attempts to delete a comment they're not allowed to delete. */
+		g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN, _("This comment may not be deleted."));
+		return FALSE;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Delete the comment. */
+	return gdata_service_delete_entry (service, domain, GDATA_ENTRY (comment_), cancellable, error);
+}
+
+static void
+delete_comment_async_cb (GDataService *service, GAsyncResult *service_result, GSimpleAsyncResult *commentable_result)
+{
+	gboolean success;
+	GError *error = NULL;
+
+	success = gdata_service_delete_entry_finish (service, service_result, &error);
+
+	if (error != NULL) {
+		/* Error. */
+		g_simple_async_result_take_error (commentable_result, error);
+	} else {
+		g_simple_async_result_set_op_res_gboolean (commentable_result, success);
+	}
+
+	g_simple_async_result_complete (commentable_result);
+
+	g_object_unref (commentable_result);
+}
+
+/**
+ * gdata_commentable_delete_comment_async:
+ * @self: a #GDataCommentable
+ * @service: a #GDataService with which the comment will be deleted
+ * @comment_: a comment to be deleted
+ * @cancellable: (allow-none): optional #GCancellable object, or %NULL
+ * @callback: a #GAsyncReadyCallback to call when the operation is finished
+ * @user_data: (closure): data to pass to the @callback function
+ *
+ * Deletes @comment from the #GDataCommentable. @self, @service and @comment_ are all reffed when this method is called, so can safely be freed after
+ * this method returns.
+ *
+ * For more details, see gdata_commentable_delete_comment(), which is the synchronous version of this method.
+ *
+ * When the operation is finished, @callback will be called. You can then call gdata_commentable_delete_comment_finish() to get the results of the
+ * operation.
+ *
+ * Since: 0.9.2
+ */
+void
+gdata_commentable_delete_comment_async (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                        GAsyncReadyCallback callback, gpointer user_data)
+{
+	GDataCommentableInterface *iface;
+	GSimpleAsyncResult *result;
+	GDataAuthorizationDomain *domain = NULL;
+
+	g_return_if_fail (GDATA_IS_COMMENTABLE (self));
+	g_return_if_fail (GDATA_IS_SERVICE (service));
+	g_return_if_fail (GDATA_IS_COMMENT (comment_));
+	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
+
+	iface = GDATA_COMMENTABLE_GET_IFACE (self);
+
+	g_return_if_fail (g_type_is_a (G_OBJECT_TYPE (comment_), get_comment_type (iface)) == TRUE);
+
+	/* Build the async result. */
+	result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_commentable_delete_comment_async);
+
+	g_assert (iface->is_comment_deletable != NULL);
+	if (iface->is_comment_deletable (self, comment_) == FALSE) {
+		/* Translators: This is an error message for if a user attempts to delete a comment they're not allowed to delete. */
+		g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN,
+		                                 _("This comment may not be deleted."));
+		g_simple_async_result_complete_in_idle (result);
+		g_object_unref (result);
+		return;
+	}
+
+	/* Get the authorisation domain. */
+	if (iface->get_authorization_domain != NULL) {
+		domain = iface->get_authorization_domain (self);
+	}
+
+	/* Delete the comment. */
+	gdata_service_delete_entry_async (service, domain, GDATA_ENTRY (comment_), cancellable, (GAsyncReadyCallback) delete_comment_async_cb, result);
+}
+
+/**
+ * gdata_commentable_delete_comment_finish:
+ * @self: a #GDataCommentable
+ * @result: a #GAsyncResult
+ * @error: a #GError, or %NULL
+ *
+ * Finishes an asynchronous comment deletion operation started with gdata_commentable_delete_comment_async().
+ *
+ * Return value: %TRUE if the comment was successfully deleted, %FALSE otherwise
+ *
+ * Since: 0.9.2
+ */
+gboolean
+gdata_commentable_delete_comment_finish (GDataCommentable *self, GAsyncResult *result, GError **error)
+{
+	g_return_val_if_fail (GDATA_IS_COMMENTABLE (self), FALSE);
+	g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+	g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), gdata_commentable_delete_comment_async) == TRUE, FALSE);
+
+	if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error) == TRUE) {
+		/* Error. */
+		return FALSE;
+	}
+
+	return g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (result));
+}
diff --git a/gdata/gdata-commentable.h b/gdata/gdata-commentable.h
new file mode 100644
index 0000000..70b3776
--- /dev/null
+++ b/gdata/gdata-commentable.h
@@ -0,0 +1,101 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * GData Client
+ * Copyright (C) Philip Withnall 2009 <philip tecnocode co uk>
+ * Copyright (C) Richard Schwarting 2010 <aquarichy gmail com>
+ *
+ * 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/>.
+ */
+
+#ifndef GDATA_COMMENTABLE_H
+#define GDATA_COMMENTABLE_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdata/gdata-feed.h>
+#include <gdata/gdata-service.h>
+#include <gdata/gdata-comment.h>
+
+#define GDATA_TYPE_COMMENTABLE			(gdata_commentable_get_type ())
+#define GDATA_COMMENTABLE(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), GDATA_TYPE_COMMENTABLE, GDataCommentable))
+#define GDATA_COMMENTABLE_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST((k), GDATA_TYPE_COMMENTABLE, GDataCommentableInterface))
+#define GDATA_IS_COMMENTABLE(o)			(G_TYPE_CHECK_INSTANCE_TYPE ((o), GDATA_TYPE_COMMENTABLE))
+#define GDATA_COMMENTABLE_GET_IFACE(o)		(G_TYPE_INSTANCE_GET_INTERFACE ((o), GDATA_TYPE_COMMENTABLE, GDataCommentableInterface))
+
+/**
+ * GDataCommentable:
+ *
+ * All the fields in the #GDataCommentable structure are private and should never be accessed directly
+ *
+ * Since: 0.9.2
+ */
+typedef struct _GDataCommentable		GDataCommentable; /* dummy typedef */
+
+/**
+ * GDataCommentableInterface:
+ * @parent: the parent type
+ * @comment_type: the #GType of the comment class (subclass of #GDataComment) to use for query results from this commentable object
+ * @get_authorization_domain: (allow-none): a function to return the #GDataAuthorizationDomain to be used for all operations on the comments
+ * belonging to this commentable object; not implementing this function is equivalent to returning %NULL from it, which signifies that operations on the
+ * comments don't require authorization
+ * @get_query_comments_uri: a function that returns the URI of a #GDataFeed of comments from a commentable object, or %NULL if the given commentable
+ * object doesn't support commenting; free with g_free()
+ * @get_insert_comment_uri: a function that returns the URI to add new comments to the commentable object, or %NULL if the given commentable object
+ * doesn't support adding comments; free with g_free()
+ * @is_comment_deletable: a function that returns %TRUE if the given comment may be deleted, %FALSE otherwise
+ *
+ * The interface structure for the #GDataCommentable interface.
+ *
+ * Since: 0.9.2
+ */
+typedef struct {
+	GTypeInterface parent;
+
+	GType comment_type;
+
+	GDataAuthorizationDomain *(*get_authorization_domain) (GDataCommentable *self);
+
+	gchar *(*get_query_comments_uri) (GDataCommentable *self);
+	gchar *(*get_insert_comment_uri) (GDataCommentable *self, GDataComment *comment);
+	gboolean (*is_comment_deletable) (GDataCommentable *self, GDataComment *comment);
+} GDataCommentableInterface;
+
+GType gdata_commentable_get_type (void) G_GNUC_CONST;
+
+GDataFeed *gdata_commentable_query_comments (GDataCommentable *self, GDataService *service, GDataQuery *query, GCancellable *cancellable,
+                                             GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+                                             GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+void gdata_commentable_query_comments_async (GDataCommentable *self, GDataService *service, GDataQuery *query, GCancellable *cancellable,
+                                             GDataQueryProgressCallback progress_callback, gpointer progress_user_data,
+                                             GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data);
+GDataFeed *gdata_commentable_query_comments_finish (GDataCommentable *self, GAsyncResult *result,
+                                                    GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+GDataComment *gdata_commentable_insert_comment (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                                GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+void gdata_commentable_insert_comment_async (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                             GAsyncReadyCallback callback, gpointer user_data);
+GDataComment *gdata_commentable_insert_comment_finish (GDataCommentable *self, GAsyncResult *result,
+                                                       GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+
+gboolean gdata_commentable_delete_comment (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                           GError **error);
+void gdata_commentable_delete_comment_async (GDataCommentable *self, GDataService *service, GDataComment *comment_, GCancellable *cancellable,
+                                             GAsyncReadyCallback callback, gpointer user_data);
+gboolean gdata_commentable_delete_comment_finish (GDataCommentable *self, GAsyncResult *result, GError **error);
+
+G_END_DECLS
+
+#endif /* !GDATA_COMMENTABLE_H */
diff --git a/gdata/gdata.h b/gdata/gdata.h
index 86c0024..4139d20 100644
--- a/gdata/gdata.h
+++ b/gdata/gdata.h
@@ -39,6 +39,8 @@
 #include <gdata/gdata-authorization-domain.h>
 #include <gdata/gdata-client-login-authorizer.h>
 #include <gdata/gdata-oauth1-authorizer.h>
+#include <gdata/gdata-commentable.h>
+#include <gdata/gdata-comment.h>
 
 /* Namespaces */
 
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index 1eda93e..cf4ac9c 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -911,3 +911,14 @@ gdata_calendar_query_show_deleted
 gdata_calendar_query_set_show_deleted
 gdata_picasaweb_service_get_user_async
 gdata_picasaweb_service_get_user_finish
+gdata_commentable_get_type
+gdata_commentable_query_comments
+gdata_commentable_query_comments_async
+gdata_commentable_query_comments_finish
+gdata_commentable_insert_comment
+gdata_commentable_insert_comment_async
+gdata_commentable_insert_comment_finish
+gdata_commentable_delete_comment
+gdata_commentable_delete_comment_async
+gdata_commentable_delete_comment_finish
+gdata_comment_get_type



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