Introduction to the Open Xdrive API

by Kevin Farnham
September 21, 2007

Introduction

The Open Xdrive API is a component of the Xdrive Data Service Platform (XSDP). The API is a JSON interface that "allows developers to access the storage, services, and functions of the XDSP programatically via a set of web services."

The most important version 1.1 XSDP JSON API calls for constructing a basic Xdrive application are:

  • file.getlisting: Retrieves the list of directories and files for an Xdrive directory.
  • io.upload: Uploads a file from local storage to an Xdrive directory.
  • io.download: Download a file from an Xdrive directory to local storage.

In this introductory article, I'll briefly describe the Xdrive Data Service Platform; outline the structure of the three JSON API components listed above; demonstrate how to get started with the Xdrive API using a simple application; and preview the new features coming up in Xdrive API Version 1.2.

The Xdrive Data Service Platform

Xdrive.com provides users with 5GB of free online storage, with additional storage available for a fee. The site provides a convenient user interface for managing Xdrive files and directories, and uploading and downloading files. I signed up for an Xdrive account a while ago and blogged about it in my "Got My Free Xdrive" post.

I used my kevinfarnham1 AIM screen name as my Xdrive login. When I point my browser at Xdrive.com, log in, and click on "Manage My Xdrive," I'm presented with the following view of my Xdrive files and directories:

Online view of Xdrive files and directories
Figure 1. Online view of Xdrive files and directories (click the image for a larger version)

The Xdrive Data Service Platform provides developers access to the directories and files represented by the view in Figure 1.

The Xdrive JSON API

Xdrive API Authentication

The Getting Started with XDSP JSON v1.1 guide provides an introduction to XDSP and the JSON API. To do anything with the XSDP using a program, you need to authenticate the Xdrive account you'll be accessing. The Version 1.1 API does not have a fully featured authentication capability, though work on that is active and ongoing.

The simplest way to authenticate access to XDSP is to log into Xdrive using the Xdrive.com interface, and then run your application in that same browser instance (this could include another tab or new browser window created from the window where you logged into Xdrive). Logging into Xdrive.com saves a JSESSIONID cookie in your browser. The jsessionid variable in this cookie is read when you make JSON calls to the API, enabling programmatic access to that particular Xdrive account.

file.getlisting()

The file.getlisting() API call retrieves a directory listing for a user's Xdrive storage. The input parameter is an XDSP FileObject object that specifies the id parameter. An XDSP FileObject object's id represents the unique identifier for the file object. Leaving the id blank returns the data in the root (/) Xdrive directory.

Here's an example of a formatted JSON FileObject object, named srcFile, that could be sent as an input to file.getlisting(), requesting a listing of the files in a particular directory owned by the logged-in user:

{"srcFile":
   {"type":"FileObject",
   "id":"xdr:XFS-123456789"}
}

The response JSON output by file.getlisting provides a detailed description of each file and directory in the target directory identified by the input JSON. Here's the example output JSON from the "Getting Started" guide:

  {"srcFile":
             {"type":"FileObject",
              "id":"xdr:XFS-123456789",
              "parentId":"xdr:XFS-0",
              "filename":"/",
              "isDir":true,
              "isShared":false,
              "isMapped":false,                       
              "modifiedTime":1179196431000,
              "createTime":1143842914000,
              "aliasTo":"xdr:null",
              "accessPerm":null,
              "maxQuota":-1,
              "size":17725711},
   "children":
              [{"type":"FileObject",
                "id":"xdr:XFS-222222222",
                "parentId":"xdr:XFS-123456789",
                "filename":"Winter.jpg",
                "isDir":false,
                "isShared":false,
                "isMapped":false,
                "modifiedTime":1178646469000,
                "createTime":1178646468000,
                "aliasTo":"xdr:null",
                "accessPerm":null,
                "maxQuota":-1,
                "size":105542},
               {...}],
   "jsessionid":"77B8EEA5C0EE5C22FA551735D22A4CB9.xdr-mtc13.websys.aol.com_6002"
  }

An important element of this output is the isDir parameter. Directories and standard files are presented using the same JSON format. The files where isDir is true are directories; hence, their id parameters can be used as inputs to subsequent file.getlisting() calls.

The example problem in this article demonstrates how to use file.getlisting() in a basic XDSP API application.

io.upload()

The io.upload() call is used to upload files from a user's local directory to their Xdrive directory. The input JSON consists of an XDSP FileObject object and an XDSP StatusObject. The purpose of the StatusObject is to enable querying for the status of I/O operations (for example, remaining files, remaining bytes) and for conveying error messages. See the Xdrive Data Service Platform v1.1 API Reference for detailed documentation of the StatusObject object and all XDSP transfer and method objects.

