/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* * GData Client * Copyright (C) Richard Schwarting 2009 * Copyright (C) Philip Withnall 2009–2010 * * 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 . */ /** * SECTION:gdata-picasaweb-service * @short_description: GData PicasaWeb service object * @stability: Stable * @include: gdata/services/picasaweb/gdata-picasaweb-service.h * * #GDataPicasaWebService is a subclass of #GDataService for communicating with the GData API of Google PicasaWeb. It supports querying for files * and albums, and uploading files. * * For more details of PicasaWeb's GData API, see the * online documentation. * * * Authenticating and Creating a New Album * * GDataClientLoginAuthorizer *authorizer; * GDataPicasaWebService *service; * GDataPicasaWebAlbum *album, *inserted_album; * * /* Create a service object and authorize against the PicasaWeb service */ * authorizer = gdata_client_login_authorizer_new ("companyName-applicationName-versionID", GDATA_TYPE_PICASAWEB_SERVICE); * gdata_client_login_authorizer_authenticate (authorizer, username, password, NULL, NULL); * service = gdata_picasaweb_service_new (GDATA_AUTHORIZER (authorizer)); * * /* Create a GDataPicasaWebAlbum entry for the new album, setting some information about it */ * album = gdata_picasaweb_album_new (NULL); * gdata_entry_set_title (GDATA_ENTRY (album), "Photos from the Rhine"); * gdata_entry_set_summary (GDATA_ENTRY (album), "An album of our adventures on the great river."); * gdata_picasaweb_album_set_location (album, "The Rhine, Germany"); * * /* Insert the new album on the server. Note that this is a blocking operation. */ * inserted_album = gdata_picasaweb_service_insert_album (service, album, NULL, NULL); * * g_object_unref (album); * g_object_unref (inserted_album); * g_object_unref (service); * g_object_unref (authorizer); * * * * * Uploading a Photo or Video * * 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, 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. */ * 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 (uploaded_file_entry); * * * * * Since: 0.4.0 */ #include #include #include #include "gdata-service.h" #include "gdata-picasaweb-service.h" #include "gdata-private.h" #include "gdata-parser.h" #include "atom/gdata-link.h" #include "gdata-upload-stream.h" #include "gdata-picasaweb-feed.h" static GList *get_authorization_domains (void); _GDATA_DEFINE_AUTHORIZATION_DOMAIN (picasaweb, "lh2", "http://picasaweb.google.com/data/") G_DEFINE_TYPE (GDataPicasaWebService, gdata_picasaweb_service, GDATA_TYPE_SERVICE) static void gdata_picasaweb_service_class_init (GDataPicasaWebServiceClass *klass) { GDataServiceClass *service_class = GDATA_SERVICE_CLASS (klass); service_class->feed_type = GDATA_TYPE_PICASAWEB_FEED; service_class->get_authorization_domains = get_authorization_domains; } static void gdata_picasaweb_service_init (GDataPicasaWebService *self) { /* Nothing to see here */ } static GList * get_authorization_domains (void) { return g_list_prepend (NULL, get_picasaweb_authorization_domain ()); } /** * gdata_picasaweb_service_new: * @authorizer: (allow-none): a #GDataAuthorizer to authorize the service's requests, or %NULL * * Creates a new #GDataPicasaWebService using the given #GDataAuthorizer. If @authorizer is %NULL, all requests are made as an unauthenticated user. * * Return value: a new #GDataPicasaWebService, or %NULL; unref with g_object_unref() * * Since: 0.9.0 */ GDataPicasaWebService * gdata_picasaweb_service_new (GDataAuthorizer *authorizer) { g_return_val_if_fail (authorizer == NULL || GDATA_IS_AUTHORIZER (authorizer), NULL); return g_object_new (GDATA_TYPE_PICASAWEB_SERVICE, "authorizer", authorizer, NULL); } /** * gdata_picasaweb_service_get_primary_authorization_domain: * * The primary #GDataAuthorizationDomain for interacting with PicasaWeb. This will not normally need to be used, as it's used internally * by the #GDataPicasaWebService methods. However, if using the plain #GDataService methods to implement custom queries or requests which libgdata * does not support natively, then this domain may be needed to authorize the requests. * * The domain never changes, and is interned so that pointer comparison can be used to differentiate it from other authorization domains. * * Return value: (transfer none): the service's authorization domain * * Since: 0.9.0 */ GDataAuthorizationDomain * gdata_picasaweb_service_get_primary_authorization_domain (void) { return get_picasaweb_authorization_domain (); } /* * create_uri: * @self: a #GDataPicasaWebService * @username: (allow-none): the username to use, or %NULL to use the currently logged in user * @type: the type of object to access: "entry" for a user, or "feed" for an album * * Builds a URI to use when querying for albums or a user. * * Return value: a constructed URI; free with g_free() * * Since: 0.4.0 */ static gchar * create_uri (GDataPicasaWebService *self, const gchar *username, const gchar *type) { if (username == NULL) { /* Ensure we're authorized first */ if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)), get_picasaweb_authorization_domain ()) == FALSE) { return NULL; } /* Querying Picasa albums for the "default" user when logged in returns the albums for the authenticated user */ username = "default"; } return _gdata_service_build_uri ("https://picasaweb.google.com/data/%s/api/user/%s", type, username); } /** * gdata_picasaweb_service_get_user: * @self: a #GDataPicasaWebService * @username: (allow-none): the username of the user whose information you wish to retrieve, or %NULL for the currently authenticated user. * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @error: a #GError, or %NULL * * Queries the service to return the user specified by @username. * * Return value: (transfer full): a #GDataPicasaWebUser; unref with g_object_unref() * * Since: 0.6.0 */ GDataPicasaWebUser * gdata_picasaweb_service_get_user (GDataPicasaWebService *self, const gchar *username, GCancellable *cancellable, GError **error) { gchar *uri; GDataParsable *user; SoupMessage *message; g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); uri = create_uri (self, username, "entry"); if (uri == NULL) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, _("You must specify a username or be authenticated to query a user.")); return NULL; } message = _gdata_service_query (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), uri, NULL, cancellable, error); g_free (uri); if (message == NULL) return NULL; g_assert (message->response_body->data != NULL); user = gdata_parsable_new_from_xml (GDATA_TYPE_PICASAWEB_USER, message->response_body->data, message->response_body->length, error); g_object_unref (message); return GDATA_PICASAWEB_USER (user); } static void get_user_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { GDataPicasaWebService *service = GDATA_PICASAWEB_SERVICE (source_object); const gchar *username = task_data; g_autoptr(GDataPicasaWebUser) user = NULL; g_autoptr(GError) error = NULL; /* Get the user and return */ user = gdata_picasaweb_service_get_user (service, username, cancellable, &error); if (error != NULL) g_task_return_error (task, g_steal_pointer (&error)); else g_task_return_pointer (task, g_steal_pointer (&user), g_object_unref); } /** * gdata_picasaweb_service_get_user_async: * @self: a #GDataPicasaWebService * @username: (allow-none): the username of the user whose information you wish to retrieve, or %NULL for the currently authenticated user * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @callback: a #GAsyncReadyCallback to call when the query is finished * @user_data: (closure): data to pass to the @callback function * * Queries the service to return the user specified by @username. * * For more details, see gdata_picasaweb_service_get_user() which is the synchronous version of this method. * * When the operation is finished, @callback will be called. You can then call gdata_picasaweb_service_get_user_finish() to get the results of the * operation. * * Since: 0.9.1 */ void gdata_picasaweb_service_get_user_async (GDataPicasaWebService *self, const gchar *username, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_autoptr(GTask) task = NULL; g_return_if_fail (GDATA_IS_PICASAWEB_SERVICE (self)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (callback != NULL); task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, gdata_picasaweb_service_get_user_async); g_task_set_task_data (task, g_strdup (username), (GDestroyNotify) g_free); g_task_run_in_thread (task, get_user_thread); } /** * gdata_picasaweb_service_get_user_finish: * @self: a #GDataPicasaWebService * @result: a #GAsyncResult * @error: a #GError, or %NULL * * Finishes an asynchronous user retrieval operation started with gdata_picasaweb_service_get_user_async(). * * Return value: (transfer full): a #GDataPicasaWebUser; unref with g_object_unref() * * Since: 0.9.1 */ GDataPicasaWebUser * gdata_picasaweb_service_get_user_finish (GDataPicasaWebService *self, GAsyncResult *async_result, GError **error) { g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), NULL); g_return_val_if_fail (G_IS_ASYNC_RESULT (async_result), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); g_return_val_if_fail (g_task_is_valid (async_result, self), NULL); g_return_val_if_fail (g_async_result_is_tagged (async_result, gdata_picasaweb_service_get_user_async), NULL); return g_task_propagate_pointer (G_TASK (async_result), error); } /** * gdata_picasaweb_service_query_all_albums: * @self: a #GDataPicasaWebService * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL * @username: (allow-none): the username of the user whose albums you wish to retrieve, 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 an entry is loaded, or %NULL * @progress_user_data: (closure): data to pass to the @progress_callback function * @error: a #GError, or %NULL * * Queries the service to return a list of all albums belonging to the specified @username which match the given * @query. If a user is authenticated with the service, @username can be set as %NULL to return a list of albums belonging * to the currently-authenticated user. * * Note that the #GDataQuery:q query parameter cannot be set on @query for album queries. * * For more details, see gdata_service_query(). * * Return value: (transfer full): a #GDataFeed of query results; unref with g_object_unref() * * Since: 0.4.0 */ GDataFeed * gdata_picasaweb_service_query_all_albums (GDataPicasaWebService *self, GDataQuery *query, const gchar *username, GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error) { gchar *uri; GDataFeed *album_feed; g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), 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); if (query != NULL && gdata_query_get_q (query) != NULL) { /* Bug #593336 — Query parameter "q=..." isn't valid for album kinds */ g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER, _("Query parameter not allowed for albums.")); return NULL; } uri = create_uri (self, username, "feed"); if (uri == NULL) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, _("You must specify a username or be authenticated to query all albums.")); return NULL; } /* Execute the query */ album_feed = gdata_service_query (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), uri, query, GDATA_TYPE_PICASAWEB_ALBUM, cancellable, progress_callback, progress_user_data, error); g_free (uri); return album_feed; } /** * gdata_picasaweb_service_query_all_albums_async: * @self: a #GDataPicasaWebService * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL * @username: (allow-none): the username of the user whose albums you wish to retrieve, or %NULL * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @progress_callback: (allow-none) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL * @progress_user_data: (closure): data to pass to the @progress_callback function * @destroy_progress_user_data: (allow-none): the 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 authentication is finished * @user_data: (closure): data to pass to the @callback function * * Queries the service to return a list of all albums belonging to the specified @username which match the given * @query. @self, @query and @username are all reffed/copied when this function is called, so can safely be unreffed/freed after * this function returns. * * For more details, see gdata_picasaweb_service_query_all_albums(), which is the synchronous version of * this function, and gdata_service_query_async(), which is the base asynchronous query function. * * Since: 0.9.1 */ void gdata_picasaweb_service_query_all_albums_async (GDataPicasaWebService *self, GDataQuery *query, const gchar *username, GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data) { gchar *uri; g_return_if_fail (GDATA_IS_PICASAWEB_SERVICE (self)); 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); if (query != NULL && gdata_query_get_q (query) != NULL) { /* Bug #593336 — Query parameter "q=..." isn't valid for album kinds */ g_autoptr(GTask) task = NULL; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, gdata_service_query_async); g_task_return_new_error (task, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_BAD_QUERY_PARAMETER, "%s", _("Query parameter not allowed for albums.")); return; } uri = create_uri (self, username, "feed"); if (uri == NULL) { g_autoptr(GTask) task = NULL; task = g_task_new (self, cancellable, callback, user_data); g_task_set_source_tag (task, gdata_service_query_async); g_task_return_new_error (task, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, "%s", _("You must specify a username or be authenticated to query all albums.")); return; } /* Schedule the async query */ gdata_service_query_async (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), uri, query, GDATA_TYPE_PICASAWEB_ALBUM, cancellable, progress_callback, progress_user_data, destroy_progress_user_data, callback, user_data); g_free (uri); } static const gchar * get_query_files_uri (GDataPicasaWebAlbum *album, GError **error) { if (album != NULL) { GDataLink *_link = gdata_entry_look_up_link (GDATA_ENTRY (album), "http://schemas.google.com/g/2005#feed"); if (_link == NULL) { /* Error */ g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_PROTOCOL_ERROR, _("The album did not have a feed link.")); return NULL; } return gdata_link_get_uri (_link); } else { /* Default URI */ return "https://picasaweb.google.com/data/feed/api/user/default/albumid/default"; } } /** * gdata_picasaweb_service_query_files: * @self: a #GDataPicasaWebService * @album: (allow-none): a #GDataPicasaWebAlbum from which to retrieve the files, or %NULL * @query: (allow-none): a #GDataQuery with the 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 an entry is loaded, or %NULL * @progress_user_data: (closure): data to pass to the @progress_callback function * @error: a #GError, or %NULL * * Queries the specified @album for a list of the files which match the given @query. If @album is %NULL and a user is * authenticated with the service, the user's default album will be queried. * * For more details, see gdata_service_query(). * * Return value: (transfer full): a #GDataFeed of query results; unref with g_object_unref() * * Since: 0.4.0 */ GDataFeed * gdata_picasaweb_service_query_files (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataQuery *query, GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GError **error) { const gchar *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 (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); uri = get_query_files_uri (album, error); if (uri == NULL) return NULL; /* Execute the query */ return gdata_service_query (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), uri, GDATA_QUERY (query), GDATA_TYPE_PICASAWEB_FILE, cancellable, progress_callback, progress_user_data, error); } /** * gdata_picasaweb_service_query_files_async: * @self: a #GDataPicasaWebService * @album: (allow-none): a #GDataPicasaWebAlbum from which to retrieve the files, or %NULL * @query: (allow-none): a #GDataQuery with the query parameters, or %NULL * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @progress_callback: (allow-none) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL * @progress_user_data: (closure): data to pass to the @progress_callback function * @destroy_progress_user_data: (allow-none): the 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 * * Queries the specified @album for a list of the files which match the given @query. If @album is %NULL and a user is authenticated with the service, * the user's default album will be queried. @self, @album and @query are all reffed when this function is called, so can safely be unreffed after * this function returns. * * For more details, see gdata_picasaweb_service_query_files(), which is the synchronous version of this function, and gdata_service_query_async(), * which is the base asynchronous query function. * * Since: 0.9.1 */ void gdata_picasaweb_service_query_files_async (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataQuery *query, GCancellable *cancellable, GDataQueryProgressCallback progress_callback, gpointer progress_user_data, GDestroyNotify destroy_progress_user_data, GAsyncReadyCallback callback, gpointer user_data) { const gchar *request_uri; GError *child_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 (query == NULL || GDATA_IS_QUERY (query)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); g_return_if_fail (callback != NULL); request_uri = get_query_files_uri (album, &child_error); if (request_uri == NULL) { g_task_report_error (self, callback, user_data, gdata_service_query_async, g_steal_pointer (&child_error)); return; } gdata_service_query_async (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), request_uri, GDATA_QUERY (query), GDATA_TYPE_PICASAWEB_FILE, cancellable, progress_callback, progress_user_data, destroy_progress_user_data, callback, user_data); } /** * 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 * @slug: the filename to give to the uploaded file * @content_type: the content type of the uploaded data * @cancellable: (allow-none): a #GCancellable for the entire upload stream, or %NULL * @error: a #GError, or %NULL * * 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. It is recommended to retry the * upload after refreshing the authorization tokens held by the associated #GDataAuthorizer using gdata_authorizer_refresh_authorization(). * * The stream returned by this function should be written to using the standard #GOutputStream methods, asynchronously 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. * * In order to cancel the upload, a #GCancellable passed in to @cancellable must be cancelled using g_cancellable_cancel(). Cancelling the individual * #GOutputStream operations on the #GDataUploadStream will not cancel the entire upload; merely the write or close operation in question. See the * #GDataUploadStream:cancellable for more details. * * Any upload errors will be thrown by the stream methods, and may come from the #GDataServiceError domain. * * Return value: (transfer full): a #GDataUploadStream to write the file data to, or %NULL; unref with g_object_unref() * * Since: 0.8.0 */ GDataUploadStream * gdata_picasaweb_service_upload_file (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GDataPicasaWebFile *file_entry, const gchar *slug, const gchar *content_type, GCancellable *cancellable, GError **error) { const gchar *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 (slug != NULL && *slug != '\0', NULL); g_return_val_if_fail (content_type != NULL && *content_type != '\0', NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); 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.")); return NULL; } if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)), get_picasaweb_authorization_domain ()) == FALSE) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, _("You must be authenticated to upload a file.")); return NULL; } /* PicasaWeb allows you to post to a default Dropbox */ album_id = (album != NULL) ? gdata_picasaweb_album_get_id (album) : "default"; /* Build the upload URI and upload stream */ upload_uri = _gdata_service_build_uri ("https://picasaweb.google.com/data/feed/api/user/default/albumid/%s", album_id); upload_stream = GDATA_UPLOAD_STREAM (gdata_upload_stream_new (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), SOUP_METHOD_POST, upload_uri, GDATA_ENTRY (file_entry), slug, content_type, cancellable)); g_free (upload_uri); return upload_stream; } /** * gdata_picasaweb_service_finish_file_upload: * @self: a #GDataPicasaWebService * @upload_stream: the #GDataUploadStream from the operation * @error: a #GError, or %NULL * * Finish off a file upload operation started by gdata_picasaweb_service_upload_file(), parsing the result and returning the new #GDataPicasaWebFile. * * 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. * * Return value: (transfer full): the new #GDataPicasaWebFile, or %NULL; unref with g_object_unref() * * Since: 0.8.0 */ GDataPicasaWebFile * 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 (GDATA_IS_UPLOAD_STREAM (upload_stream), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* 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; /* 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)); } /** * gdata_picasaweb_service_insert_album: * @self: a #GDataPicasaWebService * @album: a #GDataPicasaWebAlbum to create on the server * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @error: a #GError, or %NULL * * Inserts a new album described by @album. A user must be * authenticated to use this function. * * Return value: (transfer full): the inserted #GDataPicasaWebAlbum; unref with * g_object_unref() * * Since: 0.6.0 */ GDataPicasaWebAlbum * gdata_picasaweb_service_insert_album (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GCancellable *cancellable, GError **error) { g_return_val_if_fail (GDATA_IS_PICASAWEB_SERVICE (self), NULL); g_return_val_if_fail (GDATA_IS_PICASAWEB_ALBUM (album), NULL); g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (gdata_entry_is_inserted (GDATA_ENTRY (album)) == TRUE) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_ENTRY_ALREADY_INSERTED, _("The album has already been inserted.")); return NULL; } if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)), get_picasaweb_authorization_domain ()) == FALSE) { g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, _("You must be authenticated to insert an album.")); return NULL; } return GDATA_PICASAWEB_ALBUM (gdata_service_insert_entry (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), "https://picasaweb.google.com/data/feed/api/user/default", GDATA_ENTRY (album), cancellable, error)); } /** * gdata_picasaweb_service_insert_album_async: * @self: a #GDataPicasaWebService * @album: a #GDataPicasaWebAlbum to create on the server * @cancellable: (allow-none): optional #GCancellable object, or %NULL * @callback: a #GAsyncReadyCallback to call when insertion is finished * @user_data: (closure): data to pass to the @callback function * * Inserts a new album described by @album. The user must be authenticated to use this function. @self and @album are both reffed when this function * is called, so can safely be unreffed after this function returns. * * @callback should call gdata_service_insert_entry_finish() to obtain a #GDataPicasaWebAlbum representing the inserted album and to check for * possible errors. * * For more details, see gdata_picasaweb_service_insert_album(), which is the synchronous version of this function, and * gdata_service_insert_entry_async(), which is the base asynchronous insertion function. * * Since: 0.8.0 */ void gdata_picasaweb_service_insert_album_async (GDataPicasaWebService *self, GDataPicasaWebAlbum *album, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { g_return_if_fail (GDATA_IS_PICASAWEB_SERVICE (self)); g_return_if_fail (GDATA_IS_PICASAWEB_ALBUM (album)); g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); gdata_service_insert_entry_async (GDATA_SERVICE (self), get_picasaweb_authorization_domain (), "https://picasaweb.google.com/data/feed/api/user/default", GDATA_ENTRY (album), cancellable, callback, user_data); }