[libgdata] picasaweb: Switch to a stream-based upload API
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgdata] picasaweb: Switch to a stream-based upload API
- Date: Fri, 10 Dec 2010 17:53:59 +0000 (UTC)
commit bee6e510abd2cb63341028d30c59f0f2f374b2dd
Author: Philip Withnall <philip tecnocode co uk>
Date: Fri Dec 10 15:05:46 2010 +0000
picasaweb: Switch to a stream-based upload API
For similar reasons as the Documents service's switch to a stream-based
upload and download API, it makes sense to switch the PicasaWeb service to a
stream-based upload API. This gives us more flexibility as to the source of
uploaded data.
The test suite has been updated appropriately.
The following API has been changed:
â?¢ gdata_picasaweb_service_upload_file()
The following API has been removed:
â?¢ gdata_picasaweb_service_upload_file_async()
â?¢ gdata_picasaweb_service_upload_file_finish()
The following API has been added:
â?¢ gdata_picasaweb_service_finish_file_upload()
docs/reference/gdata-sections.txt | 3 +-
gdata/gdata.symbols | 5 +-
gdata/services/picasaweb/gdata-picasaweb-service.c | 308 +++++---------------
gdata/services/picasaweb/gdata-picasaweb-service.h | 12 +-
gdata/tests/picasaweb.c | 143 ++++++++--
5 files changed, 203 insertions(+), 268 deletions(-)
---
diff --git a/docs/reference/gdata-sections.txt b/docs/reference/gdata-sections.txt
index c80da98..071218a 100644
--- a/docs/reference/gdata-sections.txt
+++ b/docs/reference/gdata-sections.txt
@@ -1335,8 +1335,7 @@ gdata_picasaweb_service_query_all_albums_async
gdata_picasaweb_service_query_files
gdata_picasaweb_service_query_files_async
gdata_picasaweb_service_upload_file
-gdata_picasaweb_service_upload_file_async
-gdata_picasaweb_service_upload_file_finish
+gdata_picasaweb_service_finish_file_upload
gdata_picasaweb_service_insert_album
gdata_picasaweb_service_insert_album_async
<SUBSECTION Standard>
diff --git a/gdata/gdata.symbols b/gdata/gdata.symbols
index a4409ec..7d65b16 100644
--- a/gdata/gdata.symbols
+++ b/gdata/gdata.symbols
@@ -587,9 +587,6 @@ gdata_picasaweb_service_get_user
gdata_picasaweb_service_query_all_albums
gdata_picasaweb_service_query_all_albums_async
gdata_picasaweb_service_query_files
-gdata_picasaweb_service_upload_file
-gdata_picasaweb_service_upload_file_async
-gdata_picasaweb_service_upload_file_finish
gdata_picasaweb_service_insert_album
gdata_picasaweb_feed_get_type
gdata_picasaweb_user_get_type
@@ -856,3 +853,5 @@ gdata_documents_service_add_entry_to_folder_async
gdata_documents_service_add_entry_to_folder_finish
gdata_documents_service_remove_entry_from_folder_async
gdata_documents_service_remove_entry_from_folder_finish
+gdata_picasaweb_service_upload_file
+gdata_picasaweb_service_finish_file_upload
diff --git a/gdata/services/picasaweb/gdata-picasaweb-service.c b/gdata/services/picasaweb/gdata-picasaweb-service.c
index 7b911dd..d656150 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-service.c
+++ b/gdata/services/picasaweb/gdata-picasaweb-service.c
@@ -59,22 +59,46 @@
* <title>Uploading a Photo or Video</title>
* <programlisting>
* GDataPicasaWebFile *file_entry, *uploaded_file_entry;
+ * GDataUploadStream *upload_stream;
* GFile *file_data;
+ * GFileInfo *file_info;
+ * GFileInputStream *file_stream;
*
* /<!-- -->* Specify the GFile image on disk to upload *<!-- -->/
* file_data = g_file_new_for_path (path);
*
+ * /<!-- -->* Get the file information for the file being uploaded. If another data source was being used for the upload, it would have to
+ * * provide an appropriate slug and content type. Note that this is a blocking operation. *<!-- -->/
+ * file_info = g_file_query_info (file_data, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ * G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ *
* /<!-- -->* Create a GDataPicasaWebFile entry for the image, setting a title and caption/summary *<!-- -->/
* file_entry = gdata_picasaweb_file_new (NULL);
* gdata_entry_set_title (GDATA_ENTRY (file_entry), "Black Cat");
* gdata_entry_set_summary (GDATA_ENTRY (file_entry), "Photo of the world's most beautiful cat.");
*
+ * /<!-- -->* Create an upload stream for the file. This is non-blocking. *<!-- -->/
+ * upload_stream = gdata_picasaweb_service_upload_file (service, album, file_entry, g_file_info_get_display_name (file_info),
+ * g_file_info_get_content_type (file_info), NULL);
+ * g_object_unref (file_info);
+ * g_object_unref (file_entry);
+ *
+ * /<!-- -->* Prepare a file stream for the file to be uploaded. This is a blocking operation. *<!-- -->/
+ * file_stream = g_file_read (file_data, NULL, NULL);
+ * g_object_unref (file_data);
+ *
* /<!-- -->* Upload the file to the server. Note that this is a blocking operation. *<!-- -->/
- * uploaded_file_entry = gdata_picasaweb_service_upload_file (service, album, file_entry, file_data, NULL, NULL);
+ * g_output_stream_splice (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (file_stream),
+ * G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, NULL);
+ *
+ * /<!-- -->* Parse the resulting updated entry. This is a non-blocking operation. *<!-- -->/
+ * uploaded_file_entry = gdata_picasaweb_service_finish_file_upload (service, upload_stream, NULL);
+ * g_object_unref (file_stream);
+ * g_object_unref (upload_stream);
+ *
+ * /<!-- -->* ... *<!-- -->/
*
- * g_object_unref (file_entry);
* g_object_unref (uploaded_file_entry);
- * g_object_unref (file_data);
* </programlisting>
* </example>
*
@@ -415,87 +439,45 @@ gdata_picasaweb_service_query_files_async (GDataPicasaWebService *self, GDataPic
progress_user_data, callback, user_data);
}
-static GOutputStream *
-get_file_output_stream (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry, GFile *file_data, GError **error)
-{
- GFileInfo *file_info = NULL;
- const gchar *slug = NULL, *content_type = NULL, *user_id = NULL, *album_id = NULL;
- GOutputStream *output_stream;
- gchar *upload_uri;
-
- /* PicasaWeb allows you to post to a default Dropbox */
- album_id = (album != NULL) ? gdata_entry_get_id (GDATA_ENTRY (album)) : "default";
- user_id = gdata_service_get_username (GDATA_SERVICE (self));
-
- file_info = g_file_query_info (file_data, "standard::display-name,standard::content-type", G_FILE_QUERY_INFO_NONE, NULL, error);
- if (file_info == NULL)
- return NULL;
-
- slug = g_file_info_get_display_name (file_info);
- content_type = g_file_info_get_content_type (file_info);
-
- /* Build the upload URI and upload stream */
- upload_uri = _gdata_service_build_uri (TRUE, "http://picasaweb.google.com/data/feed/api/user/%s/albumid/%s", user_id, album_id);
- output_stream = gdata_upload_stream_new (GDATA_SERVICE (self), SOUP_METHOD_POST, upload_uri, GDATA_ENTRY (file_entry), slug, content_type);
- g_free (upload_uri);
- g_object_unref (file_info);
-
- return output_stream;
-}
-
-static GDataPicasaWebFile *
-parse_spliced_stream (GOutputStream *output_stream, GError **error)
-{
- const gchar *response_body;
- gssize response_length;
- GDataPicasaWebFile *new_entry;
-
- /* Get the response from the server */
- response_body = gdata_upload_stream_get_response (GDATA_UPLOAD_STREAM (output_stream), &response_length);
- g_assert (response_body != NULL && response_length > 0);
-
- /* Parse the response to produce a GDataPicasaWebFile */
- new_entry = GDATA_PICASAWEB_FILE (gdata_parsable_new_from_xml (GDATA_TYPE_PICASAWEB_FILE, response_body, (gint) response_length, error));
-
- return new_entry;
-}
-
/**
* gdata_picasaweb_service_upload_file:
* @self: a #GDataPicasaWebService
* @album: (allow-none): a #GDataPicasaWebAlbum into which to insert the file, or %NULL
* @file_entry: a #GDataPicasaWebFile to insert
- * @file_data: the actual file to upload
- * @cancellable: optional #GCancellable object, or %NULL
+ * @slug: the filename to give to the uploaded file
+ * @content_type: the content type of the uploaded data
* @error: a #GError, or %NULL
*
- * Uploads a file (photo or video) to the given PicasaWeb @album, using the @actual_file from disk and the metadata from @file. If @album is
- * %NULL, the file will be uploaded to the currently-authenticated user's "Drop Box" album. A user must be authenticated to use this function.
+ * Uploads a file (photo or video) to the given PicasaWeb @album, using the metadata from @file and the file data written to the resulting
+ * #GDataUploadStream. If @album is %NULL, the file will be uploaded to the currently-authenticated user's "Drop Box" album. A user must be
+ * authenticated to use this function.
*
* If @file has already been inserted, a %GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED error will be returned. If no user is authenticated
* with the service, %GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED will be returned.
*
- * If there is a problem reading @file_data, an error from g_output_stream_splice() or g_file_query_info() will be returned. Other errors from
- * #GDataServiceError can be returned for other exceptional conditions, as determined by the server.
+ * The stream returned by this function should be written to using the standard #GOutputStream methods, asychronously or synchronously. Once the stream
+ * is closed (using g_output_stream_close()), gdata_picasaweb_service_finish_file_upload() should be called on it to parse and return the updated
+ * #GDataPicasaWebFile for the uploaded file. This must be done, as @file_entry isn't updated in-place.
*
- * Return value: (transfer full): the inserted #GDataPicasaWebFile with updated properties from @file_entry; unref with g_object_unref()
+ * Any upload errors will be thrown by the stream methods, and may come from the #GDataServiceError domain.
*
- * Since: 0.4.0
+ * Return value: (transfer full): a #GDataUploadStream to write the file data to, or %NULL; unref with g_object_unref()
+ *
+ * Since: 0.8.0
**/
-GDataPicasaWebFile *
-gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry, GFile *file_data,
- GCancellable *cancellable, GError **error)
+GDataUploadStream *
+gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry, const gchar *slug,
+ const gchar *content_type, GError **error)
{
- GOutputStream *output_stream;
- GInputStream *input_stream;
- GDataPicasaWebFile *new_entry;
- GError *child_error = NULL;
+ const gchar *user_id = NULL, *album_id = NULL;
+ GDataUploadStream *upload_stream;
+ gchar *upload_uri;
g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), NULL);
g_return_val_if_fail (album == NULL || GDATA_IS_PICASAWEB_ALBUM (album), NULL);
g_return_val_if_fail (GDATA_IS_PICASAWEB_FILE (file_entry), NULL);
- g_return_val_if_fail (G_IS_FILE (file_data), NULL);
- g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
+ g_return_val_if_fail (slug != NULL && *slug != '\0', NULL);
+ g_return_val_if_fail (content_type != NULL && *content_type != '\0', NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
if (gdata_entry_is_inserted (GDATA_ENTRY (file_entry)) == TRUE) {
@@ -510,194 +492,52 @@ gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWeb
return NULL;
}
- output_stream = get_file_output_stream (self, album, file_entry, file_data, error);
- if (output_stream == NULL)
- return NULL;
-
- /* Pipe the input file to the upload stream */
- input_stream = G_INPUT_STREAM (g_file_read (file_data, cancellable, error));
- if (input_stream == NULL) {
- g_object_unref (output_stream);
- return NULL;
- }
-
- g_output_stream_splice (output_stream, input_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- cancellable, &child_error);
-
- g_object_unref (input_stream);
- if (child_error != NULL) {
- g_object_unref (output_stream);
- g_propagate_error (error, child_error);
- return NULL;
- }
+ /* PicasaWeb allows you to post to a default Dropbox */
+ album_id = (album != NULL) ? gdata_entry_get_id (GDATA_ENTRY (album)) : "default";
+ user_id = gdata_service_get_username (GDATA_SERVICE (self));
- new_entry = parse_spliced_stream (output_stream, error);
- g_object_unref (output_stream);
+ /* Build the upload URI and upload stream */
+ upload_uri = _gdata_service_build_uri (TRUE, "http://picasaweb.google.com/data/feed/api/user/%s/albumid/%s", user_id, album_id);
+ upload_stream = GDATA_UPLOAD_STREAM (gdata_upload_stream_new (GDATA_SERVICE (self), SOUP_METHOD_POST, upload_uri, GDATA_ENTRY (file_entry),
+ slug, content_type));
+ g_free (upload_uri);
- return new_entry;
+ return upload_stream;
}
/**
- * gdata_picasaweb_service_upload_file_finish:
+ * gdata_picasaweb_service_finish_file_upload:
* @self: a #GDataPicasaWebService
- * @result: a #GSimpleAsyncResult
+ * @upload_stream: the #GDataUploadStream from the operation
* @error: a #GError, or %NULL
*
- * This should be called to obtain the result of a call to
- * gdata_picasaweb_service_upload_file_async() and to check for
- * errors.
+ * Finish off a file upload operation started by gdata_picasaweb_service_upload_file(), parsing the result and returning the new #GDataPicasaWebFile.
*
- * If there is a problem reading the subect file's data, an error
- * from g_output_stream_splice() or g_file_query_info() will be
- * returned. Other errors from #GDataServiceError can be returned for
- * other exceptional conditions, as determined by the server.
+ * If an error occurred during the upload operation, it will have been returned during the operation (e.g. by g_output_stream_splice() or one
+ * of the other stream methods). In such a case, %NULL will be returned but @error will remain unset. @error is only set in the case that the server
+ * indicates that the operation was successful, but an error is encountered in parsing the result sent by the server.
*
- * If the file to upload has already been inserted, a
- * %GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED error will be set. If
- * no user is authenticated with the service when trying to upload it,
- * %GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED will be set.
+ * Return value: (transfer full): the new #GDataPicasaWebFile, or %NULL; unref with g_object_unref()
*
- * Return value: (transfer full): the inserted #GDataPicasaWebFile; unref with
- * g_object_unref()
- *
- * Since: 0.6.0
+ * Since: 0.8.0
*/
GDataPicasaWebFile *
-gdata_picasaweb_service_upload_file_finish (GDataPicasaWebService *self, GAsyncResult *result, GError **error)
+gdata_picasaweb_service_finish_file_upload (GDataPicasaWebService *self, GDataUploadStream *upload_stream, GError **error)
{
+ const gchar *response_body;
+ gssize response_length;
+
g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), NULL);
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
+ g_return_val_if_fail (GDATA_IS_UPLOAD_STREAM (upload_stream), NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
+ /* Get the response from the server */
+ response_body = gdata_upload_stream_get_response (upload_stream, &response_length);
+ if (response_body == NULL || response_length == 0)
return NULL;
- g_assert (gdata_picasaweb_service_upload_file_async == g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (result)));
-
- return GDATA_PICASAWEB_FILE (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)));
-}
-
-typedef struct {
- GDataPicasaWebService *service;
- GAsyncReadyCallback callback;
- gpointer user_data;
-} UploadFileAsyncData;
-
-static void
-upload_file_async_data_free (UploadFileAsyncData *data)
-{
- g_object_unref (data->service);
- g_slice_free (UploadFileAsyncData, data);
-}
-
-static void
-upload_file_async_cb (GOutputStream *output_stream, GAsyncResult *result, UploadFileAsyncData *data)
-{
- GError *error = NULL;
- GDataPicasaWebFile *file = NULL;
- GSimpleAsyncResult *async_result;
-
- g_output_stream_splice_finish (output_stream, result, &error);
-
- /* If we're error free, parse the file from the stream */
- if (error == NULL)
- file = parse_spliced_stream (output_stream, &error);
-
- if (error == NULL && file != NULL) {
- async_result = g_simple_async_result_new (G_OBJECT (data->service), (GAsyncReadyCallback) data->callback,
- data->user_data, gdata_picasaweb_service_upload_file_async);
- } else {
- async_result = g_simple_async_result_new_from_error (G_OBJECT (data->service), (GAsyncReadyCallback) data->callback,
- data->user_data, error);
- }
-
- g_simple_async_result_set_op_res_gpointer (async_result, file, NULL);
-
- g_simple_async_result_complete (async_result);
-
- upload_file_async_data_free (data);
- g_object_unref (async_result);
-}
-
-/**
- * gdata_picasaweb_service_upload_file_async:
- * @self: a #GDataPicasaWebService
- * @album: (allow-none): a #GDataPicasaWebAlbum into which to insert the file, or %NULL
- * @file_entry: a #GDataPicasaWebFile to insert
- * @file_data: the actual file to upload
- * @cancellable: optional #GCancellable object, or %NULL
- * @callback: a #GAsyncReadyCallback to call when authentication is finished
- * @user_data: (closure): data to pass to the @callback function
- *
- * Uploads a file (photo or video) to the given PicasaWeb @album
- * asynchronously, using the @actual_file from disk and the metadata
- * from @file. If @album is %NULL, the file will be uploaded to the
- * currently-authenticated user's "Drop Box" album. A user must be
- * authenticated to use this function.
- *
- * @callback should call gdata_picasaweb_service_upload_file_finish()
- * to obtain a #GDataPicasaWebFile representing the uploaded file and
- * check for possible errors.
- *
- * Since: 0.6.0
- **/
-void
-gdata_picasaweb_service_upload_file_async (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry,
- GFile *file_data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
-{
- GOutputStream *output_stream;
- GInputStream *input_stream;
- UploadFileAsyncData *data;
- GSimpleAsyncResult *result;
- GError *error = NULL;
-
- g_return_if_fail (GDATA_IS_PICASAWEB_SERVICE (self));
- g_return_if_fail (album == NULL || GDATA_IS_PICASAWEB_ALBUM (album));
- g_return_if_fail (GDATA_IS_PICASAWEB_FILE (file_entry));
- g_return_if_fail (G_IS_FILE (file_data));
- g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
-
- if (gdata_entry_is_inserted (GDATA_ENTRY (file_entry)) == TRUE) {
- g_set_error_literal (&error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED,
- _("The entry has already been inserted."));
- goto error;
- }
-
- if (gdata_service_is_authenticated (GDATA_SERVICE (self)) == FALSE) {
- g_set_error_literal (&error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
- _("You must be authenticated to upload a file."));
- goto error;
- }
-
- /* Prepare and retrieve a #GDataOutputStream for the file and its data */
- output_stream = get_file_output_stream (self, album, file_entry, file_data, &error);
- if (output_stream == NULL)
- goto error;
-
- /* Pipe the input file to the upload stream */
- input_stream = G_INPUT_STREAM (g_file_read (file_data, cancellable, &error));
- if (input_stream == NULL) {
- g_object_unref (output_stream);
- goto error;
- }
-
- data = g_slice_new (UploadFileAsyncData);
- data->service = g_object_ref (self);
- data->callback = callback;
- data->user_data = user_data;
-
- /* Actually transfer the data */
- g_output_stream_splice_async (output_stream, input_stream, G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- 0, cancellable, (GAsyncReadyCallback) upload_file_async_cb, data);
-
- g_object_unref (input_stream);
- g_object_unref (output_stream);
-
- return;
-
-error:
- result = g_simple_async_result_new_from_error (G_OBJECT (self), callback, user_data, error);
- g_simple_async_result_complete (result);
+ /* Parse the response to produce a GDataPicasaWebFile */
+ return GDATA_PICASAWEB_FILE (gdata_parsable_new_from_xml (GDATA_TYPE_PICASAWEB_FILE, response_body, (gint) response_length, error));
}
/**
diff --git a/gdata/services/picasaweb/gdata-picasaweb-service.h b/gdata/services/picasaweb/gdata-picasaweb-service.h
index cbbd6be..7b3012b 100644
--- a/gdata/services/picasaweb/gdata-picasaweb-service.h
+++ b/gdata/services/picasaweb/gdata-picasaweb-service.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include <gdata/gdata-service.h>
+#include <gdata/gdata-upload-stream.h>
#include <gdata/services/picasaweb/gdata-picasaweb-album.h>
#include <gdata/services/picasaweb/gdata-picasaweb-user.h>
@@ -85,13 +86,10 @@ void gdata_picasaweb_service_query_files_async (GDataPicasaWebService *self, GDa
#include <gdata/services/picasaweb/gdata-picasaweb-file.h>
-GDataPicasaWebFile *gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry,
- GFile *file_data,
- GCancellable *cancellable, GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
-
-void gdata_picasaweb_service_upload_file_async (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry,
- GFile *file_data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
-GDataPicasaWebFile *gdata_picasaweb_service_upload_file_finish (GDataPicasaWebService *self, GAsyncResult *result,
+GDataUploadStream *gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry,
+ const gchar *slug, const gchar *content_type,
+ GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
+GDataPicasaWebFile *gdata_picasaweb_service_finish_file_upload (GDataPicasaWebService *self, GDataUploadStream *upload_stream,
GError **error) G_GNUC_WARN_UNUSED_RESULT G_GNUC_MALLOC;
GDataPicasaWebAlbum *gdata_picasaweb_service_insert_album (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GCancellable *cancellable,
diff --git a/gdata/tests/picasaweb.c b/gdata/tests/picasaweb.c
index abc5e45..061f21b 100644
--- a/gdata/tests/picasaweb.c
+++ b/gdata/tests/picasaweb.c
@@ -1148,15 +1148,23 @@ test_query_all_albums_async (gconstpointer service)
}
typedef struct {
+ GDataPicasaWebService *service;
GDataPicasaWebFile *photo;
GDataPicasaWebFile *updated_photo;
GFile *photo_file;
+ gchar *slug;
+ gchar *content_type;
+ GFileInputStream *file_stream;
} UploadData;
static void
setup_upload (UploadData *data, gconstpointer service)
{
+ GFileInfo *file_info;
const gchar * const tags[] = { "foo", "bar", ",,baz,baz", NULL };
+ GError *error = NULL;
+
+ data->service = g_object_ref ((gpointer) service);
/* Build the photo */
data->photo = gdata_picasaweb_file_new (NULL);
@@ -1167,6 +1175,22 @@ setup_upload (UploadData *data, gconstpointer service)
/* File is public domain: http://en.wikipedia.org/wiki/File:German_garden_gnome_cropped.jpg */
data->photo_file = g_file_new_for_path (TEST_FILE_DIR "photo.jpg");
+
+ /* Get the file's info */
+ file_info = g_file_query_info (data->photo_file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (G_IS_FILE_INFO (file_info));
+
+ data->slug = g_strdup (g_file_info_get_display_name (file_info));
+ data->content_type = g_strdup (g_file_info_get_content_type (file_info));
+
+ g_object_unref (file_info);
+
+ /* Get an input stream for the file */
+ data->file_stream = g_file_read (data->photo_file, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (G_IS_FILE_INPUT_STREAM (data->file_stream));
}
static void
@@ -1180,23 +1204,43 @@ teardown_upload (UploadData *data, gconstpointer service)
g_object_unref (data->photo);
g_object_unref (data->photo_file);
+ g_free (data->slug);
+ g_free (data->content_type);
+ g_object_unref (data->file_stream);
+ g_object_unref (data->service);
}
static void
test_upload_default_album (UploadData *data, gconstpointer service)
{
+ GDataUploadStream *upload_stream;
const gchar * const *tags, * const *tags2;
+ gssize transfer_size;
GError *error = NULL;
- /* Upload the photo */
+ /* Prepare the upload stream */
/* TODO right now, it will just go to the default album, we want an uploading one :| */
- data->updated_photo = gdata_picasaweb_service_upload_file (GDATA_PICASAWEB_SERVICE (service), NULL, data->photo, data->photo_file, NULL,
- &error);
+ upload_stream = gdata_picasaweb_service_upload_file (GDATA_PICASAWEB_SERVICE (service), NULL, data->photo, data->slug, data->content_type,
+ &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_UPLOAD_STREAM (upload_stream));
+
+ /* Upload the photo */
+ transfer_size = g_output_stream_splice (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (data->file_stream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (transfer_size, >, 0);
+
+ /* Finish off the upload */
+ data->updated_photo = gdata_picasaweb_service_finish_file_upload (GDATA_PICASAWEB_SERVICE (service), upload_stream, &error);
g_assert_no_error (error);
g_assert (GDATA_IS_PICASAWEB_FILE (data->updated_photo));
- g_clear_error (&error);
- /* TODO: check entries and feed properties */
+ /* Check the photo's properties */
+ g_assert (gdata_entry_is_inserted (GDATA_ENTRY (data->updated_photo)));
+ g_assert_cmpstr (gdata_entry_get_title (GDATA_ENTRY (data->updated_photo)), ==, gdata_entry_get_title (GDATA_ENTRY (data->photo)));
+ g_assert_cmpstr (gdata_picasaweb_file_get_caption (data->updated_photo), ==, gdata_picasaweb_file_get_caption (data->photo));
+
tags = gdata_picasaweb_file_get_tags (data->photo);
tags2 = gdata_picasaweb_file_get_tags (data->updated_photo);
g_assert_cmpuint (g_strv_length ((gchar**) tags2), ==, g_strv_length ((gchar**) tags));
@@ -1225,17 +1269,33 @@ teardown_upload_async (UploadAsyncData *data, gconstpointer service)
}
static void
-test_upload_default_album_async_cb (GDataPicasaWebService *service, GAsyncResult *result, UploadAsyncData *data)
+test_upload_default_album_async_cb (GOutputStream *stream, GAsyncResult *result, UploadAsyncData *data)
{
+ const gchar * const *tags, * const *tags2;
+ gssize transfer_size;
GError *error = NULL;
- data->data.updated_photo = gdata_picasaweb_service_upload_file_finish (service, result, &error);
+ /* Finish off the transfer */
+ transfer_size = g_output_stream_splice_finish (stream, result, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (transfer_size, >, 0);
+
+ /* Finish off the upload */
+ data->data.updated_photo = gdata_picasaweb_service_finish_file_upload (data->data.service, GDATA_UPLOAD_STREAM (stream), &error);
g_assert_no_error (error);
g_assert (GDATA_IS_PICASAWEB_FILE (data->data.updated_photo));
- g_clear_error (&error);
- g_assert (gdata_entry_is_inserted (GDATA_ENTRY (data->data.updated_photo)));
+ /* Check the photo's properties */
+ g_assert (gdata_entry_is_inserted (GDATA_ENTRY (data->data.updated_photo)));
g_assert_cmpstr (gdata_entry_get_title (GDATA_ENTRY (data->data.updated_photo)), ==, gdata_entry_get_title (GDATA_ENTRY (data->data.photo)));
+ g_assert_cmpstr (gdata_picasaweb_file_get_caption (data->data.updated_photo), ==, gdata_picasaweb_file_get_caption (data->data.photo));
+
+ tags = gdata_picasaweb_file_get_tags (data->data.photo);
+ tags2 = gdata_picasaweb_file_get_tags (data->data.updated_photo);
+ g_assert_cmpuint (g_strv_length ((gchar**) tags2), ==, g_strv_length ((gchar**) tags));
+ g_assert_cmpstr (tags2[0], ==, tags[0]);
+ g_assert_cmpstr (tags2[1], ==, tags[1]);
+ g_assert_cmpstr (tags2[2], ==, tags[2]);
g_main_loop_quit (data->main_loop);
}
@@ -1243,22 +1303,41 @@ test_upload_default_album_async_cb (GDataPicasaWebService *service, GAsyncResult
static void
test_upload_default_album_async (UploadAsyncData *data, gconstpointer service)
{
- /* Upload the photo */
- gdata_picasaweb_service_upload_file_async (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.photo_file, NULL,
- (GAsyncReadyCallback) test_upload_default_album_async_cb, data);
+ GDataUploadStream *upload_stream;
+ GError *error = NULL;
+
+ /* Prepare the upload stream */
+ upload_stream = gdata_picasaweb_service_upload_file (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.slug,
+ data->data.content_type, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_UPLOAD_STREAM (upload_stream));
+
+ /* Upload the photo asynchronously */
+ g_output_stream_splice_async (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (data->data.file_stream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, G_PRIORITY_DEFAULT, NULL,
+ (GAsyncReadyCallback) test_upload_default_album_async_cb, data);
g_main_loop_run (data->main_loop);
+
+ g_object_unref (upload_stream);
}
static void
-test_upload_default_album_cancellation_cb (GDataPicasaWebService *service, GAsyncResult *async_result, UploadAsyncData *data)
+test_upload_default_album_cancellation_cb (GOutputStream *stream, GAsyncResult *result, UploadAsyncData *data)
{
+ gssize transfer_size;
GError *error = NULL;
- data->data.updated_photo = gdata_picasaweb_service_upload_file_finish (service, async_result, &error);
+ /* Finish off the transfer */
+ transfer_size = g_output_stream_splice_finish (stream, result, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
- g_assert (data->data.updated_photo == NULL);
+ g_assert_cmpint (transfer_size, ==, -1);
g_clear_error (&error);
+ /* Finish off the upload */
+ data->data.updated_photo = gdata_picasaweb_service_finish_file_upload (data->data.service, GDATA_UPLOAD_STREAM (stream), &error);
+ g_assert_no_error (error);
+ g_assert (data->data.updated_photo == NULL);
+
g_main_loop_quit (data->main_loop);
}
@@ -1272,34 +1351,54 @@ test_upload_default_album_cancellation_cancel_cb (GCancellable *cancellable)
static void
test_upload_default_album_cancellation (UploadAsyncData *data, gconstpointer service)
{
+ GDataUploadStream *upload_stream;
GCancellable *cancellable;
+ GError *error = NULL;
/* Create an idle function which will cancel the upload */
cancellable = g_cancellable_new ();
g_idle_add ((GSourceFunc) test_upload_default_album_cancellation_cancel_cb, cancellable);
- /* Upload the photo */
- gdata_picasaweb_service_upload_file_async (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.photo_file, cancellable,
- (GAsyncReadyCallback) test_upload_default_album_cancellation_cb, data);
+ /* Prepare the upload stream */
+ upload_stream = gdata_picasaweb_service_upload_file (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.slug,
+ data->data.content_type, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_UPLOAD_STREAM (upload_stream));
+
+ /* Upload the photo asynchronously */
+ g_output_stream_splice_async (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (data->data.file_stream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, G_PRIORITY_DEFAULT, cancellable,
+ (GAsyncReadyCallback) test_upload_default_album_cancellation_cb, data);
g_main_loop_run (data->main_loop);
+ g_object_unref (upload_stream);
g_object_unref (cancellable);
}
static void
test_upload_default_album_cancellation2 (UploadAsyncData *data, gconstpointer service)
{
+ GDataUploadStream *upload_stream;
GCancellable *cancellable;
+ GError *error = NULL;
- /* Create an idle function which will cancel the upload */
+ /* Create a timeout function which will cancel the upload after 1ms */
cancellable = g_cancellable_new ();
g_timeout_add (1, (GSourceFunc) test_upload_default_album_cancellation_cancel_cb, cancellable);
- /* Upload the photo */
- gdata_picasaweb_service_upload_file_async (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.photo_file, cancellable,
- (GAsyncReadyCallback) test_upload_default_album_cancellation_cb, data);
+ /* Prepare the upload stream */
+ upload_stream = gdata_picasaweb_service_upload_file (GDATA_PICASAWEB_SERVICE (service), NULL, data->data.photo, data->data.slug,
+ data->data.content_type, &error);
+ g_assert_no_error (error);
+ g_assert (GDATA_IS_UPLOAD_STREAM (upload_stream));
+
+ /* Upload the photo asynchronously */
+ g_output_stream_splice_async (G_OUTPUT_STREAM (upload_stream), G_INPUT_STREAM (data->data.file_stream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, G_PRIORITY_DEFAULT, cancellable,
+ (GAsyncReadyCallback) test_upload_default_album_cancellation_cb, data);
g_main_loop_run (data->main_loop);
+ g_object_unref (upload_stream);
g_object_unref (cancellable);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]