Last active
October 28, 2018 05:11
-
-
Save akoskovacs/fd3319bfb009577e771d2e83c7fc1098 to your computer and use it in GitHub Desktop.
Plain Reddit reader for the console with Node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// esversion: 6; | |
/// SETTINGS /// | |
// Maximum number of posts to be showed | |
const MAX_COUNT = 10; | |
// List of the subreddits, the desired sort order (multiple is allowed) | |
// and count of posts | |
const SUBREDDITS = [ | |
{ | |
name: 'spacex', | |
action: ['new'], | |
count: MAX_COUNT | |
}, | |
{ | |
name: 'europe', | |
action: ['top'], | |
count: MAX_COUNT | |
} | |
]; | |
/// END OF SETTINGS /// | |
/// ... BLA BLA CODE ... /// | |
const https = require('https'); | |
const colors = require('colors'); | |
const HOST = "https://www.reddit.com"; | |
const URI = "/r/$S/$A.json"; | |
const ERROR_INVALID_POST = -3; | |
const ERROR_BAD_ACTION = -2; | |
const ERROR_INVALID_DATA = -1; | |
class SubReddit { | |
constructor(name) { | |
this.name = name || "all"; | |
} | |
isValidAction(action) { | |
const ACTIONS = ['new', 'top', 'hot', 'controversial', 'rising']; | |
return ACTIONS.includes(action); | |
} | |
fetchTopPosts(count) { return this.fetchPosts('top', count); } | |
fetchNew(count) { return this.fetchPosts('new', count); } | |
fetchHotPosts(count) { return this.fetchPosts('hot', count); } | |
getURI(action) { | |
return URI.replace('$S', this.name) | |
.replace('$A', action || 'new'); | |
} | |
getURL(action) { | |
return HOST + this.getURI(action); | |
} | |
fetchPosts(action, count) { | |
if (this.isValidAction(action)) { | |
return this._fetchPosts(this.getURL(action || 'top'), count); | |
} else { | |
return Promise.reject([ERROR_BAD_ACTION, "Bad action"]); | |
} | |
} | |
_fetchPosts(requestURL, count) { | |
// console.log("Fetching: ", requestURL); | |
return new Promise((resolve, reject) => { | |
count = count || MAX_COUNT; | |
https.get(requestURL, (r) => { | |
const { statusCode } = r; | |
if (statusCode !== 200) { | |
reject([statusCode, `Houston, we have problem! (status code ${statusCode})`]); | |
return; | |
} | |
r.setEncoding('utf-8'); | |
let rawData = ''; | |
r.on('data', (chunk) => { rawData += chunk; }); | |
r.on('end', () => { | |
const listing = JSON.parse(rawData); | |
if (!listing || !listing.data || !listing.data.children) { | |
reject([ERROR_INVALID_DATA, `Houston, we have problem! (status code ${statusCode})`]); | |
return; | |
} | |
const jsonPosts = listing.data.children; | |
let posts = []; | |
for (let i = 0; i < count; i++) { | |
let jsonPost = jsonPosts[i]; | |
if (!jsonPost || !jsonPost.data || !jsonPost.data.title || !jsonPost.data.url) { | |
reject([ERROR_INVALID_POST, `Houston, we have a main bus A undervolt! (invalid post data)`]); | |
return; | |
} | |
posts.push(new Post(jsonPosts[i].data.title, jsonPosts[i].data.url)); | |
} | |
resolve(posts); | |
}); | |
}); | |
}); | |
} | |
} | |
class Post { | |
constructor(title, url) { | |
this.title = title || null; | |
this.url = url || null; | |
} | |
prettyPrint() { | |
console.log(this.toPrettyString()); | |
} | |
toPrettyString() { | |
return ` ${this.title.green.bold}\n\t\t${this.url.blue.underline}\n`; | |
} | |
} | |
/// MAIN /// | |
SUBREDDITS.forEach((sub) => { | |
const { name, count, action } = sub; | |
let sr = new SubReddit(name); | |
action.forEach((act) => { | |
sr.fetchPosts(act, count) | |
.then((posts) => { | |
console.log(colors.cyan.bold(`Showing ${count} posts for r/${name}, sorted by '${act}'\n`)); | |
posts.forEach((post) => { | |
post.prettyPrint(); | |
}); | |
}) | |
.catch((error) => { | |
console.error(colors.red("Error: " + error[1])); | |
}); | |
}); | |
}); | |
/// QED /// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment