Mercurial > snowl
changeset 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 | d128eee04c8a |
files | extension/content/preferences.js extension/modules/feed.js |
diffstat | 2 files changed, 104 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/extension/content/preferences.js Wed May 14 22:33:20 2008 -0700 +++ b/extension/content/preferences.js Wed May 14 23:22:49 2008 -0700 @@ -5,6 +5,8 @@ Cu.import("resource://snowl/modules/service.js"); Cu.import("resource://snowl/modules/datastore.js"); +Cu.import("resource://snowl/modules/feed.js"); +Cu.import("resource://snowl/modules/URI.js"); let SnowlPreferences = { onImportOPML: function() { @@ -30,18 +32,16 @@ let outline = xmlDocument.getElementsByTagName("body")[0]; this._importOutline(outline); - - SnowlService.refreshStaleSources(); }, _importOutline: function(aOutline) { // If this outline represents a feed, subscribe the user to the feed. - var url = aOutline.getAttribute("xmlUrl"); - if (url) { + let uri = URI.get(aOutline.getAttribute("xmlUrl")); + if (uri) { // FIXME: make sure the user isn't already subscribed to the feed // before subscribing them. - let title = aOutline.getAttribute("title") || aOutline.getAttribute("text") || "untitled"; - this._importItem(url, title); + let name = aOutline.getAttribute("title") || aOutline.getAttribute("text") || "untitled"; + this._importItem(uri, name); } if (aOutline.hasChildNodes()) { @@ -59,15 +59,7 @@ }, _importItem: function(aURL, aName) { - // FIXME: create the statement once and then reuse it each time. - let statement = SnowlDatastore.createStatement("INSERT INTO sources (machineURI, name) VALUES (:machineURI, :name)"); - try { - statement.params.machineURI = aURL; - statement.params.name = aName; - statement.step(); - } - finally { - statement.reset(); - } + let subscriber = new SnowlFeedSubscriber(aURL, aName); + subscriber.subscribe(); } };
--- 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); + } + +};