Friday, June 20, 2008

KnowledgeTree document download via Google Gadget

This is an installment feature for the KT-Gadget, a widget for KnowledgeTree, an open-source document management system.

As mentioned in the previous post, I employed an application proxy to act as a bridge between a Google Gadget and KnowledgeTree's SOAP services. Originally, the application proxy responses were formatted in XML. Moving forward, I decided to adopt the JSON format instead of XML owing to simpler methods in handling JSON feeds from both PHP and (of course) Javascript worlds.

The application proxy's SOAP client is based on PHP and converting an associative array of response items to JSON format is implemented simply by using PHP's json_encode function. At the gadget side, the requests for remote data are invoked using Google's _IG_FetchContent function. Using Javascript's eval() function, the returned JSON text response is converted to an object whose members can be easily accessed using dot or subscript operators.

Here are the details.. To download a document, KT-Gadget sends a request to the helper application by invoking the url:

http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=download_document&sid=rsop4e364ptf4slkp2a2vtvb96&did=4

The JSON response by the application proxy is of the form:
{"response":{"status_code":0,"message":"http:\/\/docs.pipoltek.com\/ktwebservice\/download.php?code=d2db2c0868ab0c9cd053fe2e43ab9926d1bcf94c&d=4&u=6a0j9qqpqc11de6nju6o0ej5o7"}}

The relevant block of KT-Gadget code is reproduced hereunder:

var url = "http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=" + sessionID__MODULE_ID__ + "&fid=6";
_IG_FetchContent(url, function (jsonFeed) {
var jsonData = eval('(' + jsonFeed + ')');
if (jsonData.response.status_code != 0) {
alert ('Error in retrieving document!');
} else{
dd_link = jsonData.response.message;
_gel("ktg-lnk").innerHTML = '<a href="' + dd_link + '">@';
}
})

Once the application proxy has responded, the JSON text response (jsonFeed) is converted to an object (jsonData) using the eval() function. The response contains the download URL the value of which can be referenced as jsonData.response.message.

Where did the Session-ID (sid) and Document-ID (did) used as URL parameters come from? The Session-ID is assigned during login and the Document-ID, together with the rest of the document details, is returned by a call to get_folder_contents.

Here's the login invocation:
http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=login&uid=rexjun&pwd=cabanilla

The invocation to get_folder_contents:
http://kt-gadget.pipoltek.com/pipoltek.com/json/?oid=get_folder_contents&sid=0j8jkhjn55t7r3b0rshbcchpn1&fid=6

If you get a "Session is invalid" error, it's because the link is using an ID of an expired session. Change the URL parameter (sid) to a fresh Session-ID returned by the login call to get better results.

You may try out KT-Gadget by adding it to your iGoogle page or view the gadget source code here.

Thursday, June 12, 2008

Accessing Soap Services from Google Gadgets

The earlier gadget projects I developed have utilized third-party web services from a variety of sources:

  • Google Maps for geographic data
  • Google Docs spreadsheet as XML datasource
  • IP-Geolocation (IP address->Country) service from HostIP.Info
  • User profile and gaming statistics as XML feeds from Xfire.
Given the constraints of a space-restricted, remotely-hosted, javascript-only application, gadgets primarily rely on web services to provide richer data content without the attendant complexity. However, javascript is beset by cross-domain restrictions that even impact xmlHttpRequest, the very underpinnings of Ajax. Since Google gadgets are javascript apps, the same-origin security policy prevents it from making requests outside the domain it is running on.

Although Google addressed this problem by providing the _IG_FetchXMLContent function, it lacks support for https, SOAP and POST. It looks like the newer gadget.io.makeRequest function is intended to address these deficiencies. However, the availability of the gadget.io.* functions in Google's production servers is yet forthcoming.

I decided not to hold my breath..

KT-Gadget is a widget front-end to KnowledgeTree - an open-source document management system. To access KnowledgeTree's SOAP services, I had to deploy another application to receive the requests from Google's _IG_FetchXMLContent calls, make the corresponding SOAP requests, and generate the appropriate XML output. Two basic functions are implemented: login and get_folder_contents. The functions are based on PHP, the same language that was used to develop KnowlegeTree.

After pushing the login button, the gadget will indicate the progress of the subsequent operations:
  • Logging in
  • Fetching Documents
  • Sorting Documents
In its current state, the gadget is useful as a watcher of some sort of inbox for workflow-enabled documents like incoming faxes needing disposition or requisitions requiring approval. Sit around and watch your work pile up...

I plan to implement two more functions: download_document and perform_document_workflow_transition. We don't want work to pile up, do we? Other nice-to-have features: watch all accessible folders and sub-folders; show number of documents per folder; folder and document colors based on certain thresholds like document count, age, metadata contents (priority, etc); automatic refresh.

But don't hold your breath...