In addition to the JSON, the io.upload request must include definition of the files to be uploaded. The Getting Started guide includes an illustrative example that applies io.upload using an HTTP POST.

io.download()

The io.download() call is used to download files from a user's Xdrive directory to their local directory. The input JSON consists of a FileObject object that identifies the file to be downloaded and an XDSP StatusObject. An optional range parameter can also be included in the input JSON, defining a byte range for block access.

Calls to io.download() do not produce a JSON response. Rather, the file bytes are returned. The response header includes the following information about the download file:

  • Content-Length (bytes)
  • Accept-Ranges (bytes)
  • Content-Range
  • Content-Disposition (attachment file name)
  • Content-Type (MIME type and name of file)

See the Getting Started guide and the Xdrive Data Service Platform v1.1 API Reference for details.

Xdrive API Sample Application

An example application was developed that applies the file.getlisting() XDSP API call. Here's a screen view of the application when it is initially loaded:

Test Xdrive API application initial page
Figure 2. Test Xdrive API application initial page

Here's the <body> HTML for this application:

<body>

<h2>Test XDrive API</h2>

<form method="post" action="http://plus.xdrive.com/json/v1.1/file.getlisting" 
    onsubmit="return getFolderListing();" target="jsonIframe">
  <input type="hidden" name="data" value="">
  <strong>Enter XDrive Folder ID</strong><br/>
  <input type="text" name="srcFile" id="srcFileId" size="30">  
  <br/>
  <input type="submit" value="getListing"/>
</form>

<h3>The Submitted Data</h3>

<div id="dataDiv"></div>

<h3>JSON Iframe</h3>

<iframe name="jsonIframe" height="100" src="blank.html"></iframe>

<h3>JSON Textarea</h3>

<textarea id="jsonText" cols="35" rows="3"></textarea>
<br/>
<button onclick="getListingJsonHandler()">Decode the JSON</button>

<h3>The Directory Listing</h3>

<div id="listDiv"></div>

</body>

The key element is the form that is activated when the "getListing" button is clicked. This calls the Xdrive JSON API, requesting the listing for the directory entered into the "Enter XDrive Folder ID" text box. But before sending the request, the getFolderListing() function is called. Let's take a look at this JavaScript function:

function getFolderListing() {
  var data = "";
  var id = document.forms[0].srcFileId.value;
  if(id == null || id.length > 0) {
    data = "{\"srcFile\":{\"type\":\"FileObject\",\"id\":\"" + id + "\"}}";
  }
  document.forms[0].data.value = data;

  var dataDiv = document.getElementById("dataDiv");
  dataDiv.innerHTML = "<p><strong>[</strong>" + data +
	    "<strong>]</strong></p>";
  
  return true;
}

The variable id is set to the value of the input text box in the form, which is tagged with id="srcFileId" in the form's HTML. So whatever the user typed into the "Enter XDrive Folder ID" text box is stored in the variable id in the function getFolderListing().

Based on what the user entered (if anything), the data value is left blank or is assigned to the JSON text that represents an XDSP FileObject object. The hidden data input in the form (see the HTML) is assigned to whatever is in the data variable (either blank, or the JSON text for an XDSP FileObject).

Finally, for diagnostic purposes, and to let the user see what's happening, the dataDiv <div> element, which is located immediately beneath the "The Submitted Data" label on the web page, is filled in with the data that is going to be sent to the XDSP API.

The URL http://plus.xdrive.com/json/v1.1/file.getlisting is now called. The target="jsonIframe" attribute in the form element directs the response output to the jsonIframe iframe that has been defined in the HTML (located immediately beneath the "JSON Iframe" label).

Here's what I see if I leave the "Enter XDrive Folder ID" input text box blank (indicating that I want to retrieve the listing for my root Xdrive directory):

Test Xdrive API app page after requesting root directory listing
Figure 3. Test Xdrive API app page after requesting root directory listing

Here we see that the submitted data was blank (the brackets merely mark the bounds of the data text) and that text was returned by the Xdrive API (displayed in the "JSON Iframe" box). You can scroll the iframe box, and you'll see a lot of text; but it's not text that's easily readable.

For this reason, I put a file.getlisting() JSON response code "decoder" function into the application. If I copy the text from the "JSON Iframe" into the "JSON Textarea" text box and click the "Decode the JSON" button, the getListingJsonHandler() JavaScript function is called. Take a look at getListingJsonHandler() to see how I decode the returned JSON:

