[libgdata] Bug 598649 — Download API for PicasaWeb images and thumbnails
- From: Richard Hans Schwarting <rschwart src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [libgdata] Bug 598649 — Download API for PicasaWeb images and thumbnails
- Date: Sun, 6 Dec 2009 04:50:53 +0000 (UTC)
commit efc38812b658cf56f4141aa59dd1639b1430adde
Author: Richard Schwarting <rschwart src gnome org>
Date: Sun Dec 6 17:46:07 2009 +1300
Bug 598649 â?? Download API for PicasaWeb images and thumbnails
Add download APIs and infrastructure for GDataMedia and GDataThumbnail
configure.ac | 10 ++
docs/reference/gdata-sections.txt | 2 +
gdata/gdata-download-stream.c | 69 ++++++++
gdata/gdata-private.h | 2 +
gdata/gdata.symbols | 2 +
gdata/media/gdata-media-content.c | 60 +++++++
gdata/media/gdata-media-content.h | 2 +
gdata/media/gdata-media-thumbnail.c | 59 +++++++
gdata/media/gdata-media-thumbnail.h | 2 +
gdata/tests/Makefile.am | 2 +
gdata/tests/picasaweb.c | 296 ++++++++++++++++++++++++++++++++++-
11 files changed, 505 insertions(+), 1 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 30a0aa8..fca8fc2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,6 +59,16 @@ PKG_CHECK_MODULES(GDATA, [$pkg_modules])
AC_SUBST(GDATA_CFLAGS)
AC_SUBST(GDATA_LIBS)
+# Optional dependencies
+
+PKG_CHECK_MODULES(GDK, gdk-2.0, have_gdk=yes, have_gdk=no)
+if test "x$have_gdk" = "xyes"; then
+ AC_DEFINE(HAVE_GDK, 1, [Defined if GDK+ is installed])
+fi
+
+AC_SUBST(GDK_CFLAGS) # TODO: test how this fairs without gdk-2.0.pc avail
+AC_SUBST(GDK_LIBS)
+
# GNOME support, which pulls in libsoup-gnome-2.4 to provide transparent proxy support
AC_MSG_CHECKING(whether to build with GNOME support)
AC_ARG_ENABLE(gnome, AS_HELP_STRING([--enable-gnome], [Whether to enable GNOME support]),, enable_gnome=yes)
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index fc95a95..282babe 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -1103,6 +1103,7 @@ gdata_media_content_get_expression
gdata_media_content_get_duration
gdata_media_content_get_height
gdata_media_content_get_width
+gdata_media_content_download
<SUBSECTION Standard>
gdata_media_content_get_type
GDATA_MEDIA_CONTENT
@@ -1142,6 +1143,7 @@ gdata_media_thumbnail_get_uri
gdata_media_thumbnail_get_height
gdata_media_thumbnail_get_width
gdata_media_thumbnail_get_time
+gdata_media_thumbnail_download
<SUBSECTION Standard>
gdata_media_thumbnail_get_type
GDATA_MEDIA_THUMBNAIL
diff --git a/gdata/gdata-download-stream.c b/gdata/gdata-download-stream.c
index 4891f2c..ee0137f 100644
--- a/gdata/gdata-download-stream.c
+++ b/gdata/gdata-download-stream.c
@@ -560,3 +560,72 @@ gdata_download_stream_get_content_length (GDataDownloadStream *self)
g_return_val_if_fail (GDATA_IS_DOWNLOAD_STREAM (self), -1);
return self->priv->content_length;
}
+
+/**
+ * _gdata_download_stream_find_destination:
+ * @default_filename: a default filename used if the user selects a directory as the destination
+ * @target_dest_file: the destination file or directory to download to
+ * @actual_dest_file: will be set to reference the actual destination, which might be different from @target_dest_file
+ * @replace_file_if_exists: whether to replace pre-existing files at the download location
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Sets up a download stream for a given destination.
+ *
+ * If @target_dest_file is a directory, then the file will be
+ * downloaded into the directory with the filename specified by
+ * @default_filename. Otherwise, the file will be downloaded as the
+ * file specified by @target_dest_file.
+ *
+ * @actual_dest_file usually only differs from @target_dest_file when
+ * the latter is set to a directory, and @default_filename must be
+ * used. The @actual_dest_file argument should be a pointer to a %NULL
+ * #GFile. Regardless, unref the #GFile returned in @actual_dest_file
+ * with g_object_unref(), as it increases the ref count of
+ * @target_dest_file even when they are the same.
+ *
+ * Return value: a #GFileOutputStream, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.6.0
+ **/
+GFileOutputStream *
+_gdata_download_stream_find_destination (const gchar *default_filename, GFile *target_dest_file, GFile **actual_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error)
+{
+ GFileInfo *target_dest_info;
+ GFileOutputStream *dest_stream;
+
+ g_return_val_if_fail (default_filename != NULL, NULL);
+ g_return_val_if_fail (G_IS_FILE (target_dest_file), NULL);
+ g_return_val_if_fail (actual_dest_file != NULL && *actual_dest_file == NULL, NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ /* handle the case where it exists as a directory, so we want to insert it in there */
+ if (g_file_query_exists (target_dest_file, cancellable)) {
+ target_dest_info = g_file_query_info (target_dest_file, "standard::type", G_FILE_QUERY_INFO_NONE, cancellable, error);
+ if (target_dest_info == NULL)
+ return NULL;
+
+ if (g_file_info_get_file_type (target_dest_info) == G_FILE_TYPE_DIRECTORY)
+ *actual_dest_file = g_file_get_child (target_dest_file, default_filename);
+
+ g_object_unref (target_dest_info);
+ }
+
+ /* handle the general case (where it doesn't exist or it does but isn't a directory) */
+ if (*actual_dest_file == NULL)
+ *actual_dest_file = g_object_ref (target_dest_file);
+
+ /* replace or create, leaving it up to the APIs to get the relevant error message */
+ if (replace_file_if_exists)
+ dest_stream = g_file_replace (*actual_dest_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, cancellable, error);
+ else
+ dest_stream = g_file_create (*actual_dest_file, G_FILE_CREATE_NONE, cancellable, error);
+
+ if (dest_stream == NULL) {
+ g_object_unref (*actual_dest_file);
+ return NULL;
+ }
+
+ return dest_stream;
+}
diff --git a/gdata/gdata-private.h b/gdata/gdata-private.h
index c8d007e..4114469 100644
--- a/gdata/gdata-private.h
+++ b/gdata/gdata-private.h
@@ -69,6 +69,8 @@ GDataService *_gdata_documents_service_get_spreadsheet_service (GDataDocumentsSe
#include "gdata-parser.h"
+GFileOutputStream *_gdata_download_stream_find_destination (const gchar *default_filename, GFile *target_dest_file, GFile **actual_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error) G_GNUC_WARN_UNUSED_RESULT;
+
G_END_DECLS
#endif /* !GDATA_PRIVATE_H */
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index b41f44f..8902029 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -514,6 +514,7 @@ gdata_media_content_get_expression
gdata_media_content_get_duration
gdata_media_content_get_height
gdata_media_content_get_width
+gdata_media_content_download
gdata_youtube_content_get_type
gdata_youtube_content_get_format
gdata_media_thumbnail_get_type
@@ -521,6 +522,7 @@ gdata_media_thumbnail_get_uri
gdata_media_thumbnail_get_height
gdata_media_thumbnail_get_width
gdata_media_thumbnail_get_time
+gdata_media_thumbnail_download
gdata_youtube_state_get_type
gdata_youtube_state_get_name
gdata_youtube_state_get_reason_code
diff --git a/gdata/media/gdata-media-content.c b/gdata/media/gdata-media-content.c
index f5fc09c..f307137 100644
--- a/gdata/media/gdata-media-content.c
+++ b/gdata/media/gdata-media-content.c
@@ -33,9 +33,11 @@
#include <libxml/parser.h>
#include "gdata-media-content.h"
+#include "gdata-download-stream.h"
#include "gdata-parsable.h"
#include "gdata-parser.h"
#include "gdata-media-enums.h"
+#include "gdata-private.h"
static void gdata_media_content_finalize (GObject *object);
static void gdata_media_content_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
@@ -544,3 +546,61 @@ gdata_media_content_get_width (GDataMediaContent *self)
g_return_val_if_fail (GDATA_IS_MEDIA_CONTENT (self), 0);
return self->priv->width;
}
+
+/**
+ * gdata_media_content_download:
+ * @self: a #GDataMediaContent
+ * @service: the #GDataService
+ * @default_filename: an optional default filename used if the user selects a directory as the destination
+ * @target_dest_file: the destination file or directory to download to
+ * @replace_file_if_exists: whether to replace already existing files at the download location
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Downloads and returns a #GFile of the content represented by @self.
+ *
+ * If @target_dest_file is a directory, then the file will be
+ * downloaded into this directory with the default filename specified
+ * in @default_filename.
+ *
+ * Return value: the content's data, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.6.0
+ **/
+GFile *
+gdata_media_content_download (GDataMediaContent *self, GDataService *service, const gchar *default_filename, GFile *target_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error)
+{
+ GFileOutputStream *dest_stream;
+ const gchar *src_uri;
+ GInputStream *src_stream;
+ GFile *actual_file = NULL;
+ GError *child_error = NULL;
+
+ g_return_val_if_fail (GDATA_IS_MEDIA_CONTENT (self), NULL);
+ g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
+ g_return_val_if_fail (default_filename != NULL, NULL);
+ g_return_val_if_fail (G_IS_FILE (target_dest_file), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ dest_stream = _gdata_download_stream_find_destination (default_filename, target_dest_file, &actual_file, replace_file_if_exists, cancellable, error);
+ if (dest_stream == NULL)
+ return NULL;
+
+ src_uri = gdata_media_content_get_uri (self);
+
+ /* Synchronously splice the data from the download stream to the file stream (network -> disk) */
+ src_stream = gdata_download_stream_new (GDATA_SERVICE (service), src_uri);
+ g_output_stream_splice (G_OUTPUT_STREAM (dest_stream), src_stream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, &child_error);
+ g_object_unref (src_stream);
+ g_object_unref (dest_stream);
+ if (child_error != NULL) {
+ g_object_unref (actual_file);
+ g_propagate_error (error, child_error);
+ return NULL;
+ }
+
+ return actual_file;
+}
+
diff --git a/gdata/media/gdata-media-content.h b/gdata/media/gdata-media-content.h
index 2980054..fff4ade 100644
--- a/gdata/media/gdata-media-content.h
+++ b/gdata/media/gdata-media-content.h
@@ -24,6 +24,7 @@
#include <glib-object.h>
#include <gdata/gdata-parsable.h>
+#include <gdata/gdata-service.h>
G_BEGIN_DECLS
@@ -103,6 +104,7 @@ GDataMediaExpression gdata_media_content_get_expression (GDataMediaContent *self
gint64 gdata_media_content_get_duration (GDataMediaContent *self);
guint gdata_media_content_get_height (GDataMediaContent *self);
guint gdata_media_content_get_width (GDataMediaContent *self);
+GFile *gdata_media_content_download (GDataMediaContent *self, GDataService *service, const gchar *default_filename, GFile *target_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
diff --git a/gdata/media/gdata-media-thumbnail.c b/gdata/media/gdata-media-thumbnail.c
index e1fd657..f0a5dc7 100644
--- a/gdata/media/gdata-media-thumbnail.c
+++ b/gdata/media/gdata-media-thumbnail.c
@@ -34,8 +34,10 @@
#include <string.h>
#include "gdata-media-thumbnail.h"
+#include "gdata-download-stream.h"
#include "gdata-parsable.h"
#include "gdata-parser.h"
+#include "gdata-private.h"
static void gdata_media_thumbnail_finalize (GObject *object);
static void gdata_media_thumbnail_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
@@ -360,3 +362,60 @@ gdata_media_thumbnail_get_time (GDataMediaThumbnail *self)
g_return_val_if_fail (GDATA_IS_MEDIA_THUMBNAIL (self), -1);
return self->priv->time;
}
+
+/**
+ * gdata_media_thumbnail_download:
+ * @self: a #GDataMediaThumbnail
+ * @service: the #GDataService
+ * @default_filename: an optional default filename used if the user selects a directory as the destination
+ * @target_dest_file: the destination file or directory to download to
+ * @replace_file_if_exists: whether to replace already existing files at the download location
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Downloads and returns the thumbnail represented by @self.
+ *
+ * If @target_dest_file is a directory, then the file will be
+ * downloaded into this directory with the default filename specified
+ * in @default_filename.
+ *
+ * Return value: the thumbnail's data, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.6.0
+ **/
+GFile *
+gdata_media_thumbnail_download (GDataMediaThumbnail *self, GDataService *service, const gchar *default_filename, GFile *target_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error)
+{
+ GFileOutputStream *dest_stream;
+ const gchar *src_uri;
+ GInputStream *src_stream;
+ GFile *actual_file = NULL;
+ GError *child_error = NULL;
+
+ g_return_val_if_fail (GDATA_IS_MEDIA_THUMBNAIL (self), NULL);
+ g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
+ g_return_val_if_fail (default_filename != NULL, NULL);
+ g_return_val_if_fail (G_IS_FILE (target_dest_file), NULL);
+ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ dest_stream = _gdata_download_stream_find_destination (default_filename, target_dest_file, &actual_file, replace_file_if_exists, cancellable, error);
+ if (dest_stream == NULL)
+ return NULL;
+
+ src_uri = gdata_media_thumbnail_get_uri (self);
+
+ /* Synchronously splice the data from the download stream to the file stream (network -> disk) */
+ src_stream = gdata_download_stream_new (GDATA_SERVICE (service), src_uri);
+ g_output_stream_splice (G_OUTPUT_STREAM (dest_stream), src_stream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, cancellable, &child_error);
+ g_object_unref (src_stream);
+ g_object_unref (dest_stream);
+ if (child_error != NULL) {
+ g_object_unref (actual_file);
+ g_propagate_error (error, child_error);
+ return NULL;
+ }
+
+ return actual_file;
+}
diff --git a/gdata/media/gdata-media-thumbnail.h b/gdata/media/gdata-media-thumbnail.h
index 90d1074..92f55cf 100644
--- a/gdata/media/gdata-media-thumbnail.h
+++ b/gdata/media/gdata-media-thumbnail.h
@@ -22,6 +22,7 @@
#include <glib.h>
#include <glib-object.h>
+#include <gdata/gdata-service.h>
#include <gdata/gdata-parsable.h>
@@ -64,6 +65,7 @@ const gchar *gdata_media_thumbnail_get_uri (GDataMediaThumbnail *self);
guint gdata_media_thumbnail_get_height (GDataMediaThumbnail *self);
guint gdata_media_thumbnail_get_width (GDataMediaThumbnail *self);
gint64 gdata_media_thumbnail_get_time (GDataMediaThumbnail *self);
+GFile *gdata_media_thumbnail_download (GDataMediaThumbnail *self, GDataService *service, const gchar *default_filename, GFile *target_dest_file, gboolean replace_file_if_exists, GCancellable *cancellable, GError **error) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
diff --git a/gdata/tests/Makefile.am b/gdata/tests/Makefile.am
index 248e7f3..9cce5ab 100644
--- a/gdata/tests/Makefile.am
+++ b/gdata/tests/Makefile.am
@@ -3,6 +3,7 @@ include $(top_srcdir)/Makefile.decl
INCLUDES = \
-I$(top_srcdir)/ \
-I$(top_srcdir)/gdata \
+ $(GDK_CFLAGS) \
-DTEST_FILE_DIR="\"$(top_srcdir)/gdata/tests/\""\
$(DISABLE_DEPRECATED) \
$(WARN_CFLAGS) \
@@ -10,6 +11,7 @@ INCLUDES = \
LIBS = \
$(top_builddir)/gdata/libgdata.la \
+ $(GDK_LIBS) \
$(GDATA_LIBS)
noinst_PROGRAMS = $(TEST_PROGS)
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index 018dafa..f5057ea 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -21,6 +21,12 @@
#include <glib.h>
#include <unistd.h>
#include <string.h>
+#include <config.h>
+
+/* For the thumbnail size tests in test_download_thumbnails() */
+#ifdef HAVE_GDK
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#endif
#include "gdata.h"
#include "common.h"
@@ -99,6 +105,292 @@ test_authentication_async (void)
}
static void
+test_download_thumbnails (GDataService *service)
+{
+ GDataFeed *album_feed, *photo_feed;
+ GList *album_entries, *photo_entries, *thumbnails, *node;
+ GDataPicasaWebAlbum *album;
+ GDataPicasaWebFile *photo;
+ GDataPicasaWebQuery *query;
+ GFile *dest_dir, *dest_file, *actual_file;
+ GDataMediaThumbnail *thumbnail;
+ GdkPixbuf *pixbuf;
+ gchar *file_path, *basename;
+ GError *error = NULL;
+
+ /* Acquire album, photo to test */
+ album_feed = gdata_picasaweb_service_query_all_albums (GDATA_PICASAWEB_SERVICE (service), NULL, NULL, NULL, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_FEED (album_feed));
+
+ album_entries = gdata_feed_get_entries (album_feed);
+ g_assert (album_entries != NULL);
+
+ album = GDATA_PICASAWEB_ALBUM (album_entries->data);
+
+ query = gdata_picasaweb_query_new (NULL);
+ gdata_picasaweb_query_set_image_size (query, "32"); /* we're querying for the smallest size, to save bandwidth here :D */
+ photo_feed = gdata_picasaweb_service_query_files (GDATA_PICASAWEB_SERVICE (service), album, GDATA_QUERY (query), NULL, NULL, NULL, &error);
+ g_object_unref (query);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_FEED (photo_feed));
+
+ photo_entries = gdata_feed_get_entries (photo_feed);
+ g_assert (photo_entries != NULL);
+
+ photo = GDATA_PICASAWEB_FILE (photo_entries->data);
+
+ dest_dir = g_file_new_for_path ("/tmp/gdata.picasaweb.test.dir/");
+ dest_file = g_file_new_for_path ("/tmp/gdata.picasaweb.test.dir/test.jpg");
+
+ /* clean up any pre-existing test output */
+ if (g_file_query_exists (dest_dir, NULL)) {
+ g_file_trash (dest_dir, NULL, &error); /* TODO does this remove it even with files in it? hope so */
+ g_assert_no_error (error);
+ }
+
+ thumbnails = gdata_picasaweb_file_get_thumbnails (photo);
+ thumbnail = GDATA_MEDIA_THUMBNAIL (thumbnails->data);
+
+ /* to a directory, non-existent, should succeed, file with "directory"'s name */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "gdata.picasaweb.test.dir");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a "directory", which doesn't actually exist (as a directory), should fail */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* create the directory so we can test on it and in it */
+ g_file_trash (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+ g_file_make_directory (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+
+ /* to a directory, existent, should succeed, making use of the default filename provided */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (actual_file != NULL);
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "thumbnail.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a directory, existent, with inferred file destination already existent, without replace, should fail */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* to a directory, existent, with inferred file destination already existent, with replace, should succeed */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_dir, TRUE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "thumbnail.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a path, non-existent, should succeed */
+ g_assert (g_file_query_exists (dest_file, NULL) == FALSE);
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "test.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a path, existent, without replace, should fail */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* to a path, existent, with replace, should succeed */
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_file, TRUE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "test.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* clean up test file and thumbnail*/
+ g_file_trash (dest_file, NULL, &error);
+ g_assert_no_error (error);
+
+ /* test getting all thumbnails and that they're all the correct size */
+ for (node = thumbnails; node != NULL; node = node->next) {
+ thumbnail = GDATA_MEDIA_THUMBNAIL (node->data);
+ actual_file = gdata_media_thumbnail_download (thumbnail, service, "thumbnail.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+
+#ifdef HAVE_GDK
+ file_path = g_file_get_path (actual_file);
+ pixbuf = gdk_pixbuf_new_from_file (file_path, &error);
+ g_assert_no_error (error);
+ g_free (file_path);
+
+ /* PicasaWeb reported the height of a thumbnail as a pixel too large once, but otherwise correct */
+ g_assert_cmpint (abs (gdk_pixbuf_get_width (pixbuf) - (gint)gdata_media_thumbnail_get_width (thumbnail)) , <=, 1);
+ g_assert_cmpint (abs (gdk_pixbuf_get_height (pixbuf) - (gint)gdata_media_thumbnail_get_height (thumbnail)) , <=, 1);
+ g_object_unref (pixbuf);
+#endif /* HAVE_GDK */
+
+ g_file_trash (actual_file, NULL, &error);
+ g_assert (g_file_query_exists (actual_file, NULL) == FALSE);
+ g_assert_no_error (error);
+ g_object_unref (actual_file);
+ }
+
+ /* clean up test directory again */
+ g_file_trash (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+
+ g_object_unref (photo_feed);
+ g_object_unref (album_feed);
+ g_object_unref (dest_dir);
+ g_object_unref (dest_file);
+}
+
+static void
+test_download (GDataService *service)
+{
+ GDataFeed *album_feed, *photo_feed;
+ GList *album_entries, *photo_entries, *media_contents;
+ GDataPicasaWebAlbum *album;
+ GDataPicasaWebFile *photo;
+ GDataPicasaWebQuery *query;
+ GDataMediaContent* content;
+ GFile *dest_dir, *dest_file, *actual_file;
+ gchar *basename;
+ GError *error = NULL;
+
+ /*** Acquire a photo to test ***/
+ album_feed = gdata_picasaweb_service_query_all_albums (GDATA_PICASAWEB_SERVICE (service), NULL, NULL, NULL, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_FEED (album_feed));
+
+ album_entries = gdata_feed_get_entries (album_feed);
+ g_assert (album_entries != NULL);
+
+ album = GDATA_PICASAWEB_ALBUM (album_entries->data);
+
+ query = gdata_picasaweb_query_new (NULL);
+ gdata_picasaweb_query_set_image_size (query, "32"); /* we're querying for the smallest size, to save bandwidth here :D */
+ photo_feed = gdata_picasaweb_service_query_files (GDATA_PICASAWEB_SERVICE (service), album, GDATA_QUERY (query), NULL, NULL, NULL, &error);
+ g_object_unref (query);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_FEED (photo_feed));
+
+ photo_entries = gdata_feed_get_entries (photo_feed);
+ g_assert (photo_entries != NULL);
+
+ photo = GDATA_PICASAWEB_FILE (photo_entries->data);
+
+ dest_dir = g_file_new_for_path ("/tmp/gdata.picasaweb.test.dir/");
+ dest_file = g_file_new_for_path ("/tmp/gdata.picasaweb.test.dir/test.jpg");
+
+ /* clean up any pre-existing test output */
+ if (g_file_query_exists (dest_dir, NULL)) {
+ g_file_trash (dest_dir, NULL, &error); /* TODO does this remove it even with files in it? hope so */
+ g_assert_no_error (error);
+ }
+
+ media_contents = gdata_picasaweb_file_get_contents (photo);
+ g_assert_cmpint (g_list_length (media_contents), ==, 1);
+ content = GDATA_MEDIA_CONTENT (media_contents->data);
+
+ /* to a directory, non-existent, should succeed, file with "directory"'s name */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "gdata.picasaweb.test.dir");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a file in a "directory", which already exists as a file, should fail */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* create the directory so we can test on it and in it */
+ g_file_trash (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+ g_file_make_directory (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+
+ /* to a directory, existent, should succeed, using default filename */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (actual_file != NULL);
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "default.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+ /* TODO: test that it exists with default filename? */
+
+ /* to a directory, existent, should fail trying to use the default filename, which already exists */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_dir, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* to a directory, existent, should succeed with default filename, replacing what already exists */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_dir, TRUE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "default.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a path, non-existent, should succeed */
+ g_assert (g_file_query_exists (dest_file, NULL) == FALSE);
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "test.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* to a path, existent, without replace, should fail */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_file, FALSE, NULL, &error);
+ g_assert_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS);
+ g_clear_error (&error);
+ g_assert (actual_file == NULL);
+
+ /* to a path, existent, with replace, should succeed */
+ actual_file = gdata_media_content_download (content, service, "default.jpg", dest_file, TRUE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (g_file_query_exists (actual_file, NULL));
+ basename = g_file_get_basename (actual_file);
+ g_assert_cmpstr (basename, ==, "test.jpg");
+ g_free (basename);
+ g_object_unref (actual_file);
+
+ /* clean up test directory */
+ g_file_trash (dest_dir, NULL, &error);
+ g_assert_no_error (error);
+
+ g_object_unref (photo_feed);
+ g_object_unref (album_feed);
+ g_object_unref (dest_dir);
+ g_object_unref (dest_file);
+}
+
+static void
test_upload_simple (GDataService *service)
{
GDataPicasaWebFile *photo, *photo_new;
@@ -775,7 +1067,6 @@ main (int argc, char *argv[])
g_test_add_func ("/picasaweb/authentication", test_authentication);
if (g_test_thorough () == TRUE)
g_test_add_func ("/picasaweb/authentication_async", test_authentication_async);
- g_test_add_data_func ("/picasaweb/upload/photo", service, test_upload_simple);
g_test_add_data_func ("/picasaweb/query/all_albums", service, test_query_all_albums);
g_test_add_data_func ("/picasaweb/query/user", service, test_query_user);
if (g_test_thorough () == TRUE)
@@ -787,6 +1078,9 @@ main (int argc, char *argv[])
g_test_add_data_func ("/picasaweb/query/photo_feed", service, test_photo_feed);
g_test_add_data_func ("/picasaweb/query/photo_feed_entry", service, test_photo_feed_entry);
g_test_add_data_func ("/picasaweb/query/photo", service, test_photo);
+ g_test_add_data_func ("/picasaweb/upload/photo", service, test_upload_simple);
+ g_test_add_data_func ("/picasaweb/download/photo", service, test_download);
+ g_test_add_data_func ("/picasaweb/download/thumbnails", service, test_download_thumbnails);
g_test_add_data_func ("/picasaweb/album/new", service, test_album_new);
retval = g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]