An Open XDrive Usage Meter Dashboard Widget

I always have trouble remembering three things: faces, names, and - I can't remember what the third thing is. - Fred Allen.

You won't have ANY memory issues with Open XDrive, in Jim Knowlton's recent post he explained why it's is so cool! In a nutshell - 5GB of online storage -- FREE!!!!

With online storage it would be useful to know how much you've used - and what's currently available. I've put together the beginnings of a Mac OS X Dahsboard Widget to do just that. You can see the Widget in action in Figure 1.

Figure 1. The Open XDrive Usage Meter Widget in action.

The Open XDrive API utilizes a JSON (JavaScript Object Notation) interface to programatically interact with storage. JSON returns data that can be evaluated into a JavaScript object. As I've discussed previously Dashboard Widgets are really standalone web pages, so the techniques discussed here can be employed in any AJAX application.

Before we can retrieve the user's usage information, we must authenticate against XDrive, and retrieve the MemberObject, using the member.login method. This is done in the loadUserData function shown in Listing 1. loadUserData takes two parameters, the username and password.

function loadUserData(username,password)
{
	// Member Login URL
	var feedURL = "http://plus.xdrive.com/json/v1.1/member.login";
	
	// Pass JSON Member Object Data
	var postData = 'data={"user":{"type":"MemberObject","username":"' + username + '","password":"' + password + '"}}';
	
	// Create XMLHttpRequest Object
	var xmlRequest = new XMLHttpRequest();
	
	// Open a POST request - false indicates we will do this synchronously
	xmlRequest.open("POST", feedURL, false);
	
	// Set Headers
	xmlRequest.setRequestHeader("Cache-Control", "no-cache");
        xmlRequest.setRequestHeader('Content-type','application/x-www-form-urlencoded'); 
	
	// Post Data
	xmlRequest.send(postData);

	// Check for successful POST
	if (xmlRequest.status == 200) {
	
	  // Evaluate JSON userdata
	  // We specifically will need the JSessionID...
	  userdata = ( "(" + xmlRequest.responseText + ")" ).evalJSON();
	}
}

Listing 1. The loadUserData function.

