| var index = require("./index.js"), |
| DomHandler = index.DomHandler, |
| DomUtils = index.DomUtils; |
| |
| //TODO: make this a streamable handler |
| function FeedHandler(callback, options){ |
| this.init(callback, options); |
| } |
| |
| require("inherits")(FeedHandler, DomHandler); |
| |
| FeedHandler.prototype.init = DomHandler; |
| |
| function getElements(what, where){ |
| return DomUtils.getElementsByTagName(what, where, true); |
| } |
| function getOneElement(what, where){ |
| return DomUtils.getElementsByTagName(what, where, true, 1)[0]; |
| } |
| function fetch(what, where, recurse){ |
| return DomUtils.getText( |
| DomUtils.getElementsByTagName(what, where, recurse, 1) |
| ).trim(); |
| } |
| |
| function addConditionally(obj, prop, what, where, recurse){ |
| var tmp = fetch(what, where, recurse); |
| if(tmp) obj[prop] = tmp; |
| } |
| |
| var isValidFeed = function(value){ |
| return value === "rss" || value === "feed" || value === "rdf:RDF"; |
| }; |
| |
| FeedHandler.prototype.onend = function(){ |
| var feed = {}, |
| feedRoot = getOneElement(isValidFeed, this.dom), |
| tmp, childs; |
| |
| if(feedRoot){ |
| if(feedRoot.name === "feed"){ |
| childs = feedRoot.children; |
| |
| feed.type = "atom"; |
| addConditionally(feed, "id", "id", childs); |
| addConditionally(feed, "title", "title", childs); |
| if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp; |
| addConditionally(feed, "description", "subtitle", childs); |
| if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp); |
| addConditionally(feed, "author", "email", childs, true); |
| |
| feed.items = getElements("entry", childs).map(function(item){ |
| var entry = {}, tmp; |
| |
| item = item.children; |
| |
| addConditionally(entry, "id", "id", item); |
| addConditionally(entry, "title", "title", item); |
| if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp; |
| if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp; |
| if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp); |
| return entry; |
| }); |
| } else { |
| childs = getOneElement("channel", feedRoot.children).children; |
| |
| feed.type = feedRoot.name.substr(0, 3); |
| feed.id = ""; |
| addConditionally(feed, "title", "title", childs); |
| addConditionally(feed, "link", "link", childs); |
| addConditionally(feed, "description", "description", childs); |
| if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp); |
| addConditionally(feed, "author", "managingEditor", childs, true); |
| |
| feed.items = getElements("item", feedRoot.children).map(function(item){ |
| var entry = {}, tmp; |
| |
| item = item.children; |
| |
| addConditionally(entry, "id", "guid", item); |
| addConditionally(entry, "title", "title", item); |
| addConditionally(entry, "link", "link", item); |
| addConditionally(entry, "description", "description", item); |
| if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp); |
| return entry; |
| }); |
| } |
| } |
| this.dom = feed; |
| DomHandler.prototype._handleCallback.call( |
| this, feedRoot ? null : Error("couldn't find root of feed") |
| ); |
| }; |
| |
| module.exports = FeedHandler; |