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