--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mypackage_wrt/FeedUpdateBroker.js Fri Apr 30 15:01:03 2010 +0100
@@ -0,0 +1,180 @@
+///////////////////////////////////////////////////////////////////////////////
+// The FeedUpdateBroker class implements a simple RSS fetcher and parser.
+// Adapted from WRTKit RssReader example
+
+// Constructor.
+function FeedUpdateBroker() {
+ this.httpReq = null;
+ this.feedAddress = null;
+ this.callback = null;
+ this.ignoreContent = false;
+ this.cancelled = false;
+ this.responseParser = this.handleRssResponse;
+ this.startFromItem = 0;
+ this.maxItems = 0;
+}
+
+// Fetches a feed from the specified URL and calls the callback when the feed
+// has been fetched and parsed, or if the process results in an error.
+FeedUpdateBroker.prototype.doFetchFeed = function(){
+ // create new XML HTTP request
+ this.httpReq = new Ajax();
+
+ // set callback
+ var self = this;
+ this.httpReq.onreadystatechange = function() { self.readyStateChanged(); };
+
+ // initiate the request
+ this.httpReq.open("GET", nocache(this.feedAddress), true);
+ this.httpReq.send(null);
+}
+
+// has been fetched and parsed, or if the process results in an error.
+FeedUpdateBroker.prototype.fetchFeed = function(feedURL, callback) {
+ // remember callback
+ this.callback = callback;
+ this.feedAddress = feedURL;
+ this.doFetchFeed();
+}
+
+// Callback for ready-state change events in the XML HTTP request.
+FeedUpdateBroker.prototype.readyStateChanged = function() {
+ // complete request?
+ if (this.httpReq.readyState == 4) {
+ // attempt to get response status
+ var responseStatus = null;
+ try {
+ responseStatus = this.httpReq.status;
+ } catch (noStatusException) {}
+
+ // are we being prompted for login?
+ var text = this.httpReq.responseText;
+ if ( isLoginPrompt (text) ) {
+ var self = this;
+// setTimeout(self.doFetchFeed(), 100);
+ login(function(){self.doFetchFeed();});
+ return;
+ }
+
+ // handle the response and call the registered callback object
+ var response = this.httpReq.responseXML;
+ if (response == null) {
+ // if the content type is not set correctly, we get the response as text
+ var xmlparser = new DOMParser();
+ response = xmlparser.parseFromString(this.httpReq.responseText, "text/xml");
+ }
+ this.callback.feedUpdateCompleted(this.handleResponse(responseStatus, response));
+ }
+}
+
+// Handles a completed response.
+FeedUpdateBroker.prototype.handleResponse = function(responseStatus, xmlDoc){
+ if (this.responseParser == null) {
+ return this.handleRssResponse(responseStatus, xmlDoc);
+ }
+ else {
+ return this.responseParser.call(this, this, responseStatus, xmlDoc);
+ }
+}
+
+
+FeedUpdateBroker.prototype.handleRssResponse = function(broker, responseStatus, xmlDoc){
+ if ( this.cancelled ) {
+ return { status: "cancelled" };
+ }
+ if (responseStatus == 200 && xmlDoc != null) {
+ // node ref for iterating
+ var node;
+
+ // get last modified time - default to current time
+ var lastModified = new Date().getTime();
+ var channelElements = xmlDoc.getElementsByTagName("channel");
+ if (channelElements.length > 0) {
+ node = channelElements[0].firstChild;
+ while (node != null) {
+ if (node.nodeType == Node.ELEMENT_NODE) {
+ if (node.nodeName == "pubDate" ||
+ node.nodeName == "lastBuildDate" ||
+ node.nodeName == "dc:date") {
+ lastModified = getTextOfNode(node);
+ break;
+ }
+ }
+ node = node.nextSibling;
+ }
+ }
+
+ // init feed items array
+ var items = [];
+
+ // we got the feed XML so now we'll parse it
+ var itemElements = xmlDoc.getElementsByTagName("item");
+
+ for (var i = this.startFromItem; i < itemElements.length; i++) {
+ if ( this.maxItems > 0 && this.maxItems < i ) {
+ break;
+ }
+ // iterate through child nodes of this item and gather
+ // all the data we need for a feed item
+ var title = null;
+ var date = null;
+ var description = null;
+ var url = null;
+ var author = null;
+ node = itemElements[i].firstChild;
+ while (node != null) {
+ if (node.nodeType == Node.ELEMENT_NODE) {
+ if (node.nodeName == "title") {
+ // item title
+ title = getTextOfNode(node);
+ } else if (node.nodeName == "pubDate" || node.nodeName == "dc:date") {
+ // item publishing date
+ date = getTextOfNode(node);
+ } else if (node.nodeName == "description" && !this.ignoreContent ) {
+ // item description
+ description = getTextOfNode(node);
+ } else if (node.nodeName == "link") {
+ // link URL
+ url = getTextOfNode(node);
+ } else if (node.nodeName == "dc:creator" ) {
+ author = getTextOfNode(node);
+ }
+ }
+ node = node.nextSibling;
+ }
+
+ // create the item and add to the items array
+ items.push({ title: title, date: date, description: description, url: url, author: author });
+ }
+
+ // update was completed successfully
+ return { status: "ok", lastModified: lastModified, items: items };
+ } else {
+ // update failed
+ return { status: "error" };
+ }
+}
+
+// Returns the text of a node.
+function getTextOfNode(node) {
+ var buf = "";
+ // iterate through all child elements and collect all text to the buffer
+ var child = node.firstChild;
+ while (child != null) {
+ if (child.nodeType == Node.TEXT_NODE || child.nodeType == Node.CDATA_SECTION_NODE) {
+ // append text to buffer
+ if (buf != "") {
+ buf += " ";
+ }
+ buf += child.nodeValue;
+ }
+ child = child.nextSibling;
+ }
+
+ return buf;
+}
+
+FeedUpdateBroker.prototype.cancel = function() {
+ this.cancelled = true;
+ this.httpReq.abort();
+}