Friday, March 28, 2008

Google's GData Java API

This has been out for a while, but I recently realized that Google's GData API provides a way to interact with all Google services (Doc, Calendar, YouTube, Blogger, Picasso, etc) through your own server side code. One nice application for Science Gateways is to write a Web Service that submits grid jobs, writes service state changes to Google Calendar, spits out result synopsis to a blog, and posts visualizations to Picasso or YouTube.

Below is some code liberally borrowed from Blogger, YouTube, and Calendar API gdata examples to show how simple this is. Some notes:


--------------------
Code example below
--------------------
import com.google.gdata.client.*;
import com.google.gdata.client.youtube.*;
import com.google.gdata.data.*;
import com.google.gdata.data.geo.impl.*;
import com.google.gdata.data.media.*;
import com.google.gdata.data.media.mediarss.*;
import com.google.gdata.data.youtube.*;
import com.google.gdata.data.extensions.*;
import com.google.gdata.util.*;

import com.google.gdata.client.*;
import com.google.gdata.data.*;
import com.google.gdata.util.*;
import java.io.IOException;
import java.net.URL;
import java.util.*;

//Google Calendar stuff
import com.google.gdata.client.calendar.*;
import com.google.gdata.data.acl.*;
import com.google.gdata.data.calendar.*;
import com.google.gdata.data.extensions.*;

public class TestBlogger {
String clientID="XXXXX";
String developer_key="XXXXXXX";

String feedUrl="http://gdata.youtube.com/feeds/api/videos/";
String scarFace5sec="http://gdata.youtube.com/feeds/api/videos/egwB7hVIIEc";

GoogleService googleService;
YouTubeService youTubeService;
CalendarService calendarService;

public GoogleService getGoogleService() {
return googleService;
}
public void setGoogleService(GoogleService googleService) {
this.googleService=googleService;
}

public YouTubeService getYouTubeService() {
return youTubeService;
}

public void setYouTubeService(YouTubeService youTubeService) {
this.youTubeService=youTubeService;
}

public void setCalendarService(CalendarService calendarService) {
this.calendarService=calendarService;
}

public CalendarService getCalendarService() {
return this.calendarService;
}

public TestBlogger() throws Exception {
//Replace these with real values.
String userName="me@gmail.com";
String password= "qwerty";

//Log into blogger.
GoogleService myService=new GoogleService("blogger","");
myService.setUserCredentials(userName,password);
setGoogleService(myService);

//Log into YouTube
YouTubeService service = new YouTubeService(clientID, developer_key);
service.setUserCredentials(userName,password);
setYouTubeService(service);

//Log into Calendar
CalendarService calService=new CalendarService(clientID);
calService.setUserCredentials(userName,password);
setCalendarService(calService);
}

public void writeToCalendar(String titleOfEvent,
String contentToPost) throws Exception {
URL postUrl =
new URL("http://www.google.com/calendar/feeds/"+userName+"/private/full");
CalendarEventEntry myEntry = new CalendarEventEntry();

myEntry.setTitle(new PlainTextConstruct(titleOfEvent));
myEntry.setContent(new PlainTextConstruct(contentToPost));

// DateTime startTime = DateTime.parseDateTime("2008-03-18T15:00:00-08:00");
System.out.println((new Date()).toString());
DateTime startTime = new DateTime(new Date());
// DateTime endTime = DateTime.parseDateTime("2008-03-18T17:00:00-08:00");
When eventTimes = new When();
eventTimes.setStartTime(startTime);
// eventTimes.setEndTime(endTime);
myEntry.addTime(eventTimes);

// Send the request and receive the response:
CalendarEventEntry insertedEntry = calendarService.insert(postUrl, myEntry);

CalendarEventEntry myEntry2 = new CalendarEventEntry();
String now=(new Date()).toString();
myEntry2.setContent(new PlainTextConstruct("Test post at "+now));
myEntry2.setQuickAdd(true);

// Send the request and receive the response:
CalendarEventEntry insertedEntry2 =calendarService.insert(postUrl, myEntry2);
}

public String getBloggerEntryString() throws Exception {
String returnString="";
URL feedUrl=new URL("http://communitygrids.blogspot.com/atom.xml");
Feed resultFeed = googleService.getFeed(feedUrl, Feed.class);

// Print the results
System.out.println(resultFeed.getTitle().getPlainText());
for (int i = 0; i < resultFeed.getEntries().size(); i++) { Entry entry = resultFeed.getEntries().get(i); returnString+=entry.getTitle().getPlainText()+"
";
}
return returnString;
}

public String getVideoFeedString() throws Exception {

String returnString;

VideoFeed videoFeed=youTubeService.getFeed(new URL(feedUrl),
VideoFeed.class);

VideoEntry videoEntry = youTubeService.getEntry(new URL(scarFace5sec),
VideoEntry.class);

returnString="Title: " + videoEntry.getTitle().getPlainText()+"
";
returnString+=videoEntry.getMediaGroup().getDescription().getPlainTextContent()+"
";
return returnString;
}

public Entry createPost(GoogleService myService, String blogID, String title,
String content, String authorName, String userName)
throws ServiceException, IOException {
// Create the entry to insert
Entry myEntry = new Entry();
myEntry.setTitle(new PlainTextConstruct(title));
myEntry.setContent(new PlainTextConstruct(content));
Person author = new Person(authorName, null, userName);
myEntry.getAuthors().add(author);

// Ask the service to insert the new entry
URL postUrl = new URL("http://www.blogger.com/feeds/" + blogID + "/posts/default");
return myService.insert(postUrl, myEntry);
}


public static void main(String[] args) throws Exception {
String blogId=1292929011;
String someName="test";

TestBlogger blog=new TestBlogger();
// System.out.println(blog.getBloggerEntryString());
// System.out.println(blog.getVideoFeedString());
String content="Some post test with the blogger Java api"+"
";
content=blog.getBloggerEntryString()+blog.getVideoFeedString();
blog.createPost(blog.getGoogleService(),
blogId,
"Testing Blogger API",
content,
"Marlon Pierce",
someName);
blog.writeToCalendar("Test Calendar Post",content);
}
}

3 comments:

Christopher Byrne said...

I like how clean your code is compared to a lot of the poorly documented gData samples on the Google site.

But I do have a couple of questions:

1. Why the multiple repeats of the import code lines (e.g. import com.google.gdata.client.*; and
import com.google.gdata.data.*;)?

2. My code is compiling but failing on execution, throwing this error:

Exception in thread "AgentThread: JavaAgent" java.lang.NoClassDefFoundError: com.google.gdata.client.GoogleService (initialization failure)at java.lang.J9VMInternals.initialize(J9VMInternals.java:140)
at BloggerInterface.(init)(BloggerInterface.java:31)


Have you seen this error?

Marlon Pierce said...

The multiple imports are just sloppy, probably. You can ignore them.

I have not seen the error in #2. After a little googling, it looks like it is associated with IBM's JVM. I did this with Sun's JDK, probably 1.5.

Spider said...

Nice article.
Could you also give an example on how to create and update a Calendar on google server. Had a look at google's example but dint like the "updating of calendar" part. It would help if you can give an example on how to use the "ID" or the "url" of the created calendar to update a calendar.