## GDataDocumentsDocument GDataDocumentsDocument — GData documents document object |

## Stability Level

Unstable, unless otherwise indicated

## Synopsis

    #include <gdata/services/documents/gdata-documents-document.h>

                        GDataDocumentsDocument;
                        GDataDocumentsDocumentClass;
    GDataDocumentsDocument * gdata_documents_document_new   (const gchar *id);
    GDataDownloadStream * gdata_documents_document_download (GDataDocumentsDocument *self,
                                                             GDataDocumentsService *service,
                                                             const gchar *export_format,
                                                             GCancellable *cancellable,
                                                             GError **error);
    gchar *             gdata_documents_document_get_download_uri
                                                            (GDataDocumentsDocument *self,
                                                             const gchar *export_format);
    const gchar *       gdata_documents_document_get_thumbnail_uri
                                                            (GDataDocumentsDocument *self);

## Object Hierarchy

      GObject
       +----GDataParsable
             +----GDataEntry
                   +----GDataDocumentsEntry
                         +----GDataDocumentsDocument
                               +----GDataDocumentsDrawing
                               +----GDataDocumentsPresentation
                               +----GDataDocumentsSpreadsheet
                               +----GDataDocumentsText

## Implemented Interfaces

GDataDocumentsDocument implements GDataAccessHandler.

## Description

