Comparing version 0.0.1 to 0.0.2
139
lib/feed.js
@@ -1,2 +0,2 @@ | ||
//feed.js | ||
//feed.js | ||
var xml2js = require('xml2js'); | ||
@@ -15,14 +15,14 @@ var _ = require('underscore'); | ||
function parseURL(feedURL, options, callback) { | ||
if (typeof options == 'function' && !callback) { | ||
if (typeof options === 'function' && !callback) { | ||
callback = options; | ||
options = {}; | ||
} | ||
var defaults = {uri:feedURL, jar:false, proxy:false, followRedirect:true, timeout:1000 * 30}; | ||
var defaults = {uri: feedURL, jar: false, proxy: false, followRedirect: true, timeout: 1000 * 30}; | ||
options = _.extend(defaults, options); | ||
//check that the protocal is either http or https | ||
var u = URL.parse(feedURL); | ||
if (u.protocol == 'http:' || u.protocol == 'https:') { | ||
if (u.protocol === 'http:' || u.protocol === 'https:') { | ||
//make sure to have a 30 second timeout | ||
var req = request(options, function (err, response, xml) { | ||
if (err || xml == null) { | ||
if (err || xml === null) { | ||
if (err) { | ||
@@ -38,3 +38,3 @@ callback(err, null); | ||
} else { | ||
callback({error:"Only http or https protocalls are accepted"}, null); | ||
callback({error: "Only http or https protocols are accepted"}, null); | ||
} | ||
@@ -47,3 +47,3 @@ } | ||
if (xml.split('<').length >= 3) { | ||
var parser = new xml2js.Parser({trim:false, normalize:true, mergeAttrs:true}); | ||
var parser = new xml2js.Parser({trim: false, normalize: true, mergeAttrs: true}); | ||
parser.addListener('end', function (jsonDOM) { | ||
@@ -104,3 +104,3 @@ if (jsonDOM) { | ||
//Start with the metadata for the feed | ||
var output = {'type':'rss',items:[]}; | ||
var output = {'type': 'rss', items: []}; | ||
var metadata = {}; | ||
@@ -131,4 +131,2 @@ var channel = json.channel; | ||
} | ||
//ok, now lets get into the meat of the feed | ||
@@ -156,8 +154,7 @@ //just double check that it exists | ||
///wordpress author | ||
if(val['dc:creator']){ | ||
if (val['dc:creator']) { | ||
obj.author = val['dc:creator'][0]; | ||
} | ||
if(val.author) | ||
{ | ||
if (val.author) { | ||
obj.author = val.author[0]; | ||
@@ -173,6 +170,3 @@ } | ||
var isPermaLink = true; | ||
//if(param){ | ||
// isPermaLink = param.isPermaLink; | ||
//} | ||
obj.guid = {'link':link, isPermaLink:param}; | ||
obj.guid = {'link': link, isPermaLink: param}; | ||
} | ||
@@ -187,28 +181,45 @@ //now push the obj onto the stack | ||
//formats the ATOM feed to the needed output | ||
//yes, this is a shamless copy-pasta of the RSS code (its all the same structure!) | ||
function formatATOM(json) { | ||
var output = {'type':'atom', metadata:{}, items:[]}; | ||
var output = {'type': 'atom', items: []}; | ||
//Start with the metadata for the feed | ||
var metadata = {}; | ||
var channel = json; | ||
var channel = json.feed; | ||
if (typeof channel.title === "object") { | ||
console.log(channel.title); | ||
} | ||
if (channel.title) { | ||
metadata.title = channel.title; | ||
output.title = channel.title[0]._; | ||
} | ||
if (channel.subtitle) { | ||
metadata.desc = channel.subtitle; | ||
if (_.isArray(channel.subtitle)) { | ||
if (channel.subtitle[0]._) { | ||
output.desc = channel.subtitle[0]._; | ||
} | ||
} else { | ||
output.desc = channel.subtitle; | ||
} | ||
if (channel.link) { | ||
metadata.url = channel.link; | ||
if (_.isArray(channel.link)) { | ||
_.each(channel.link, function (val, index) { | ||
if (val.type && val.type.indexOf("html") > 0) { | ||
output.link = val.href; | ||
} | ||
if (val.rel === "hub") { | ||
output.hub = val.href; | ||
} | ||
}); | ||
} | ||
if (channel.id) { | ||
metadata.id = channel.id; | ||
output.id = channel.id[0]; | ||
} | ||
if (channel.update) { | ||
metadata.update = channel.update; | ||
if (channel.updated) { | ||
output.last_modified = new Date(channel.updated[0]).toString(); | ||
} | ||
if (channel.author) { | ||
metadata.author = channel.author; | ||
output.author = channel.author[0].name[0]; | ||
} | ||
output.metadata = metadata; | ||
//just double check that it exists and that it is an array | ||
@@ -222,11 +233,9 @@ if (channel.entry) { | ||
var obj = {}; | ||
obj.id = val.id; | ||
obj.id = val.id[0]; | ||
if (!val.title) { | ||
console.log(json); | ||
} | ||
obj.title = val.title; | ||
obj.title = val.title[0]._; | ||
if (val.content) { | ||
obj.desc = val.content; | ||
} else if (val.summary) { | ||
obj.desc = val.summary; | ||
obj.summary = val.content[0]._; | ||
} | ||
@@ -250,3 +259,3 @@ var categories = []; | ||
_.each(val.link, function (val, i) { | ||
if (val.rel == 'alternate') { | ||
if (val.rel === 'self') { | ||
link = val.href; | ||
@@ -263,8 +272,5 @@ } | ||
//lets try basis js date parsing for now | ||
obj.date = Date.parse(val.published); | ||
obj.published_at = Date.parse(val.published[0]); | ||
obj.time_ago = DateHelper.time_ago_in_words(obj.published_at); | ||
} | ||
if (val.updated) { | ||
//lets try basis js date parsing for now | ||
obj.updated = Date.parse(val.updated); | ||
} | ||
//now push the obj onto the stack | ||
@@ -280,4 +286,4 @@ output.items.push(obj); | ||
// Ruby strftime: %b %d, %Y %H:%M:%S GMT | ||
time_ago_in_words_with_parsing: function(from) { | ||
var date = new Date; | ||
time_ago_in_words_with_parsing:function (from) { | ||
var date = new Date(); | ||
date.setTime(Date.parse(from)); | ||
@@ -288,7 +294,7 @@ return this.time_ago_in_words(date); | ||
// DateHelper.time_ago_in_words(1331079503000) | ||
time_ago_in_words: function(from) { | ||
return this.distance_of_time_in_words(new Date, from); | ||
time_ago_in_words:function (from) { | ||
return this.distance_of_time_in_words(new Date(), from); | ||
}, | ||
distance_of_time_in_words: function(to, from) { | ||
distance_of_time_in_words:function (to, from) { | ||
var distance_in_seconds = ((to - from) / 1000); | ||
@@ -298,13 +304,32 @@ var distance_in_minutes = Math.floor(distance_in_seconds / 60); | ||
distance_in_minutes = Math.abs(distance_in_minutes); | ||
if (distance_in_minutes == 0) { return 'less than a minute'+tense; } | ||
if (distance_in_minutes == 1) { return 'a minute'+tense; } | ||
if (distance_in_minutes < 45) { return distance_in_minutes + ' minutes'+tense; } | ||
if (distance_in_minutes < 90) { return 'about an hour'+tense; } | ||
if (distance_in_minutes < 1440) { return 'about ' + Math.floor(distance_in_minutes / 60) + ' hours'+tense; } | ||
if (distance_in_minutes < 2880) { return 'a day'+tense; } | ||
if (distance_in_minutes < 43200) { return Math.floor(distance_in_minutes / 1440) + ' days'+tense; } | ||
if (distance_in_minutes < 86400) { return 'about a month'+tense; } | ||
if (distance_in_minutes < 525960) { return Math.floor(distance_in_minutes / 43200) + ' months'+tense; } | ||
if (distance_in_minutes < 1051199) { return 'about a year'+tense; } | ||
if (distance_in_minutes === 0) { | ||
return 'less than a minute' + tense; | ||
} | ||
if (distance_in_minutes === 1) { | ||
return 'a minute' + tense; | ||
} | ||
if (distance_in_minutes < 45) { | ||
return distance_in_minutes + ' minutes' + tense; | ||
} | ||
if (distance_in_minutes < 90) { | ||
return 'about an hour' + tense; | ||
} | ||
if (distance_in_minutes < 1440) { | ||
return 'about ' + Math.floor(distance_in_minutes / 60) + ' hours' + tense; | ||
} | ||
if (distance_in_minutes < 2880) { | ||
return 'a day' + tense; | ||
} | ||
if (distance_in_minutes < 43200) { | ||
return Math.floor(distance_in_minutes / 1440) + ' days' + tense; | ||
} | ||
if (distance_in_minutes < 86400) { | ||
return 'about a month' + tense; | ||
} | ||
if (distance_in_minutes < 525960) { | ||
return Math.floor(distance_in_minutes / 43200) + ' months' + tense; | ||
} | ||
if (distance_in_minutes < 1051199) { | ||
return 'about a year' + tense; | ||
} | ||
return 'over ' + Math.floor(distance_in_minutes / 525960) + ' years'; | ||
@@ -311,0 +336,0 @@ } |
{ | ||
"name": "rssparser", | ||
"version": "0.0.15", | ||
"version": "0.0.2", | ||
"dependencies": { | ||
@@ -5,0 +5,0 @@ "xml2js": { |
{ | ||
"name": "rssparser", | ||
"version": "0.0.1", | ||
"description": "rssparser is an all purpose RSS/ATOM feed parser that parses feeds into a common format so that you do not have to care if they are RSS or ATOM feeds.", | ||
"version": "0.0.2", | ||
"description": "rssparser is an all purpose RSS/ATOM feed parser that parses feeds into a JSON format.", | ||
"keywords": [ | ||
@@ -29,4 +29,4 @@ "rss", | ||
"readmeFilename": "README.md", | ||
"_id": "rssparser@0.0.1", | ||
"_id": "rssparser@0.0.2", | ||
"_from": "rssparser" | ||
} |
node-rssparser | ||
---------------- | ||
rssparser is a RSS/ATOM feed parser that returns the requested feed urls in a json object that is formatted so that you will not have to worry (much) about the format of the requested feed. | ||
rssparser is a RSS/ATOM feed parser that returns the requested feed urls in a simple json object | ||
Motivation | ||
---------- | ||
RSS and ATOM feeds are both trying to deliver similar content, but are different enough with their structure to be aggravating. The purpose of rssparser is to allow for the important parts of the feeds (article titles, links, etc) to be returned in a standard format, but to also return the rest of the feed in a reasonable way. | ||
Installing | ||
@@ -32,6 +27,2 @@ ---------- | ||
}); | ||
//atom feeds | ||
parser.parseURL('http://www.blogger.com/feeds/10861780/posts/default', options, function(err, out){ | ||
console.log(out); | ||
}); | ||
``` | ||
@@ -50,11 +41,19 @@ | ||
title: Title of the feed | ||
desc: description or subtitle | ||
description: description or subtitle | ||
url: url of the feed | ||
update: pubDate or update time of the feed | ||
last_modified: pubDate or update time of the feed | ||
items:[ | ||
{ | ||
title: Title of article | ||
desc: Description or content of article | ||
link: Link to article | ||
date: Time article was published | ||
summary : Summary or content of article | ||
url : Url of the article | ||
categories : Categories of the article | ||
published_at: published date in relative | ||
time_ago: time in words | ||
author: name of the author | ||
guid | ||
{ | ||
link : link of the article | ||
isPermaLink : isPermaLink true or false | ||
} | ||
}... | ||
@@ -61,0 +60,0 @@ ] |
@@ -0,0 +0,0 @@ // string test.js |
AI-detected possible typosquat
Supply chain riskAI has identified this package as a potential typosquat of a more popular package. This suggests that the package may be intentionally mimicking another package's name, description, or other metadata.
Found 1 instance in 1 package
15376
393
73
1