The member.login method is called using the XMLHttpRequest object which allows your web page to request and get a response from a web page without reloading. The MemberObject also contains the session id - which maintains your session information on the XDrive site. This session ID is returned as jsessionid in the MemberObject structure. Note the construction of the postData variable, data= precedes the MemberObject JSON structure. A JSON data structure is returned, which can be parsed into a JavaScript object using the evalJSON method of the Prototype JavaScript library (I've previously discussed the Prototype JavaScript Library here). On a successful post the status will be 200. The loadUserData function is called whenever the Widget is loaded.

Updated 12/17/07 - This code previously used the JavaScript eval function. The eval function presents some well-known security risks. The evalJSON() Prototype function throws an error if a syntax error in a malicious attempt or syntax error is detected - providing greater security.

Whenever the Widget is shown, the quota information is updated. This is done using the updateQuotaInfo function shown in Listing 2.

function updateQuotaInfo() 
{
	// Call the member.getquota method - we MUST append the prevuously retrieved jsessionid
	// Note jsessionid is lowercase and preceeded by a ; in the URL
	var feedURL = 'http://plus.xdrive.com/json/v1.1/member.getquota;jsessionid=' + userdata.jsessionid ;
	
	// No data required for getquota - empty JSON structure
	var postData = 'data={}';
	
	var xmlRequest = new XMLHttpRequest();

	// Open a POST request - false indicates we will do this synchronously
	xmlRequest.open("POST", feedURL, false);
	
	// Set Headers
	xmlRequest.setRequestHeader("Cache-Control", "no-cache");
        xmlRequest.setRequestHeader('Content-type','application/x-www-form-urlencoded'); 
	
	// Post Data
	xmlRequest.send(postData);  

	// Check for successful POST	
	if (xmlRequest.status == 200) {	
		// Retrieve UserQuotaObject by evaluating the returned JSON data
		UsageData = eval( "(" + xmlRequest.responseText + ")" );
		
		// Set the attributes for the gauge based on current usage
		gauge.object.setMinValue(0);
		gauge.object.setMaxValue(UsageData.quota.limit);
		gauge.object.setWarningValue(Math.floor(UsageData.quota.limit * 0.75));
		gauge.object.setCriticalValue(Math.floor(UsageData.quota.limit *0.90));
		gauge.object.setValue(UsageData.quota.used);
		
		// Display the current usage as text information
		document.getElementById("used").innerText = "Total Used: " + UsageData.quota.used + " bytes";
		document.getElementById("limit").innerText = "Quota: " + Math.floor(UsageData.quota.limit/1000) + " MB";
	}
}

Listing 2. The updateQuotaInfo function.

Please note this Widget was developed DashCode, which will be come a standard component in the Mac OS X Leopard release. The gauge used is a standard Dashcode Part.

To retrieve the quota information, the member.getquota method is called. Note that the jsessionid retrieved earlier is appended to the URL. jsessionid must be in lower case and and preceded by a ; The member.getquota method does require any other data, so an empty JSON structure is passed. A UserObject is returned. The quota structure is then used to populate the labels and set the gauge. The lower limit of the gauge is set to 0, and the upper limit is set to quota.limit which is the total space available. The needle is set to quota.used which is the amount of space currently is use. The warning and critical values are set for 75% and 90% usage respectively. When the warning level is reached the gauge automatically turns yellow, and it turns red when the critical level is reached. Finally, the labels are populated with the current usage and total space allocated.

Want to get started with the Open XDrive API? Here are some resources to begin your exploration:

This is currently based on the version 1.1 of the XDrive API, version 1.2 is right around the corner. Also, from what I've read in the XDrive API, the member.login was originally designed for AOL development testing. It does open a security risk as the username and password are passed unencrypted.

I'd welcome any input to improve the authentication! Please let me know what you think! What additional features would you like to see in this Widget?

Also check out Mark Blomsma's blog this week - http://dev.aol.com/node/649 where he develops a Vista version of this widget!

Interested in native Open XDrive access in Mac OS X - see my posting on The Cocoa Open XDrive Framework

Looks awesome!

Best stuff! Thx for sharing. I'll nlog about it on my site.

Best Regards
Lucas

Don't use eval!

Using eval to parse JSON data is a severly bad idea in general. It's a much worse idea in widgets, where the usual sandbox rules might have been relaxed.

The source of the JSON data might be subverted (or malicious), or somebody might have messed with your network connection. In either case, eval() means you hand them control of your account.

Use of Eval

I am going to have to agree with Roessler, it is generally a good idea to avoid code with a eval in it. The eval function translates any string into working JavaScript with no regards for security.

That said, eval is also very useful because it is such a simple way to translate JSON strings into JavaScript objects. We use it a lot for demo/example code where we want to focus on what the API is doing and not on the security or parsing aspects.

It has also is a great tool to wield when working on quick prototypes and proofs on concepts. Many web developers use eval as a quick way to start working with JSON from other sites.

But in each one of these cases, the developer has a specific reason to use eval and understands the risks. Using eval is a lot like acting on someone else's advice. If you are not sure that you trust the giver, don't take it! One school of thought says you can use eval if the string is coming from a trustworthy service, like AOL. But the web is more like taking advice via the telephone game. Some exploits can cause a browser to use the wrong server, so the client will think it is going to a trustworthy site like plus.xdrive.com, but instead will being getting malicious JSON from sneaky.com.

A safer alternative to eval is using a JSON specific parser, like one of the ones provided from json.org (http://json.org/json2.js). You can even go so far as to only use our API via SSL and verify identity by certs. But as with all things on the web, you should know your code and know your sources.

-l

Wanna such meter) Very

Wanna such meter) Very visual and pleasant looking))

----------------
Flexible houses

Cocoa Open XDrive Access...

Interested in native Open XDrive access in Mac OS X - see my posting on The Cocoa Open XDrive Framework

yeah!

This rocks! More mac xdrive stuff!!!

Colors...

You can't see the actual color settings in the posting - however when I set the warning level (at 75%) and critical level (at 90%) it turns the gauge to yellow and the red respectively, based on gauge properties, when your usage reaches those thresholds.

I also haven't played much with developing widgets in Vista - but I don't think it would be difficult to translate this code for that purpose. I don't believe Vista widgets can use JavaScript directly - so you'd have to translate the code to C# or VB.

The other big issue as I mention in the post is authentication - it currently is passing that in the clear to get a JSESSIONID - there needs to be a more secure way to authenticate.

Meter Color

This may seem like an odd question, but is it possible to change the color areas of the meter? The one end is green because you have lots of space left, but it would be nice if the other end were red to show a lack of space. In fact, it would be nice if the meter showed a progression from green to red. Obviously, the colors don't affect the usability of the meter, but they would provide a better visual.

Something that would be interesting is to see a PC version of this same widget for Vista. Is there any chance of seeing one in the future?

Leveraging The Code...

Brice -

I haven't really played with Boxley much - but from what I've seen it would seem possible to develop a version of this widget, leveraging what it already here. One of the current drawbacks with Boxley however is the lack of a formal IDE. I can't promise to get to one soon - but I'll keep it on my list - maybe someone will want to leverage what I have here and take up your challenge sooner!

Very cool

This is very cool John and actually quite useful. How about a Boxely version for the PC folks?