GDataDocumentsDocument is a subclass of GDataDocumentsEntry to represent an arbitrary Google Documents document (i.e. an arbitrary file which isn't a Google Documents presentation, text document, drawing or spreadsheet). It is subclassed by GDataDocumentsPresentation, GDataDocumentsText, GDataDocumentsDrawing and GDataDocumentsSpreadsheet, which represent those specific types of Google Document, respectively.

GDataDocumentsDocument used to be abstract, but was made instantiable in version 0.13.0 to allow for arbitrary file uploads. This can be achieved by setting "convert" to `FALSE` when making an upload using `gdata_documents_service_upload_document_resumable()`. See the documentation for GDataDocumentsUploadQuery for an example.

It should be noted that GDataDocumentsDocument should only be used to represent arbitrary files; its subclasses should be used any time a standard Google Document (spreadsheet, text document, presentation, etc.) is to be represented.

For more details of Google Documents' GData API, see the online documentation.

Example 33. Downloading a Document

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    GDataDocumentsService *service;
    GDataDocumentsDocument *document;
    GFile *destination_file;
    const gchar *download_format;
    GDataDownloadStream *download_stream;
    GFileOutputStream *output_stream;
    GError *error = NULL;

    /* Create a service and retrieve the document to download and the file and format to save the download in */
    service = create_youtube_service ();
    document = get_document_to_download (service);
    destination_file = query_user_for_destination_file (document);
    download_format = query_user_for_download_format (document);

    /* Create the download stream */
    download_stream = gdata_documents_document_download (document, service, download_format, NULL, &error);

    g_object_unref (document);
    g_object_unref (service);

    if (error != NULL) {
        g_error ("Error creating download stream: %s", error->message);
        g_error_free (error);
        g_object_unref (destination_file);
        return;
    }

    /* Create the file output stream */
    output_stream = g_file_replace (destination_file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &error);

    g_object_unref (destination_file);

    if (error != NULL) {
        g_error ("Error creating destination file: %s", error->message);
        g_error_free (error);
        g_object_unref (download_stream);
        return;
    }

    /* Download the document. This should almost always be done asynchronously. */
    g_output_stream_splice (G_OUTPUT_STREAM (output_stream), G_INPUT_STREAM (download_stream),
                            G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET, NULL, &error);

    g_object_unref (output_stream);
    g_object_unref (download_stream);

    if (error != NULL) {
        g_error ("Error downloading document: %s", error->message);
        g_error_free (error);
        return;
    }

Each document accessible through the service has an access control list (ACL) which defines the level of access to the document to each user, and which users the document is shared with. For more information about ACLs for documents, see the online documentation on sharing documents.

Example 34. Retrieving the Access Control List for a Document

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    GDataDocumentsService *service;
    GDataDocumentsDocument *document;
    GDataFeed *acl_feed;
    GDataAccessRule *rule, *new_rule;
    GDataLink *acl_link;
    GList *i;
    GError *error = NULL;

    /* Create a service and retrieve a document to work on */
    service = create_documents_service ();
    document = get_document (service);

    /* Query the service for the ACL for the given document */
    acl_feed = gdata_access_handler_get_rules (GDATA_ACCESS_HANDLER (document), GDATA_SERVICE (service), NULL, NULL, NULL, &error);

    if (error != NULL) {
        g_error ("Error getting ACL feed for document: %s", error->message);
        g_error_free (error);
        g_object_unref (document);
        g_object_unref (service);
        return;
    }

    /* Iterate through the ACL */
    for (i = gdata_feed_get_entries (acl_feed); i != NULL; i = i->next) {
        const gchar *scope_value;

        rule = GDATA_ACCESS_RULE (i->data);

        /* Do something with the access rule here. As an example, we update the rule applying to test@gmail.com and delete all
         * the other rules. We then insert another rule for example@gmail.com below. */
        gdata_access_rule_get_scope (rule, NULL, &scope_value);
        if (scope_value != NULL && strcmp (scope_value, "test@gmail.com") == 0) {
            GDataAccessRule *updated_rule;

            /* Update the rule to make test@gmail.com a writer (full read/write access to the document, but they can't change
             * the ACL or delete the document). */
            gdata_access_rule_set_role (rule, GDATA_DOCUMENTS_ACCESS_ROLE_WRITER);
            updated_rule = GDATA_ACCESS_RULE (gdata_service_update_entry (GDATA_SERVICE (service), GDATA_ENTRY (rule), NULL, &error));

            if (error != NULL) {
                g_error ("Error updating access rule for %s: %s", scope_value, error->message);
                g_error_free (error);
                g_object_unref (acl_feed);
                g_object_unref (document);
                g_object_unref (service);
                return;
            }

            g_object_unref (updated_rule);
        } else {
            /* Delete any rule which doesn't apply to test@gmail.com */
            gdata_service_delete_entry (GDATA_SERVICE (service), GDATA_ENTRY (rule), NULL, &error);

            if (error != NULL) {
                g_error ("Error deleting access rule for %s: %s", scope_value, error->message);
                g_error_free (error);
                g_object_unref (acl_feed);
                g_object_unref (document);
                g_object_unref (service);
                return;
            }
        }
    }

    g_object_unref (acl_feed);

    /* Create and insert a new access rule for example@gmail.com which allows them read-only access to the document. */
    rule = gdata_access_rule_new (NULL);
    gdata_access_rule_set_role (rule, GDATA_DOCUMENTS_ACCESS_ROLE_READER);
    gdata_access_rule_set_scope (rule, GDATA_ACCESS_SCOPE_USER, "example@gmail.com");

    acl_link = gdata_entry_look_up_link (GDATA_ENTRY (document), GDATA_LINK_ACCESS_CONTROL_LIST);
    new_rule = GDATA_ACCESS_RULE (gdata_service_insert_entry (GDATA_SERVICE (service), gdata_link_get_uri (acl_link), GDATA_ENTRY (rule),
                                                              NULL, &error));

    g_object_unref (rule);
    g_object_unref (document);
    g_object_unref (service);

    if (error != NULL) {
        g_error ("Error inserting access rule: %s", error->message);
        g_error_free (error);
        return;
    }

    g_object_unref (acl_link);

## Details

### GDataDocumentsDocument

    typedef struct _GDataDocumentsDocument GDataDocumentsDocument;

All the fields in the GDataDocumentsDocument structure are private and should never be accessed directly.

Since 0.7.0

### GDataDocumentsDocumentClass

    typedef struct {
    } GDataDocumentsDocumentClass;

All the fields in the GDataDocumentsDocumentClass structure are private and should never be accessed directly.

Since 0.7.0

### gdata_documents_document_new ()

    GDataDocumentsDocument * gdata_documents_document_new   (const gchar *id);

Creates a new GDataDocumentsDocument with the given entry ID ("id").

`id` : | the entry's ID (not the document ID), or `NULL`. [allow-none]
Returns : | a new GDataDocumentsDocument, or `NULL`; unref with `g_object_unref()`. [transfer full]

Since 0.13.0

### gdata_documents_document_download ()

    GDataDownloadStream * gdata_documents_document_download (GDataDocumentsDocument *self,
                                                             GDataDocumentsService *service,
                                                             const gchar *export_format,
                                                             GCancellable *cancellable,
                                                             GError **error);

Downloads and returns the document file represented by the GDataDocumentsDocument. If the document doesn't exist, `NULL` is returned, but no error is set in `error`.

`export_format` should be the file extension of the desired output format for the document, from the list accepted by Google Documents. For example: `GDATA_DOCUMENTS_PRESENTATION_PDF`, `GDATA_DOCUMENTS_SPREADSHEET_ODS` or `GDATA_DOCUMENTS_TEXT_ODT`.

If `self` is a GDataDocumentsSpreadsheet, only the first grid, or sheet, in the spreadsheet will be downloaded for some export formats. To download a specific a specific grid, use `gdata_documents_spreadsheet_get_download_uri()` with GDataDownloadStream to download the grid manually. See the GData protocol specification for more information.

To get the content type of the downloaded file, `gdata_download_stream_get_content_type()` can be called on the returned GDataDownloadStream. Calling `gdata_download_stream_get_content_length()` on the stream will not return a meaningful result, however, as the stream is encoded in chunks, rather than by content length.

In order to cancel the download, a GCancellable passed in to `cancellable` must be cancelled using `g_cancellable_cancel()`. Cancelling the individual GInputStream operations on the GDataDownloadStream will not cancel the entire download; merely the read or close operation in question. See the "cancellable" for more details.

If `service` isn't authenticated, a `GDATA_SERVICE_ERROR_AUTHENTICATION_REQUIRED` will be returned.

If there is an error getting the document, a `GDATA_SERVICE_ERROR_PROTOCOL_ERROR` error will be returned.

`self` : | a GDataDocumentsDocument
`service` : | a GDataDocumentsService
`export_format` : | the format in which the document should be exported
`cancellable` : | a GCancellable for the entire download stream, or `NULL`. [allow-none]
`error` : | a GError, or `NULL`
Returns : | a GDataDownloadStream to download the document with, or `NULL`; unref with `g_object_unref()`. [transfer full]

Since 0.8.0

### gdata_documents_document_get_download_uri ()

    gchar *             gdata_documents_document_get_download_uri
                                                            (GDataDocumentsDocument *self,
                                                             const gchar *export_format);

Builds and returns the download URI for the given GDataDocumentsDocument in the desired format. Note that directly downloading the document using this URI isn't possible, as authentication is required. You should instead use `gdata_download_stream_new()` with the URI, and use the resulting GInputStream.

`export_format` should be the file extension of the desired output format for the document, from the list accepted by Google Documents. For example: `GDATA_DOCUMENTS_PRESENTATION_PDF`, `GDATA_DOCUMENTS_SPREADSHEET_ODS` or `GDATA_DOCUMENTS_TEXT_ODT`.

`self` : | a GDataDocumentsDocument
`export_format` : | the format in which the document should be exported when downloaded
Returns : | the download URI; free with `g_free()`

Since 0.7.0

### gdata_documents_document_get_thumbnail_uri ()

    const gchar *       gdata_documents_document_get_thumbnail_uri
                                                            (GDataDocumentsDocument *self);

Gets the URI of the thumbnail for the GDataDocumentsDocument. If no thumbnail exists for the document, `NULL` will be returned.

The thumbnail may then be downloaded using a GDataDownloadStream.

Example 35. Downloading a Document Thumbnail

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    GDataDocumentsService *service;
    const gchar *thumbnail_uri;
    GCancellable *cancellable;
    GdkPixbuf *pixbuf;
    GError *error = NULL;

    service = get_my_documents_service ();
    thumbnail_uri = gdata_documents_document_get_thumbnail_uri (my_document);
    cancellable = g_cancellable_new ();

    /* Prepare a download stream */
    download_stream = GDATA_DOWNLOAD_STREAM (gdata_download_stream_new (GDATA_SERVICE (service), NULL, thumbnail_uri, cancellable));

    /* Download into a new GdkPixbuf. This can be cancelled using 'cancellable'. */
    pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (download_stream), NULL, &error);

    if (error != NULL) {
        /* Handle the error. */
        g_error_free (error);
    }

    g_object_unref (download_stream);
    g_object_unref (cancellable);

    /* Do something with the GdkPixbuf. */

    g_object_unref (pixbuf);

`self` : | a GDataDocumentsDocument
Returns : | the URI of the document's thumbnail, or `NULL`. [allow-none]

Since 0.13.1