function getListingJsonHandler() {
  var listHTML;
  
  var jsonString = document.getElementById("jsonText").value;
  alert(jsonString);
  
  document.getElementById("jsonText").value = "";
  
  var jsonObj = eval('(' + jsonString + ')');
  
  listHTML = "<strong>Folder " + jsonObj.srcFile.filename + ", ID " + 
      jsonObj.srcFile.id + ", ";

  listHTML += jsonObj.children.length + " children:</strong><br/>";

  if (jsonObj.children.length > 0) {
    listHTML += "<table border=1>";
    listHTML += "<tr><td><strong>Type</strong></td>";
    listHTML += "<td><strong>Name</strong></td>"
    listHTML += "<td><strong>ID</strong></td></tr>"

    for (var iFile = 0; iFile < jsonObj.children.length; iFile++) {
      listHTML += "<tr>";
      if (jsonObj.children[iFile].isDir == true) {
        listHTML += "<td>Folder</td>";
      } else {
        listHTML += "<td>File</td>";
      }
      listHTML += "<td>" + jsonObj.children[iFile].filename + "</td>";
      listHTML += "<td>" + jsonObj.children[iFile].id + "</td>"; 
      listHTML += "</tr>";
    }
    listHTML += "</table>";
  }   

  var listDiv = document.getElementById("listDiv");
  listDiv.innerHTML = listHTML;
  
}

First, the text entered into the jsonText text window (the response JSON that I copied and pasted from the iframe) is stored in variable jsonString. The JSON text is transformed into the JSON object jsonObj by applying the eval() method to the jsonString.

Now the decoding of the response JSON begins. The variable listHTML is created to contain an HTML snippet that will be displayed in the listDiv <div> element (located beneath the "The Directory Listing" label). The jsonObj.srcFile.filename and ID parameter (jsonObj.srcFile.id) are copied into listHTML, identifying the Xdrive directory for which we've retrieved a directory listing.

Then, the "children" are accessed, and formatted into HTML to provide a display of the directory's contents. The property jsonObj.children.length tells us how many files are in the directory. If the directory contains any files or directories, the function creates a table that displays the file/directory names, the Xdrive identification strings for the files, and whether or not the file is a directory. The IDs of the entries that are directories can be cut and pasted into the "Enter XDrive Folder ID" text entry, in order to retrieve the listing of that directory's files and subdirectories.

Here's what the bottom of the application screen looks like after the returned JSON is copied from the "JSON Iframe" into the "JSON Textarea" input box, and the "Decode the JSON" button is clicked:

Bottom of Test Xdrive API app page after clicking Decode the JSON
Figure 4. Bottom of Test Xdrive API app page after clicking "Decode the JSON"

Compare what you see in Figure 4 to the my online Xdrive display in Figure 1, and you'll see that by using the XDrive API's file.getlisting() call I was able to bring my root directory's file and directory listing into an object that is accessible by my browser application for whatever purposes suit my needs. Pretty cool!

Conclusion

The Xdrive Data Service Platform includes a JSON API that provides developers with access to a user's Xdrive storage, including rich directory listing retrieval through the file.getlisting() call exemplified in this article's example problem.

The Xdrive API is new and is under active development. Enhancements in Version 1.2 of the XDSP API include:

  • Expanded authentication
  • Multiple requests/commands can be chained together, implemented via multipart requests
  • The introduction of a JSON options object to modify the request/response independent of the method result
  • Simplified for non-browser based clients
  • Expanded I/O features: true block level access and better transfer monitoring
  • Expanded collection management features
  • Expanded sharing features
  • The introduction of publishing features

Resources

The code for the example application presented in this application is available in the XdriveIframeTest.zip file.

References

Can you help me, about login in function

You said:
The simplest way to authenticate access to XDSP is to log into Xdrive using the Xdrive.com interface, and then run your application in that same browser instance (this could include another tab or new browser window created from the window where you logged into Xdrive). Logging into Xdrive.com saves a JSESSIONID cookie in your browser. The jsessionid variable in this cookie is read when you make JSON calls to the API, enabling programmatic access to that particular Xdrive account.
This method is work.

But, if i don't use the Xdrive.com interface, How I can do? For example, I use this method of API:member.login, we can login successfully, but, then when I calls this method as below:
* file.getlisting
* io.upload
* io.download
,them don't work. This exception happen:
{"exceptions":[{"type":"ExceptionObject","errorMessage":"Your login username or password is incorrect. Please note that usernames take the form of an e-mail address for most users, e.g., JohnDoe@aol.com. Please try logging in again.","errorInfo":null,"errorCode":501}]}

Would you like to tell me what's reason. Thanks a lot.