FeedHandler.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. var index = require("./index.js"),
  2. DomHandler = index.DomHandler,
  3. DomUtils = index.DomUtils;
  4. //TODO: make this a streamable handler
  5. function FeedHandler(callback, options){
  6. this.init(callback, options);
  7. }
  8. require("util").inherits(FeedHandler, DomHandler);
  9. FeedHandler.prototype.init = DomHandler;
  10. function getElements(what, where){
  11. return DomUtils.getElementsByTagName(what, where, true);
  12. }
  13. function getOneElement(what, where){
  14. return DomUtils.getElementsByTagName(what, where, true, 1)[0];
  15. }
  16. function fetch(what, where, recurse){
  17. return DomUtils.getText(
  18. DomUtils.getElementsByTagName(what, where, recurse, 1)
  19. ).trim();
  20. }
  21. function addConditionally(obj, prop, what, where, recurse){
  22. var tmp = fetch(what, where, recurse);
  23. if(tmp) obj[prop] = tmp;
  24. }
  25. var isValidFeed = function(value){
  26. return value === "rss" || value === "feed" || value === "rdf:RDF";
  27. };
  28. FeedHandler.prototype.onend = function(){
  29. var feed = {},
  30. feedRoot = getOneElement(isValidFeed, this.dom),
  31. tmp, childs;
  32. if(feedRoot){
  33. if(feedRoot.name === "feed"){
  34. childs = feedRoot.children;
  35. feed.type = "atom";
  36. addConditionally(feed, "id", "id", childs);
  37. addConditionally(feed, "title", "title", childs);
  38. if((tmp = getOneElement("link", childs)) && (tmp = tmp.attribs) && (tmp = tmp.href)) feed.link = tmp;
  39. addConditionally(feed, "description", "subtitle", childs);
  40. if((tmp = fetch("updated", childs))) feed.updated = new Date(tmp);
  41. addConditionally(feed, "author", "email", childs, true);
  42. feed.items = getElements("entry", childs).map(function(item){
  43. var entry = {}, tmp;
  44. item = item.children;
  45. addConditionally(entry, "id", "id", item);
  46. addConditionally(entry, "title", "title", item);
  47. if((tmp = getOneElement("link", item)) && (tmp = tmp.attribs) && (tmp = tmp.href)) entry.link = tmp;
  48. if((tmp = fetch("summary", item) || fetch("content", item))) entry.description = tmp;
  49. if((tmp = fetch("updated", item))) entry.pubDate = new Date(tmp);
  50. return entry;
  51. });
  52. } else {
  53. childs = getOneElement("channel", feedRoot.children).children;
  54. feed.type = feedRoot.name.substr(0, 3);
  55. feed.id = "";
  56. addConditionally(feed, "title", "title", childs);
  57. addConditionally(feed, "link", "link", childs);
  58. addConditionally(feed, "description", "description", childs);
  59. if((tmp = fetch("lastBuildDate", childs))) feed.updated = new Date(tmp);
  60. addConditionally(feed, "author", "managingEditor", childs, true);
  61. feed.items = getElements("item", feedRoot.children).map(function(item){
  62. var entry = {}, tmp;
  63. item = item.children;
  64. addConditionally(entry, "id", "guid", item);
  65. addConditionally(entry, "title", "title", item);
  66. addConditionally(entry, "link", "link", item);
  67. addConditionally(entry, "description", "description", item);
  68. if((tmp = fetch("pubDate", item))) entry.pubDate = new Date(tmp);
  69. return entry;
  70. });
  71. }
  72. }
  73. this.dom = feed;
  74. DomHandler.prototype._handleCallback.call(
  75. this, feedRoot ? null : Error("couldn't find root of feed")
  76. );
  77. };
  78. module.exports = FeedHandler;