Mercurial > snowl
diff extension/modules/feed.js @ 76:1cbd4c5a511b
link the source name to the human URI if available; add a new SnowlFeedSubscriber object that can handle subscribing to feeds from various interfaces and which sets the human URI if available; make the OPML importer use the new SnowlFeedSubscriber object
author | Myk Melez <myk@mozilla.org> |
---|---|
date | Wed, 14 May 2008 23:22:49 -0700 |
parents | 877a7694445f |
children | 915e41848f6d |
line wrap: on
line diff
--- a/extension/modules/feed.js Wed May 14 22:33:20 2008 -0700 +++ b/extension/modules/feed.js Wed May 14 23:22:49 2008 -0700 @@ -1,4 +1,4 @@ -EXPORTED_SYMBOLS = ["SnowlFeed"]; +EXPORTED_SYMBOLS = ["SnowlFeed", "SnowlFeedSubscriber"]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -355,3 +355,98 @@ } }; + +// XXX Should we make this part of the Feed object? +// FIXME: make this accept a callback to which it reports on its progress +// so we can provide feedback to the user in subscription interfaces. +function SnowlFeedSubscriber(aURI, aName) { + this.uri = aURI; + this.name = aName; +} + +SnowlFeedSubscriber.prototype = { + uri: null, + name: null, + + // Observer Service + get _obsSvc() { + let obsSvc = Cc["@mozilla.org/observer-service;1"]. + getService(Ci.nsIObserverService); + delete this._obsSvc; + this._obsSvc = obsSvc; + return this._obsSvc; + }, + + QueryInterface: function(aIID) { + if (aIID.equals(Ci.nsIDOMEventListener) || + aIID.equals(Ci.nsIFeedResultListener) || + aIID.equals(Ci.nsISupports)) + return this; + + throw Cr.NS_ERROR_NO_INTERFACE; + }, + + subscribe: function() { + let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(); + + request = request.QueryInterface(Ci.nsIDOMEventTarget); + request.addEventListener("load", this, false); + request.addEventListener("error", this, false); + + request = request.QueryInterface(Ci.nsIXMLHttpRequest); + request.open("GET", this.uri.spec, true); + request.send(null); + }, + + // nsIDOMEventListener + + handleEvent: function(aEvent) { + switch(aEvent.type) { + case "load": + this.onLoad(aEvent); + break; + case "error": + this.onError(aEvent); + break; + } + }, + + onLoad: function(aEvent) { + let request = aEvent.target; + + // FIXME: notify the user about the problem. + if (request.responseText.length == 0) + throw("feed contains no data"); + + let parser = Cc["@mozilla.org/feed-processor;1"]. + createInstance(Ci.nsIFeedProcessor); + parser.listener = this; + parser.parseFromString(request.responseText, request.channel.URI); + }, + + // nsIFeedResultListener + + handleResult: function(aResult) { + let feed = aResult.doc.QueryInterface(Components.interfaces.nsIFeed); + + // Subscribe to the feed. + let name = this.name || feed.title.plainText(); + let statement = SnowlDatastore.createStatement("INSERT INTO sources (name, machineURI, humanURI) VALUES (:name, :machineURI, :humanURI)"); + statement.params.name = name; + statement.params.machineURI = this.uri.spec; + statement.params.humanURI = feed.link.spec; + dump("subscribing to " + name + " <" + this.uri.spec + ">\n"); + statement.step(); + + let id = SnowlDatastore.dbConnection.lastInsertRowID; + + // Now refresh the feed to import all its items. + dump("refreshing " + this.uri.spec + "\n"); + let feed2 = new SnowlFeed(id, this.uri.spec, name); + feed2.handleResult(aResult); + + this._obsSvc.notifyObservers(null, "sources:changed", null); + this._obsSvc.notifyObservers(null, "messages:changed", null); + } + +};