New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hacka-news

Package Overview
Dependencies
Maintainers
1
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hacka-news - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

17

package.json
{
"name": "hacka-news",
"version": "1.0.0",
"description": "Hacker News command line reader.",
"version": "1.1.0",
"description": "npm module for loading and organizing content from the official Hacker News API.",
"main": "src/hacka-news.js",
"preferGlobal": "true",
"bin" : {
"hacka-news" : "./bin/index.js"
},
"dependencies": {
"colors": "^1.1.2",
"commander": "^2.9.0",
"request": "^2.60.0"
},
"devDependencies": {},
"scripts": {

@@ -29,5 +22,5 @@ "test": "echo \"Error: no test specified\" && exit 1"

"viewer",
"command",
"line",
"cli"
"request",
"api",
"module"
],

@@ -34,0 +27,0 @@ "author": "James Cote",

# hacka-news
-----------------
A command line interface (CLI) for [Hacker News](https://news.ycombinator.com/) that utilizes [their official API](https://github.com/HackerNews/API) and node.js.
A node module that utilizes the [Hacker News](https://news.ycombinator.com/) [official API](https://github.com/HackerNews/API) and powers [my command line app (of similar name)](https://github.com/Coteh/hacka-news-cli).
## Features
- Print out stories from HN feeds (top, new, ask, show, and job)
- View info for individual story specified by ID
- View stories by headline only or with verbosity
- Display url for a specified post
- Save/load HN stories to/from favourites, which are stored as a local JSON state in program's directory
- Print out list of stories that have been favourited
- Returns results from HN feeds (top, new, ask, show, and job)
- Returns stories in either parsed or unparsed JSON
- Return a story url for post of ID

@@ -21,6 +18,3 @@ ## Installation

## Future Additions
- Filter feed results by tags or url
- Open browser window for story
- Story caching: Save stories from feeds to cache
- Render HTML page for stories
- Save to Pocket integration
- Filter feed results by story url or some other method of organization
- More soon...
var request = require('request');
var fs = require('fs');
var cli_display = require('./cli-display')
var HACKA_API_URL = "https://hacker-news.firebaseio.com/v0/";
var HACKA_URL = "https://news.ycombinator.com/";
var MAX_LIST_STORIES = 500; //The official HN API only stores up to 500 top/new stories
var savedIDS = [];
var hackaAPIURL = "https://hacker-news.firebaseio.com/v0/";
var amtOfFeedStories = 10;
var jsonObject = null;
var writeJSON = function(serialized, callback){
fs.writeFile("saved-posts.json", serialized, function(err) {
if (err){
console.log("ERROR: Could not save file.");
return;
}
callback(err);
});
}
var getAmountOfFeedStories = function(){
return amtOfFeedStories;
};
var openSavedPostsJSON = function(){
var data = fs.readFileSync("saved-posts.json", {encoding: 'utf-8'});
jsonObject = JSON.parse(data);
if (jsonObject.ids != null){
setSavedPostIDS(jsonObject.ids);
}
}
var getURL = function(id){
return HACKA_URL + "item?id=" + id;
};
var getSavedPostID = function(index){
if (isNaN(index)){
throw -1;
}else if (index >= savedIDS.length){
throw -2;
}
return savedIDS[index];
}
var setAPIURL = function(url){
hackaAPIURL = url;
};
var setSavedPostIDS = function(savedList){
for (var i = 0; i < savedList.length; i++){
savedIDS.push(savedList[i]);
}
}
var savePostID = function(postID){
openSavedPostsJSON();
savedIDS.push(postID);
jsonObject.ids = savedIDS;
var jsonSerialized = JSON.stringify(jsonObject);
writeJSON(jsonSerialized, function(err){
console.log("Successfully added post of ID " + postID + " to favourites.");
});
}
var unsavePostID = function(postID){
openSavedPostsJSON();
var index = savedIDS.indexOf(postID);
if (index <= -1){
console.log("Could not find a post of this ID saved in your favourites.");
return;
}
savedIDS.splice(index, 1);
jsonObject.ids = savedIDS;
var jsonSerialized = JSON.stringify(jsonObject);
writeJSON(jsonSerialized, function(err){
console.log("Successfully removed post of ID " + postID + " from favourites.");
});
}
var requestFeedStoryIDs = function(storyType, callback){
request(HACKA_API_URL + storyType + "stories.json?print=pretty", function(error, response, body) {
if (error){
console.log("ERROR: Couldn't load " + storyType + " stories.");
return;
}
ids = JSON.parse(body);
callback(ids);
});
}
request(hackaAPIURL + storyType + "stories.json?print=pretty", function(error, response, body) {
if (error){
console.log("ERROR: Couldn't load " + storyType + " stories.");
return;
}
ids = JSON.parse(body);
callback(ids);
});
};
var requestStory = function(id, callback){
request(HACKA_API_URL + "item/" + id + ".json?print=pretty", function (error, response, body) {
if (error){
console.log("ERROR: Couldn't load story.");
return;
}
callback(body);
});
}
request(hackaAPIURL + "item/" + id + ".json?print=pretty", function (error, response, body) {
if (error){
console.log("ERROR: Couldn't load story.");
return;
}
callback(body);
});
};
var requestStoryParsed = function(id, callback){
requestStory(id, function(hnJsonStr){
var parsedStory = JSON.parse(hnJsonStr);
injectStoryExtras(parsedStory, callback);
// callback(parsedStory);
});
}
requestStory(id, function(hnJsonStr){
var parsedStory = JSON.parse(hnJsonStr);
injectStoryExtras(parsedStory, callback);
// callback(parsedStory);
});
};
var injectStoryExtras = function(parsedStory, callback) {
parsedStory.commentsUrl = getURL(parsedStory.id); //injecting comments url address into the node
if (parsedStory.type == "comment"){
requestRootParent(parsedStory, function(rootParent){
parsedStory.rootParent = rootParent;
callback(parsedStory);
});
}else if (parsedStory.type == "poll"){
requestPollOptions(parsedStory, function(pollOptArr){
parsedStory.partNodes = pollOptArr;
callback(parsedStory);
});
}else{
callback(parsedStory);
}
}
parsedStory.commentsUrl = getURL(parsedStory.id); //injecting comments url address into the node
if (parsedStory.type == "comment"){
requestRootParent(parsedStory, function(rootParent){
parsedStory.rootParent = rootParent;
callback(parsedStory);
});
}else if (parsedStory.type == "poll"){
requestPollOptions(parsedStory, function(pollOptArr){
parsedStory.partNodes = pollOptArr;
callback(parsedStory);
});
}else{
callback(parsedStory);
}
};
var requestRootParent = function(childNode, callback){
if (childNode == null){
console.log("ERROR: Child node is null.");
return;
}
//Get root parent of post (which, for a comment, should be the article they commented on)
var rootParent = childNode;
while (rootParent.parent != null){
rootParent = rootParent.parent;
// console.log(rootParent);
}
requestStoryParsed(rootParent, function(parsed){
callback(parsed);
});
}
if (childNode == null){
console.log("ERROR: Child node is null.");
return;
}
//Get root parent of post (which, for a comment, should be the article they commented on)
var rootParent = childNode;
while (rootParent.parent != null){
rootParent = rootParent.parent;
// console.log(rootParent);
}
requestStoryParsed(rootParent, function(parsed){
callback(parsed);
});
};
var requestPollOptions = function(pollNode, callback){
if (pollNode == null){
console.log("ERROR: Poll node is null.");
return;
}
var pollOptNodes = new Array();
for (var i = 0; i < pollNode.parts.length; i++){
//Get each pollopt
requestStoryParsed(pollNode.parts[i], function(parsedPollOpt){
pollOptNodes.push(parsedPollOpt);
if (pollOptNodes.length >= pollNode.parts.length){
callback(pollOptNodes);
}
});
}
}
if (pollNode == null){
console.log("ERROR: Poll node is null.");
return;
}
var pollOptNodes = new Array();
for (var i = 0; i < pollNode.parts.length; i++){
//Get each pollopt
requestStoryParsed(pollNode.parts[i], function(parsedPollOpt){
pollOptNodes.push(parsedPollOpt);
if (pollOptNodes.length >= pollNode.parts.length){
callback(pollOptNodes);
}
});
}
};
var requestGroup = function(idList, callback){
var loadedList = [];
var loadedCount = 0;
var expectedCount = idList.length;
for (var i = 0; i < idList.length; i++){
loadedList.push(null);
(function(index){
requestStoryParsed(idList[index], function(hnJson){
loadedList[index] = hnJson;
loadedCount++;
if (loadedCount >= expectedCount){
callback(loadedList);
}
});
})(i);
}
}
var getURL = function(id){
return HACKA_URL + "item?id=" + id;
}
var printFavourites = function(flags){
requestGroup(savedIDS, function(loadedContents){
for (var i = 0; i < loadedContents.length; i++){
if (loadedContents[i] == null){
console.log("ERROR: Story couldn't load.");
continue;
}
cli_display.displayContent(loadedContents[i], flags);
var loadedList = [];
var loadedCount = 0;
var expectedCount = idList.length;
for (var i = 0; i < idList.length; i++){
loadedList.push(null);
(function(index){
requestStoryParsed(idList[index], function(hnJson){
loadedList[index] = hnJson;
loadedCount++;
if (loadedCount >= expectedCount){
callback(loadedList);
}
});
})(i);
}
});
}
};
var printFeed = function(storyType, flags){
requestFeedStoryIDs(storyType, function(ids){
if (ids == null){
console.log("ERROR: Stories from " + storyType + " could not load.");
return;
} else if (ids.error) {
console.log("ERROR: " + ids.error + ".");
return;
var fetchTopID = function(index, callback) {
if (index < 0 || index >= MAX_LIST_STORIES){
throw -1;
}
var prunedIDs = ids.slice(0, amtOfFeedStories);
requestGroup(prunedIDs, function(loadedContents){
for (var i = 0; i < loadedContents.length; i++){
if (loadedContents[i] == null){
console.log("ERROR: Story couldn't load.");
continue;
requestFeedStoryIDs("top", function(ids){
if (ids == null){
console.log("ERROR: Top stories did not load.");
return;
}
cli_display.displayContent(loadedContents[i], flags);
}
callback(ids[index]);
});
});
}
};
var printStory = function(id, flags){
requestStoryParsed(id, function(hnJson){
cli_display.displayContent(hnJson, flags);
});
}
var fetchTopID = function(index, callback) {
if (index < 0 || index >= MAX_LIST_STORIES){
throw -1;
}
requestTopStoryIDs(function(ids){
if (ids == null){
console.log("ERROR: Top stories did not load.");
return;
}
callback(ids[index]);
});
}
var fetchTopURL = function(index, callback) {
fetchTopID(index, function(id){
callback(getURL(id));
});
}
fetchTopID(index, function(id){
callback(getURL(id));
});
};
module.exports = {
openSavedPostsJSON,
getSavedPostID,
setSavedPostIDS,
savePostID,
unsavePostID,
getURL,
printFavourites,
printFeed,
printStory,
fetchTopID,
fetchTopURL
}
getAmountOfFeedStories,
getURL,
setAPIURL,
requestFeedStoryIDs,
requestStory,
requestStoryParsed,
requestGroup,
fetchTopID,
fetchTopURL
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc