mypackage_wrt/FeedUpdateBroker.js
changeset 42 20be4dd42b12
equal deleted inserted replaced
41:315255cd1aef 42:20be4dd42b12
       
     1 ///////////////////////////////////////////////////////////////////////////////
       
     2 // The FeedUpdateBroker class implements a simple RSS fetcher and parser.
       
     3 // Adapted from WRTKit RssReader example
       
     4 
       
     5 // Constructor.
       
     6 function FeedUpdateBroker() {
       
     7     this.httpReq = null;
       
     8     this.feedAddress = null;
       
     9     this.callback = null;
       
    10 	this.ignoreContent = false;
       
    11 	this.cancelled = false;
       
    12 	this.responseParser = this.handleRssResponse;
       
    13 	this.startFromItem = 0;
       
    14 	this.maxItems = 0;
       
    15 }
       
    16 
       
    17 // Fetches a feed from the specified URL and calls the callback when the feed
       
    18 // has been fetched and parsed, or if the process results in an error.
       
    19 FeedUpdateBroker.prototype.doFetchFeed = function(){    
       
    20     // create new XML HTTP request
       
    21     this.httpReq = new Ajax();
       
    22     
       
    23     // set callback
       
    24     var self = this;
       
    25     this.httpReq.onreadystatechange = function() { self.readyStateChanged(); };
       
    26 
       
    27     // initiate the request
       
    28     this.httpReq.open("GET", nocache(this.feedAddress), true);
       
    29     this.httpReq.send(null);
       
    30 }
       
    31 
       
    32 // has been fetched and parsed, or if the process results in an error.
       
    33 FeedUpdateBroker.prototype.fetchFeed = function(feedURL, callback) {
       
    34     // remember callback
       
    35     this.callback = callback;
       
    36     this.feedAddress = feedURL;
       
    37 	this.doFetchFeed();
       
    38 }
       
    39 
       
    40 // Callback for ready-state change events in the XML HTTP request.
       
    41 FeedUpdateBroker.prototype.readyStateChanged = function() {
       
    42     // complete request?
       
    43     if (this.httpReq.readyState == 4) {
       
    44         // attempt to get response status
       
    45         var responseStatus = null;
       
    46         try {
       
    47             responseStatus = this.httpReq.status;
       
    48         } catch (noStatusException) {}
       
    49         
       
    50 		// are we being prompted for login?
       
    51 		var text = this.httpReq.responseText;
       
    52 		if ( isLoginPrompt (text) ) {
       
    53 			var self = this;
       
    54 //			setTimeout(self.doFetchFeed(), 100);
       
    55 			login(function(){self.doFetchFeed();});
       
    56 			return;
       
    57 		}
       
    58 		
       
    59         // handle the response and call the registered callback object
       
    60 		var response = this.httpReq.responseXML;
       
    61 		if (response == null) {
       
    62 			// if the content type is not set correctly, we get the response as text
       
    63 			var xmlparser = new DOMParser();
       
    64 		    response = xmlparser.parseFromString(this.httpReq.responseText, "text/xml");
       
    65 		}
       
    66         this.callback.feedUpdateCompleted(this.handleResponse(responseStatus, response));
       
    67     }
       
    68 }
       
    69 
       
    70 // Handles a completed response.
       
    71 FeedUpdateBroker.prototype.handleResponse = function(responseStatus, xmlDoc){
       
    72 	if (this.responseParser == null) {
       
    73 		return this.handleRssResponse(responseStatus, xmlDoc);
       
    74 	}
       
    75 	else {
       
    76 		return this.responseParser.call(this, this, responseStatus, xmlDoc);
       
    77 	}	
       
    78 }
       
    79 
       
    80 
       
    81 FeedUpdateBroker.prototype.handleRssResponse = function(broker, responseStatus, xmlDoc){
       
    82 	if ( this.cancelled ) {
       
    83         return { status: "cancelled" };
       
    84 	}
       
    85     if (responseStatus == 200 && xmlDoc != null) {
       
    86         // node ref for iterating
       
    87         var node;
       
    88         
       
    89         // get last modified time - default to current time
       
    90         var lastModified = new Date().getTime();
       
    91         var channelElements = xmlDoc.getElementsByTagName("channel");
       
    92         if (channelElements.length > 0) {
       
    93             node = channelElements[0].firstChild;
       
    94             while (node != null) {
       
    95                 if (node.nodeType == Node.ELEMENT_NODE) {
       
    96                     if (node.nodeName == "pubDate" ||
       
    97                             node.nodeName == "lastBuildDate" ||
       
    98                             node.nodeName == "dc:date") {
       
    99                         lastModified = getTextOfNode(node);
       
   100                         break;
       
   101                     }
       
   102                 }
       
   103                 node = node.nextSibling;
       
   104             }
       
   105         }
       
   106         
       
   107         // init feed items array
       
   108         var items = [];
       
   109         
       
   110         // we got the feed XML so now we'll parse it
       
   111         var itemElements = xmlDoc.getElementsByTagName("item");
       
   112 		
       
   113         for (var i = this.startFromItem; i < itemElements.length; i++) {
       
   114 			if ( this.maxItems > 0 && this.maxItems < i ) {
       
   115 				break;
       
   116 			}
       
   117             // iterate through child nodes of this item and gather
       
   118             // all the data we need for a feed item
       
   119             var title = null;
       
   120             var date = null;
       
   121             var description = null;
       
   122             var url = null;
       
   123             var author = null;
       
   124             node = itemElements[i].firstChild;
       
   125             while (node != null) {
       
   126                 if (node.nodeType == Node.ELEMENT_NODE) {
       
   127                     if (node.nodeName == "title") {
       
   128                         // item title
       
   129                         title = getTextOfNode(node);
       
   130                     } else if (node.nodeName == "pubDate" || node.nodeName == "dc:date") {
       
   131                         // item publishing date
       
   132                         date = getTextOfNode(node);
       
   133                     } else if (node.nodeName == "description" && !this.ignoreContent ) {
       
   134                         // item description
       
   135                         description = getTextOfNode(node);
       
   136                     } else if (node.nodeName == "link") {
       
   137                         // link URL
       
   138                         url = getTextOfNode(node);
       
   139                     } else if (node.nodeName == "dc:creator" ) {
       
   140 						author = getTextOfNode(node);
       
   141 					}
       
   142                 }
       
   143                 node = node.nextSibling;
       
   144             }
       
   145             
       
   146             // create the item and add to the items array
       
   147             items.push({ title: title, date: date, description: description, url: url, author: author });
       
   148         }
       
   149         
       
   150         // update was completed successfully
       
   151         return { status: "ok", lastModified: lastModified, items: items };
       
   152     } else {
       
   153         // update failed
       
   154         return { status: "error" };
       
   155     }
       
   156 }
       
   157 
       
   158 // Returns the text of a node.
       
   159 function getTextOfNode(node) {
       
   160     var buf = "";
       
   161 	// iterate through all child elements and collect all text to the buffer
       
   162 	var child = node.firstChild;
       
   163 	while (child != null) {
       
   164 		if (child.nodeType == Node.TEXT_NODE || child.nodeType == Node.CDATA_SECTION_NODE) {
       
   165 			// append text to buffer
       
   166 			if (buf != "") {
       
   167 				buf += " ";
       
   168 			}
       
   169 			buf += child.nodeValue;
       
   170 		}
       
   171 		child = child.nextSibling;
       
   172 	}
       
   173 	
       
   174 	return buf;
       
   175 }
       
   176 
       
   177 FeedUpdateBroker.prototype.cancel = function() {
       
   178 	this.cancelled = true;
       
   179 	this.httpReq.abort();
       
   180 }