Skip to content

Instantly share code, notes, and snippets.

@akoskovacs
Last active October 28, 2018 05:11
Show Gist options
  • Save akoskovacs/fd3319bfb009577e771d2e83c7fc1098 to your computer and use it in GitHub Desktop.
Save akoskovacs/fd3319bfb009577e771d2e83c7fc1098 to your computer and use it in GitHub Desktop.
Plain Reddit reader for the console with Node.js
// 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