Jason Botello

reddit shell: web based ssh emulator for programmatic redditing

reddit shell is a pretty simple web based linux shell emulator that allows you to browse reddit programmatically via command line. http://redditshell.com/

It works entirely off JSON requests to reddit that are then parsed, formatted, stored, and associated with new commands for future use. This project is 100% front end, which is nice and a change from what I normally do.

The terminal emulation is from the awesome jquery.terminal plugin by jcubic which you can find here: http://terminal.jcubic.pl/

As of writing this post, reddit shell can list posts from any public subreddit, navigate through page history for those posts, sort posts by new/top/rising/controversial, open the content for any post in a new window, view the comments for any public post, view individual comment trees, search reddit, and list all public subreddits.

All commands start from the retrieval of a JSON object from reddit, which is then parsed and utilized for the specified command. Here's the block that grabs posts on the front page:

$.getJSON('http://www.reddit.com/.json?jsonp=?', function(data) {
    var redditjson = data.data.children;
    $(redditjson).each(function() {
      if (this.data != undefined) {
        permalink = "http://reddit.com"+this.data.permalink;
        url = this.data.url;
        content.push(url);
        posts.push(permalink);
        // line 1
        title = this.data.title;
        domain = this.data.domain;
        if (this.data.thumbnail && this.data.thumbnail.indexOf("http") > -1) {
          image = this.data.thumbnail;
        } else {
          image = false;
        }
        subreddit = this.data.subreddit;
        if (url) {
          line1 = "<div style='width:100%;float:left;'>[<span style='color: #2C9A96;'>" + c + "</span>] <a href='"+url+"' target='_blank'>"+title + "</a> (" + domain + ")<br />";
        } else {
          line1 = title + " (" + domain + ")<br />";
        }

        if (image && showimages) {
          line1 = line1 + "<img src='" + image + "' style='float: left;margin: 10px;' /><br />";
        }
        // line 2
        created = this.data.created_utc;
        time = moment.unix(created).fromNow();
        author = this.data.author;
        line2 = "<span style='color: #666;'>submitted " + time + " by " + author + " to /r/" + subreddit + "</span><br />";
        // line 3
        ups = this.data.ups;
        num_comments = this.data.num_comments;
        line3 = "<span style='color: #666;'>" + ups + " upvotes with " + num_comments + " comments</span><p/>";
        frontpage = line1 + line2 + line3 + '</div>';
        c = c + 1;
        term.echo(frontpage, {raw:true});
      }
    });
    var after = data.data.after;
    var before = data.data.before;
    if (before != null) {
      permalink = "https://www.reddit.com/.json?count="+c+"&before="+before+"&jsonp=?";
      previous = permalink;
      previous_line = "<span>[<span style='color: #B3A600;'>previous</span>]<p />";
      term.echo(previous_line, {raw:true});
    }
    if (after != null) {
      permalink = "https://www.reddit.com/.json?count="+c+"&after="+after+"&jsonp=?";
      next = permalink;
      next_line = "<span>[<span style='color: #B3A600;'>next</span>]<p />";
      term.echo(next_line, {raw:true});
      term.set_prompt('[guest@reddit ~]# ');
    }
  });

As you can see, it's formatting object data into blocks of HTML and then storing data you'll need for future commands into global arrays and variables, depending on context. It's not amazingly sophisticated, but it does a good job of using data when it needs to and then releasing it after so as not to confuse namespaces or use a lot of memory.

That's essentially what the whole code base is - just a bunch of rules tied to the existence of certain JSON data. reddit has a fantastic open API that they make available, which allows for a deep integration like this. Kudos reddit.

Future plans for reddit shell will probably include as close to a 100% experience as possible. This means being able to login, comment, vote, post, etc. All that fun stuff. If you'd like to help with the development or want to look over the code, the project is on GitHub! Fork it up! https://github.com/jasonbio/reddit-shell

There's an easter egg waiting for anyone who tries entering dangerous linux commands as well :)

Posted

This article is my 2nd oldest. It is 580 words long.