229
229
return g_quark_from_static_string ("gdata-documents-service-error-quark");
232
static void gdata_documents_service_dispose (GObject *object);
233
static void gdata_documents_service_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
234
static void notify_authenticated_cb (GObject *service, GParamSpec *pspec, GObject *self);
235
static void notify_proxy_uri_cb (GObject *service, GParamSpec *pspec, GObject *self);
237
struct _GDataDocumentsServicePrivate {
238
GDataService *spreadsheet_service;
242
PROP_SPREADSHEET_SERVICE = 1
232
static GList *get_authorization_domains (void);
234
_GDATA_DEFINE_AUTHORIZATION_DOMAIN (documents, "writely", "https://docs.google.com/feeds/")
235
_GDATA_DEFINE_AUTHORIZATION_DOMAIN (spreadsheets, "wise", "https://spreadsheets.google.com/feeds/")
245
236
G_DEFINE_TYPE_WITH_CODE (GDataDocumentsService, gdata_documents_service, GDATA_TYPE_SERVICE, G_IMPLEMENT_INTERFACE (GDATA_TYPE_BATCHABLE, NULL))
248
239
gdata_documents_service_class_init (GDataDocumentsServiceClass *klass)
250
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
251
241
GDataServiceClass *service_class = GDATA_SERVICE_CLASS (klass);
253
g_type_class_add_private (klass, sizeof (GDataDocumentsServicePrivate));
255
gobject_class->get_property = gdata_documents_service_get_property;
256
gobject_class->dispose = gdata_documents_service_dispose;
258
service_class->service_name = "writely";
259
242
service_class->feed_type = GDATA_TYPE_DOCUMENTS_FEED;
262
* GDataService:spreadsheet-service:
264
* Another service for spreadsheets, required to be able to handle downloads.
266
* For more details about the spreadsheet downloads handling, see the
267
* <ulink type="http" url="http://groups.google.com/group/Google-Docs-Data-APIs/browse_thread/thread/bfc50e94e303a29a?pli=1">
268
* online explanation about the problem</ulink>.
272
g_object_class_install_property (gobject_class, PROP_SPREADSHEET_SERVICE,
273
g_param_spec_object ("spreadsheet-service",
274
"Spreadsheet service", "Another service for spreadsheets.",
243
service_class->get_authorization_domains = get_authorization_domains;
280
247
gdata_documents_service_init (GDataDocumentsService *self)
282
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GDATA_TYPE_DOCUMENTS_SERVICE, GDataDocumentsServicePrivate);
283
g_signal_connect (self, "notify::authenticated", G_CALLBACK (notify_authenticated_cb), NULL);
284
g_signal_connect (self, "notify::proxy-uri", G_CALLBACK (notify_proxy_uri_cb), NULL);
288
gdata_documents_service_dispose (GObject *object)
290
GDataDocumentsServicePrivate *priv = GDATA_DOCUMENTS_SERVICE (object)->priv;
292
if (priv->spreadsheet_service != NULL)
293
g_object_unref (priv->spreadsheet_service);
294
priv->spreadsheet_service = NULL;
296
G_OBJECT_CLASS (gdata_documents_service_parent_class)->dispose (object);
300
gdata_documents_service_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec)
302
GDataDocumentsServicePrivate *priv = GDATA_DOCUMENTS_SERVICE (object)->priv;
304
switch (property_id) {
305
case PROP_SPREADSHEET_SERVICE:
306
g_value_set_object (value, priv->spreadsheet_service);
309
/* We don't have any other property... */
310
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
249
/* Nothing to see here */
253
get_authorization_domains (void)
255
GList *authorization_domains = NULL;
257
authorization_domains = g_list_prepend (authorization_domains, get_documents_authorization_domain ());
258
authorization_domains = g_list_prepend (authorization_domains, get_spreadsheets_authorization_domain ());
260
return authorization_domains;
316
264
* gdata_documents_service_new:
317
* @client_id: your application's client ID
265
* @authorizer: (allow-none): a #GDataAuthorizer to authorize the service's requests, or %NULL
319
* Creates a new #GDataDocumentsService. The @client_id must be unique for your application, and as registered with Google.
267
* Creates a new #GDataDocumentsService using the given #GDataAuthorizer. If @authorizer is %NULL, all requests are made as an unauthenticated user.
321
269
* Return value: a new #GDataDocumentsService, or %NULL; unref with g_object_unref()
325
273
GDataDocumentsService *
326
gdata_documents_service_new (const gchar *client_id)
274
gdata_documents_service_new (GDataAuthorizer *authorizer)
328
g_return_val_if_fail (client_id != NULL, NULL);
276
g_return_val_if_fail (authorizer == NULL || GDATA_IS_AUTHORIZER (authorizer), NULL);
330
278
return g_object_new (GDATA_TYPE_DOCUMENTS_SERVICE,
331
"client-id", client_id,
279
"authorizer", authorizer,
284
* gdata_documents_service_get_primary_authorization_domain:
286
* The primary #GDataAuthorizationDomain for interacting with Google Documents. This will not normally need to be used, as it's used internally
287
* by the #GDataDocumentsService methods. However, if using the plain #GDataService methods to implement custom queries or requests which libgdata
288
* does not support natively, then this domain may be needed to authorize the requests.
290
* The domain never changes, and is interned so that pointer comparison can be used to differentiate it from other authorization domains.
292
* Return value: (transfer none): the service's authorization domain
296
GDataAuthorizationDomain *
297
gdata_documents_service_get_primary_authorization_domain (void)
299
return get_documents_authorization_domain ();
303
* gdata_documents_service_get_spreadsheet_authorization_domain:
305
* The #GDataAuthorizationDomain for interacting with spreadsheet data. This will not normally need to be used, as it's automatically used internally
306
* by the #GDataDocumentsService methods. However, if using the plain #GDataService methods to implement custom queries or requests which libgdata
307
* does not support natively, then this domain may be needed to authorize the requests which pertain to the Google Spreadsheets Data API, such as
308
* requests to download or upload spreadsheet documents.
310
* The domain never changes, and is interned so that pointer comparison can be used to differentiate it from other authorization domains.
312
* Return value: (transfer none): the service's authorization domain
316
GDataAuthorizationDomain *
317
gdata_documents_service_get_spreadsheet_authorization_domain (void)
319
return get_spreadsheets_authorization_domain ();
336
323
* gdata_documents_service_query_documents:
337
324
* @self: a #GDataDocumentsService
338
325
* @query: (allow-none): a #GDataDocumentsQuery with the query parameters, or %NULL
339
* @cancellable: optional #GCancellable object, or %NULL
340
* @progress_callback: (scope call): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
326
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
327
* @progress_callback: (allow-none) (scope call) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
341
328
* @progress_user_data: (closure): data to pass to the @progress_callback function
342
329
* @error: a #GError, or %NULL
377
365
request_uri = g_strconcat (_gdata_service_get_scheme (), "://docs.google.com/feeds/documents/private/full", NULL);
379
feed = gdata_service_query (GDATA_SERVICE (self), request_uri, GDATA_QUERY (query), GDATA_TYPE_DOCUMENTS_ENTRY, cancellable,
380
progress_callback, progress_user_data, error);
367
feed = gdata_service_query (GDATA_SERVICE (self), get_documents_authorization_domain (), request_uri, GDATA_QUERY (query),
368
GDATA_TYPE_DOCUMENTS_ENTRY, cancellable, progress_callback, progress_user_data, error);
381
369
g_free (request_uri);
383
371
return GDATA_DOCUMENTS_FEED (feed);
387
* gdata_documents_service_query_documents_async: (skip)
375
* gdata_documents_service_query_documents_async:
388
376
* @self: a #GDataDocumentsService
389
377
* @query: (allow-none): a #GDataDocumentsQuery with the query parameters, or %NULL
390
* @cancellable: optional #GCancellable object, or %NULL
391
* @progress_callback: a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
392
* @progress_user_data: data to pass to the @progress_callback function
378
* @cancellable: (allow-none): optional #GCancellable object, or %NULL
379
* @progress_callback: (allow-none) (closure progress_user_data): a #GDataQueryProgressCallback to call when an entry is loaded, or %NULL
380
* @progress_user_data: (closure): data to pass to the @progress_callback function
381
* @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
382
* called with @progress_user_data as a parameter and can be used to free any memory allocated for it.
393
383
* @callback: a #GAsyncReadyCallback to call when authentication is finished
394
384
* @user_data: (closure): data to pass to the @callback function
414
405
g_return_if_fail (callback != NULL);
416
407
/* Ensure we're authenticated first */
417
if (gdata_service_is_authenticated (GDATA_SERVICE (self)) == FALSE) {
418
g_simple_async_report_error_in_idle (G_OBJECT (self), callback, user_data,
419
GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED,
420
_("You must be authenticated to query documents."));
408
if (gdata_authorizer_is_authorized_for_domain (gdata_service_get_authorizer (GDATA_SERVICE (self)),
409
get_documents_authorization_domain ()) == FALSE) {
410
GSimpleAsyncResult *result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, gdata_service_query_async);
411
g_simple_async_result_set_error (result, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED, "%s",
412
_("You must be authenticated to query documents."));
413
g_simple_async_result_complete_in_idle (result);
414
g_object_unref (result);
424
419
request_uri = g_strconcat (_gdata_service_get_scheme (), "://docs.google.com/feeds/documents/private/full", NULL);
425
gdata_service_query_async (GDATA_SERVICE (self), request_uri, GDATA_QUERY (query), GDATA_TYPE_DOCUMENTS_ENTRY,
426
cancellable, progress_callback, progress_user_data, callback, user_data);
420
gdata_service_query_async (GDATA_SERVICE (self), get_documents_authorization_domain (), request_uri, GDATA_QUERY (query),
421
GDATA_TYPE_DOCUMENTS_ENTRY, cancellable, progress_callback, progress_user_data,
422
destroy_progress_user_data, callback, user_data);
427
423
g_free (request_uri);
431
* To upload spreadsheet documents, another token is needed since the service for it is "wise" as apposed to "writely" for other operations.
432
* This callback aims to authenticate to this service as a private property (@priv->spreadsheet_service) of #GDataDocumentsService.
435
notify_authenticated_cb (GObject *service, GParamSpec *pspec, GObject *self)
437
GDataService *spreadsheet_service;
438
GDataDocumentsServicePrivate *priv = GDATA_DOCUMENTS_SERVICE (service)->priv;
440
if (priv->spreadsheet_service != NULL)
441
g_object_unref (priv->spreadsheet_service);
443
spreadsheet_service = g_object_new (GDATA_TYPE_SERVICE, "client-id", gdata_service_get_client_id (GDATA_SERVICE (service)), NULL);
444
GDATA_SERVICE_GET_CLASS (spreadsheet_service)->service_name = "wise";
445
gdata_service_authenticate (spreadsheet_service, gdata_service_get_username (GDATA_SERVICE (service)),
446
gdata_service_get_password (GDATA_SERVICE (service)), NULL, NULL);
447
priv->spreadsheet_service = spreadsheet_service;
450
/* Sets the proxy on @spreadsheet_service when it is set on the service */
452
notify_proxy_uri_cb (GObject *service, GParamSpec *pspec, GObject *self)
456
if (GDATA_DOCUMENTS_SERVICE (self)->priv->spreadsheet_service == NULL)
459
proxy_uri = gdata_service_get_proxy_uri (GDATA_SERVICE (service));
460
gdata_service_set_proxy_uri (GDATA_DOCUMENTS_SERVICE (self)->priv->spreadsheet_service, proxy_uri);
463
426
static GDataUploadStream *
464
427
upload_update_document (GDataDocumentsService *self, GDataDocumentsDocument *document, const gchar *slug, const gchar *content_type,
465
428
const gchar *method, const gchar *upload_uri, GCancellable *cancellable)
890
857
g_assert (entry_id != NULL);
892
859
if (GDATA_IS_DOCUMENTS_PRESENTATION (entry)) {
893
uri = _gdata_service_build_uri (FALSE, "http://docs.google.com/feeds/folders/private/full/folder%%3A%s/presentation%%3A%s",
860
uri = _gdata_service_build_uri ("http://docs.google.com/feeds/folders/private/full/folder%%3A%s/presentation%%3A%s",
894
861
folder_id, entry_id);
895
862
} else if (GDATA_IS_DOCUMENTS_SPREADSHEET (entry)) {
896
uri = _gdata_service_build_uri (FALSE, "http://docs.google.com/feeds/folders/private/full/folder%%3A%s/spreadsheet%%3A%s",
863
uri = _gdata_service_build_uri ("http://docs.google.com/feeds/folders/private/full/folder%%3A%s/spreadsheet%%3A%s",
897
864
folder_id, entry_id);
898
865
} else if (GDATA_IS_DOCUMENTS_TEXT (entry)) {
899
uri = _gdata_service_build_uri (FALSE, "http://docs.google.com/feeds/folders/private/full/folder%%3A%s/document%%3A%s",
866
uri = _gdata_service_build_uri ("http://docs.google.com/feeds/folders/private/full/folder%%3A%s/document%%3A%s",
900
867
folder_id, entry_id);
901
868
} else if (GDATA_IS_DOCUMENTS_FOLDER (entry)) {
902
uri = _gdata_service_build_uri (FALSE, "http://docs.google.com/feeds/folders/private/full/folder%%3A%s/folder%%3A%s",
869
uri = _gdata_service_build_uri ("http://docs.google.com/feeds/folders/private/full/folder%%3A%s/folder%%3A%s",
903
870
folder_id, entry_id);
905
872
g_assert_not_reached ();
908
message = _gdata_service_build_message (GDATA_SERVICE (self), SOUP_METHOD_DELETE, uri, gdata_entry_get_etag (GDATA_ENTRY (entry)), TRUE);
875
message = _gdata_service_build_message (GDATA_SERVICE (self), get_documents_authorization_domain (), SOUP_METHOD_DELETE, uri,
876
gdata_entry_get_etag (GDATA_ENTRY (entry)), TRUE);
911
879
/* Send the message */