GCalendar: Accessing Google Calendar from JavaScript

Christian Decker wrote this in the late evening:

Introduction

Some weeks ago Google has added a nice new feature to their GData libraries: JSON data retrieval. This means that we now can retrieve data from some services of Google (Base, Blogger and Calendar for now) without having to proxy it through our servers (if you still don’t know, after thousands of posts about Cross-Domain issues, why you need to do this, just look here).

Why can we do this? Because we can just create a <script>-Element, points the src to the feed URL and tell the GData API what function to call upon load.

 
var headTag = document.getElementsByTagName('head')[0]; 
var script = document.createElement('script'); 
script.type = 'text/javascript'; 
script.src = feedurl; 
headTag.appendChild(script);

I was a bit sorry to see that Google doesn’t provide an API for Client side JavaScript. So once again, in one of those “don’t complain, do it better“-moments I figured it would be nice to write it myself for the Calendar. Off course some stuff can’t be done with JavaScript, we can only retrieve data, not submit new data to Google, so we can’t add new entries directly, but hey it’s a start :D

The library

We start off by modelling the Entry class, as you might easily figure out by the following code we rely on the Prototype library.

 
var EventEntry = Class.create();
EventEntry.prototype = {
	title: null,
	content: null,
	startDate: null,
	endDate: null,
	location: null,
	initialize: function(entry){
		this.title = entry.title.$t;
		this.content = entry.content.$t;
		this.startDate = DateConverter.rfc3339toDate(entry.gd$when[0].startTime);
		this.endDate = DateConverter.rfc3339toDate(entry.gd$when[0].endTime);
		this.location = entry.gd$where[0].valueString;
	}
};

Next we create a class that takes care of loading the feed, calling the callbacks and so on.

 
var Calendar = Class.create();
Calendar.prototype = {
	uri: "7cghno42lleqpbihmoi5qiikm8%40group.calendar.google.com",
	orderby: "starttime",
	singleEvents: true,
	futureEvents: true,
	sortOrder: "ascending",
	entries: {},
	initialize: function(u){
		if(u){this.uri = u;}
	},
	
	buildURL: function(){
		var str = "http://www.google.com/calendar/feeds/";
		str += this.uri;
		str += "/public/full-noattendees?orderby=" + this.orderby;
		str += "&alt=json-in-script&callback=window.activeCalendar.parseFeed&";
		str += "singleevents=" + this.singleEvents;
		str += "&sortorder=" + this.sortOrder;
		str += "&futureevents=" + this.futureEvents;
		return str;
	},
	
	loadFeed: function(){
		window.activeCalendar = this;
		var headTag = document.getElementsByTagName('head')[0]; 
		var script = document.createElement("script");
		script.src = this.buildURL();
		script.language = "JavaScript";
		headTag.appendChild(script);
	},
 
	parseFeed: function(json){
		e = json.feed.entry;
		for(var i=0;i < e.length;i++){
			this.entries[i] = new EventEntry(e[i])
		}
		try {
			this.onsuccess(this);
      } catch (e) {}
	},
	
	onsuccess: function(c){}
};

Notice the first line of the loadFeed? Yep, it’s a workaround, and an ugly one too. The problem is that we want to have access to the Calendar-object once we have the feed data. So we add it to the window-object. Anyway, this is the reason why you can load only one calendar at once.
And what would we be without some really ugly utility objects? So here you go, a pretty useless date converter class:

 
/**
 * Singleton object used to convert Dates from one format to another.
 */
var DateConverter = {
	rfc3339toDate: function(t){
		t = t.substr(0,19).replace(/-/g,"/").replace("T"," ");
		var dt = new Date();
		dt.setTime(Date.parse(t));
		return dt;
	}
};

So after all this code that you don’t have to write (because you can download it all here) now some code you have to write.

How to use it

I tried to keep it as simple as possible, if there are enough requests I may well extend it further, but for now it works nicely as it is. First you have to find out the feed identifier. Take the Feed URL as can be found in Google Calendar in the Calendar details and it will look something like this:

http://www.google.com/calendar/feeds/7cghno42lleqpbihmoi5qiikm8%40group.calendar.google.com/public/basic

Take the bold part and that’s the Feed Identifier that will then be used to create the instance of the Calendar:

 
var cal = new Calendar("7cghno42lleqpbihmoi5qiikm8%40group.calendar.google.com");

