class Demo {
private DocumentsService service = null;
public Demo() {
service = new DocumentsService("google-DocUpdateTip-v1");
service.setUserCredentials("username@gmail.com", "pa$$word");
GDataGAuthRequestFactory reqFactory = (GDataGAuthRequestFactory)service.RequestFactory;
reqFactory.ProtocolMajor = 3;
}
static void Main(string[] args) {
Demo demo = new Demo();
// Fetch only documents
DocumentsListQuery query = new DocumentsListQuery("http://docs.google.com/feeds/default/private/full/-/document");
DocumentsFeed doclistFeed = demo.service.Query(query);
// Update first document found
DocumentEntry entry = (DocumentEntry)doclistFeed.Entries[0];
Console.WriteLine("Updating " + entry.Title.Text + "...");
DocumentEntry updatedEntry = demo.UpdateDocContents(entry, "C:/Documents and Settings/replacement.doc");
Console.WriteLine(entry.Title.Text + " Updated!, view at " + entry.AlternateUri.ToString());
}
public DocumentEntry UpdateDocContents(DocumentEntry entryToUpdate, String replacementFileName) {
FileInfo fileInfo = new FileInfo(replacementFileName);
FileStream stream = fileInfo.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
DocumentEntry entry = null;
try {
// Convert the extension to caps and strip the "." off the front
String ext = fileInfo.Extension.ToUpper().Substring(1);
String contentType = (String)DocumentsService.GDocumentsAllowedTypes[ext];
if (contentType == null) {
throw new ArgumentException("File extension '" + ext + "' is not recognized as valid.");
}
// Set ETag because we're making an update
GDataRequestFactory factory = (GDataRequestFactory)service.RequestFactory;
factory.CustomHeaders.Add("If-Match: " + entryToUpdate.Etag);
Uri mediaUri = new Uri(entryToUpdate.MediaUri.ToString());
entry = service.Update(mediaUri, stream, contentType, entryToUpdate.Title.Text) as DocumentEntry;
} finally {
stream.Close();
}
return entry;
}
}
Update a document's content in .NET
Create a new Google Docs Spreadsheet from content using AJAX
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"
type="text/javascript"></script>
<script type="text/javascript">
var token = 'YOUR_CLIENTLOGIN_AUTH_TOKEN';
function constructContentBody(docTitle, docType, contentBody, contentType) {
var atom = ["<?xml version='1.0' encoding='UTF-8'?>",
'<entry xmlns="http://www.w3.org/2005/Atom">',
'<category scheme="http://schemas.google.com/g/2005#kind"',
' term="http://schemas.google.com/docs/2007#', docType, '"/>',
'<title>', docTitle, '</title>',
'</entry>'].join('');
var body = ['--END_OF_PART\r\n',
'Content-Type: application/atom+xml;\r\n\r\n',
atom, '\r\n',
'--END_OF_PART\r\n',
'Content-Type: ', contentType, '\r\n\r\n',
contentBody, '\r\n',
'--END_OF_PART--\r\n'].join('');
return body;
}
function createSpreadsheetFromContent(title, content, contentType) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
$.ajax({
type: 'POST',
url: 'http://docs.google.com/feeds/documents/private/full',
contentType: 'multipart/related; boundary=END_OF_PART',
data: constructContentBody(title, 'spreadsheet', content, contentType),
dataType: 'xml',
beforeSend: function(xhr) {
$('#data').html('uploading...');
xhr.setRequestHeader('Authorization', 'GoogleLogin auth=' + token);
},
success: function(resp) {
$('#data').html('Spreadsheet created!');
}
});
}
</script>
</head>
<body>
<div id="data"></div>
<button onclick="createSpreadsheetFromContent('ANewTitle', '1,2,3,4', 'text/csv')">Create spreadsheet w/ content</button>
</body>
</html>
Download a Google Doc using the PHP library
At the time of writing this tip, the Zend_Gdata_Docs component of the PHP library does not contain the export/download functionality of the DocList API. Here is an example of using AuthSub and file_get_contents() to download a document as a .txt file:
function download($client, $url, $format=null) {
$sessionToken = $client->getHttpClient()->getAuthSubToken();
$opts = array(
'http' => array(
'method' => 'GET',
'header' => "GData-Version: 3.0\r\n".
"Authorization: AuthSub token=\"$sessionToken\"\r\n"
)
);
if ($url != null) {
$url = $url . "&exportFormat=$format";
}
return file_get_contents($url, false, stream_context_create($opts));
}
// TODO 1: setup a Zend_Gdata_Docs client in $docs_client
// TODO 2: fetch a $feed or $entry
$contentLink = $feed->entries[0]->content->getSrc();
$fileContents = download($docs_client, $contentLink, 'txt');
echo 'Contents of document "' . $feed->entries[0]->title . '":<hr>';
echo "<pre>$fileContents</pre>";
OAuth in Google App Engine
This sample demonstrates a basic structure that you can use to perform 3-legged OAuth using the Google Data Python client library in Google App Engine. This particular example talks to the Documents List Data API.
Note: The sample is available in two versions, one that signs requests with RSA-SHA1 and another that signs with HMAC-SHA1.Retrieving a document's content URL in Java
List<DocumentListEntry> entries = resultFeed.getEntries();
for (DocumentListEntry entry : entries) {
MediaContent content = (MediaContent)entry.getContent();
System.out.println("View '" + entry.getTitle().getPlainText() + "' at " + content.getUri());
}
Geo-Tagging a Picasa Photo in PHP
$gp->registerPackage('Zend_Gdata_Geo');
$gp->registerPackage('Zend_Gdata_Geo_Extension');
$where = $gp->newGeoRssWhere();
$position = $gp->newGmlPos('37.0 -122.0');
$where->point = $gp->newGmlPoint($position);
$photoEntry->setGeoRssWhere($where);
Constructing unsupported XML elements using the PHP client library
When a new XML element is introduced, client library support needs to be added. At times, the services move a bit faster than the client libraries. This means that (as per the AtomPub spec) clients must store all unknown elements returned from the server. Clients may also wish to be able to use new functionality which isn't explicitly supported yet in the libraries, so clients can allow you to create arbitrary XML elements and attach them to entries.
The PHP client library accomplishes this using extension elements, represented as instances of Zend_Gdata_App_Extension_Element. Each time the server returns an element that is unknown to the client library, the client creates an instance of that class and stores it in the extensionElements array of the class representing the parent element. In order to send arbitrary XML, you can also construct a new Zend_Gdata_App_Extension_Element and place it in the extensionElements array.
As an example, Google Base added a publishing priority option, specified by adding a <gm:publishing_priority> element. At the time of this post, the element isn't supported by a class in the PHP client library, so here's how you can add it.
<?php
require_once 'Zend/Gdata/Gbase.php';
require_once 'Zend/Gdata/App/Extension/Element.php';
$base = new Zend_Gdata_Gbase();
$entry = $base->newItemEntry();
// Constructing a Zend_Gdata_App_Extension_Control
$control = $base->newControl();
// Constructing the extension element, and placing it into the array
// of extension owned by the class representing the parent app:control element.
// Arguments:
// element name (including prefix)
// namespace prefix
// namespace URI
// text node of the new element
$control->extensionElements = array(
new Zend_Gdata_App_Extension_Element('gm:publishing_priority', 'gm', 'http://base.google.com/ns-metadata/1.0', 'high')
);
$entry->control = $control;
Of course, if you discover missing elements, please feel free to file an issue in the Zend Framework issue tracker and, since it's open source, you can also contribute a fix back to the project. More information on contributing can be found on the Zend Framework wiki.