Next thing we need to do is add a callback function that is called once the Feed is loaded, and then kick the request off:

 
cal.onsuccess = function(c){alert(c);}
cal.loadFeed();

And that’s it :P
Now let’s see what we can do with it, and the reason I started fiddling with the Calendar in the first place. My custom frontend to one of my calendars can be seen here.

The main objective of advertising is to give detailed information about any kind of products in order to increase the number of potential customers. The dedicated servers provide the perfect managed web hosting solutions with great efficiency and productivity. You have a lot of opportunities to do work at home by surfing different freelancing jobs via internet. The application of website development software helps a lot to enhance the speed of web designers to develop new web designs. The internet advertising has opened a new horizon to run marketing campaigns on the large scale to have direct access to the extensive range of the customers. The wireless camera is designed by the implementation of the advanced technology of wireless networking system.

Reworked layout (once again)

Christian Decker wrote this in the wee hours:
So yeah, I thought that after all the trouble I had in the past with the layout I might just as well redo it all from scratch, and voila’ here it is :) Hope nothing’s broken, but if yes, just leave me a comment. It’s amazing what we can achieve with some CSS-Magic. I hope the next Annual Naked Day is soon because I’m ready for it. P.s.: It took only 1.5 hours to do it all :D

openSuse Linux 10.2

Christian Decker wrote this terribly early in the morning:
Guess what I’m doing at 3:20 AM on this fine holiday? Right, I’m installing one of my three machines, once again. This time one of the discs had an … uhm … fatal failure, actually it has a hole through it’s middle. Fortunately its on my testing server, which anyway has become so noisy due to the CPU-Fan lately that I have to turn it off at night, and no important data has been lost. Since I have to install it anyway I figured it would be nice to give the new version 10.2 of openSuse a try. At first I have to say, that not too much changed since version 10.1, but then why would you change something that is working fine? The enhancements are in the tiny details, my favorite being that they replaced the old (slow) Software Management tool they had in YaST with a much faster ZDM. But thinking about it, it may actually be just as slow as the old one, except that the new one shows me some activity, progress bars keep filling at incredible speed, and it feels faster, this is what Windows was always good at, letting the user believe something is happening (even if it’s not…). Good news for the show offs out there too: the really great Xgl and Compiz enhancements are contained in any standard installation, letting you make the Mac OS users cry, really really simple (those rain effects are just to die for). Great news for developers too: Eclipse is there with it’s Calisto 3.2 version, which I was really hoping for. Ok, by now the installation is finished and I’m looking forward to test it as a server, I’m already using the Desktop version for about a week on my development machine. Hope to see some of you in Linux-Land soon ^^

Sxip contributes Java and Perl libraries to OpenID 2.0

Christian Decker wrote this in the wee hours:
Some great news from the Sxip team, who recently released their a beta of their service Sxipper, have released two libraries for OpenID:
Licensed under an open source Apache 2.0 license, Sxip has released the OpenID4Java and OpenID4Perl libraries. The libraries are easy-to-use and well-documented, allowing you to add full support for OpenID 1.x, 2.0 and Attribute Exchange into your Java and Perl based applications. We invite you to try them out and would appreciate your feedback! We also welcome and encourage community participation around the ongoing development of these libraries. OpenID is an emerging Identity 2.0 authentication mechanism that enables users to maintain one login and password account for access to many sites. Package downloads for the latest version of the Java and Perl libraries for OpenID can be found on the distribution project page at code.sxip.com. In the coming weeks, we’ll update the library based on the progress of the OpenID Authentication 2.0 specification and we’re looking forward to working with others on the project!
I’m a huge fan of OpenID, and everything that helps implement the protocol easier is a step in the right direction.

Read all your mail in one place with Gmail Mail Fetcher

Christian Decker wrote this in the early evening:
gmail.pngGmail has added a feature that allows you to read mail from any other non-Gmail account within the Gmail interface. To say this is convenient is an understatement. Set-up looks like a snap, and you can add up to five non-Gmail accounts.I’ll be able to consolidate my Yahoo, Outlook, and Hotmail accounts within about five minutes flat if I’m lucky. For the privacy conscious, you can disable email archiving (it’s not set by default), and you can also disable importing non-Gmail mail anytime you want to very easily.