Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Adding .gitignore

  • Loading branch information...
commit a10d19fdad4d3f80a69e22c605a65034be1f2ac4 1 parent 898cba6
@steveklabnik steveklabnik authored
View
1  .gitignore
@@ -0,0 +1 @@
+.bundle
View
102 controllers/content_controller.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>content_controller.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="content_controller.html">content_controller.rb</a>
+ <a class="source" href="hackers_controller.html">hackers_controller.rb</a>
+ <a class="source" href="messages_controller.html">messages_controller.rb</a>
+ <a class="source" href="programs_controller.html">programs_controller.rb</a>
+ <a class="source" href="sessions_controller.html">sessions_controller.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>content_controller.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p> This is the controller that handles all of the different kinds of Content
+ posted to the site.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> We need a simple GET action that displays the given Content.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/content/:id&quot;</span> <span class="k">do</span>
+ <span class="vi">@content</span> <span class="o">=</span> <span class="no">Content</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">haml</span> <span class="ss">:&quot;content/show&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> We also need a simple POST that will create content.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s2">&quot;/content&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span>
+
+ <span class="n">params</span><span class="o">[</span><span class="ss">:content</span><span class="o">][</span><span class="ss">:author</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:content</span><span class="o">][</span><span class="ss">:author_email</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">email</span>
+ <span class="vi">@content</span> <span class="o">=</span> <span class="no">Content</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:content</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Thanks for your post!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/stream&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p> We&rsquo;re allowing comments to be made on posts, so we need a route for that as
+ well.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s2">&quot;/content/:id/comment&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span>
+ <span class="vi">@content</span> <span class="o">=</span> <span class="no">Content</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:id</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author_email</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">email</span>
+ <span class="vi">@content</span><span class="o">.</span><span class="n">comments</span> <span class="o">&lt;&lt;</span> <span class="no">Comment</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">]</span><span class="p">)</span>
+ <span class="vi">@content</span><span class="o">.</span><span class="n">save</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Replied!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/content/</span><span class="si">#{</span><span class="vi">@content</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
219 controllers/hackers_controller.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>hackers_controller.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="content_controller.html">content_controller.rb</a>
+ <a class="source" href="hackers_controller.html">hackers_controller.rb</a>
+ <a class="source" href="messages_controller.html">messages_controller.rb</a>
+ <a class="source" href="programs_controller.html">programs_controller.rb</a>
+ <a class="source" href="sessions_controller.html">sessions_controller.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>hackers_controller.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p>This is the &lsquo;hackers&rsquo; controller. &ldquo;Hackers&rdquo; are what we call &ldquo;Users&rdquo; in HH.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> We want to give our Hackers a profile page.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/hackers/:name&#39;</span> <span class="k">do</span>
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">haml</span> <span class="ss">:&quot;hackers/show&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> People need to be able to update their information. Of course, this means
+ that they need to be logged in.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s1">&#39;/hackers/update&#39;</span> <span class="k">do</span>
+ <span class="n">require_login!</span> <span class="ss">:return</span> <span class="o">=&gt;</span> <span class="s2">&quot;/hackers/update&quot;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p> If they&rsquo;re trying to update their password, let&rsquo;s take care of that. If we
+ don&rsquo;t, then we wouldn&rsquo;t want to set their password to nil! That&rsquo;d be bad.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">unless</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">].</span><span class="n">nil?</span>
+ <span class="k">if</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">][</span><span class="ss">:new</span><span class="o">]</span> <span class="o">==</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">][</span><span class="ss">:confirm</span><span class="o">]</span>
+ <span class="n">current_user</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">][</span><span class="ss">:new</span><span class="o">]</span>
+ <span class="n">current_user</span><span class="o">.</span><span class="n">save</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Password updated!&quot;</span>
+ <span class="k">else</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Password confirmation didn&#39;t match!&quot;</span>
+ <span class="k">end</span>
+ <span class="k">else</span>
+ <span class="n">current_user</span><span class="o">.</span><span class="n">update_attributes</span><span class="p">(</span><span class="ss">:about</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:hacker</span><span class="o">][</span><span class="ss">:about</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">current_user</span><span class="o">.</span><span class="n">save</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;About information updated!&quot;</span>
+ <span class="k">end</span>
+
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">&quot;</span>
+
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> Hackers can follow each other, and this route takes care of it!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/hackers/:name/follow&#39;</span> <span class="k">do</span>
+ <span class="n">require_login!</span> <span class="ss">:return</span> <span class="o">=&gt;</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">/follow&quot;</span>
+
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-6'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-6">#</a>
+ </div>
+ <p>make sure we&rsquo;re not following them already</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">if</span> <span class="n">current_user</span><span class="o">.</span><span class="n">following?</span> <span class="vi">@hacker</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;You&#39;re already following </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">.&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">&quot;</span>
+ <span class="k">return</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-7'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-7">#</a>
+ </div>
+ <p> then follow them!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">current_user</span><span class="o">.</span><span class="n">follow!</span> <span class="vi">@hacker</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Now following </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">.&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-8'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-8">#</a>
+ </div>
+ <p>this lets you unfollow a Hacker</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/hackers/:name/unfollow&#39;</span> <span class="k">do</span>
+ <span class="n">require_login!</span> <span class="ss">:return</span> <span class="o">=&gt;</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">/unfollow&quot;</span>
+
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-9'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-9">#</a>
+ </div>
+ <p>make sure we&rsquo;re following them already</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">unless</span> <span class="n">current_user</span><span class="o">.</span><span class="n">following?</span> <span class="vi">@hacker</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;You&#39;re already not following </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">.&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">&quot;</span>
+ <span class="k">return</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-10'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-10">#</a>
+ </div>
+ <p>unfollow them!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">current_user</span><span class="o">.</span><span class="n">unfollow!</span> <span class="vi">@hacker</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;No longer following </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">.&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-11'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-11">#</a>
+ </div>
+ <p> this lets us see followers.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/hackers/:name/followers&#39;</span> <span class="k">do</span>
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">haml</span> <span class="ss">:&quot;hackers/followers&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-12'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-12">#</a>
+ </div>
+ <p> This lets us see who is following.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/hackers/:name/following&#39;</span> <span class="k">do</span>
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">haml</span> <span class="ss">:&quot;hackers/following&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
107 controllers/messages_controller.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>messages_controller.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="content_controller.html">content_controller.rb</a>
+ <a class="source" href="hackers_controller.html">hackers_controller.rb</a>
+ <a class="source" href="messages_controller.html">messages_controller.rb</a>
+ <a class="source" href="programs_controller.html">programs_controller.rb</a>
+ <a class="source" href="sessions_controller.html">sessions_controller.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>messages_controller.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p> This is the new message form.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/messages/new/to/:username&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span>
+
+ <span class="vi">@username</span> <span class="o">=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span>
+ <span class="n">haml</span> <span class="ss">:&quot;messages/new&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> This route actually creates the messages.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s2">&quot;/messages&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> We wouldn&rsquo;t want anyone forging who messages are sent from!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">params</span><span class="o">[</span><span class="ss">:message</span><span class="o">][</span><span class="ss">:sender</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span>
+
+ <span class="n">message</span> <span class="o">=</span> <span class="no">Message</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Message sent.&quot;</span>
+
+ <span class="n">redirect</span> <span class="s2">&quot;/hackers/</span><span class="si">#{</span><span class="n">message</span><span class="o">.</span><span class="n">recipient</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p> This is the page where you can see your messages.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/messages&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> Let&rsquo;s sort them in descending order.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="vi">@messages</span> <span class="o">=</span> <span class="no">Message</span><span class="o">.</span><span class="n">all</span><span class="p">({</span><span class="s2">&quot;recipient&quot;</span> <span class="o">=&gt;</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span><span class="p">})</span><span class="o">.</span><span class="n">sort</span> <span class="k">do</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span>
+ <span class="n">b</span><span class="o">.</span><span class="n">created_at</span> <span class="o">&lt;=&gt;</span> <span class="n">a</span><span class="o">.</span><span class="n">created_at</span>
+ <span class="k">end</span>
+ <span class="n">haml</span> <span class="ss">:&quot;messages/index&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
216 controllers/programs_controller.html
@@ -0,0 +1,216 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>programs_controller.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="content_controller.html">content_controller.rb</a>
+ <a class="source" href="hackers_controller.html">hackers_controller.rb</a>
+ <a class="source" href="messages_controller.html">messages_controller.rb</a>
+ <a class="source" href="programs_controller.html">programs_controller.rb</a>
+ <a class="source" href="sessions_controller.html">sessions_controller.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>programs_controller.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p> We&rsquo;d like to let people show their programs. The routes in this file let us
+ do this.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> We&rsquo;re also going to let people write programs in the browser, just in case
+ they&rsquo;d like to share something, but the upload doesn&rsquo;t work, or they want to
+ copy on part of their program, or anything else.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/programs/new&quot;</span> <span class="k">do</span>
+ <span class="n">require_login!</span>
+ <span class="n">haml</span> <span class="ss">:&quot;programs/new&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> One of the best features of GitHub is the <a href="https://github.com/explore">Explore page</a>
+ . It shows off some neat repositories that people have made. So let&rsquo;s do
+ that, as well. We want to show both the last 10 programs that have been
+ updated, as well as some featured programs.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/programs&quot;</span> <span class="k">do</span>
+ <span class="vi">@programs</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">all</span><span class="o">.</span><span class="n">sort</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="n">b</span><span class="o">.</span><span class="n">updated_at</span> <span class="o">&lt;=&gt;</span> <span class="n">a</span><span class="o">.</span><span class="n">updated_at</span> <span class="p">}</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
+ <span class="n">haml</span> <span class="ss">:&quot;programs/index&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p> We need to let people upload programs, so here it is! We want to allow API
+ access for this particular route, since we&rsquo;ll be uploading programs from the
+ desktop application as well.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s2">&quot;/programs&quot;</span> <span class="k">do</span>
+ <span class="n">require_login_or_api!</span> <span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> Forging who made the program would be bad!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">params</span><span class="o">[</span><span class="ss">:program</span><span class="o">][</span><span class="s1">&#39;creator_username&#39;</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span>
+ <span class="n">program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:program</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Program created!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/programs/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">creator_username</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">slug</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-6'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-6">#</a>
+ </div>
+ <p> People should be able to comment on programs, and this route lets us do it.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s2">&quot;/programs/:username/:slug/comment&quot;</span> <span class="k">do</span>
+ <span class="vi">@program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:creator_username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:slug</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:slug</span><span class="o">]</span><span class="p">)</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-7'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-7">#</a>
+ </div>
+ <p> Good old anonymous comments need special care and attention.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">if</span> <span class="n">current_user</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author_email</span><span class="o">]</span> <span class="o">=</span> <span class="n">current_user</span><span class="o">.</span><span class="n">email</span>
+ <span class="k">else</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Anonymous&quot;</span>
+ <span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">][</span><span class="ss">:author_email</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;anonymous@example.com&quot;</span>
+ <span class="k">end</span>
+
+ <span class="vi">@program</span><span class="o">.</span><span class="n">comments</span> <span class="o">&lt;&lt;</span> <span class="no">Comment</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:comment</span><span class="o">]</span><span class="p">)</span>
+ <span class="vi">@program</span><span class="o">.</span><span class="n">save</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Replied!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/programs/</span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:slug</span><span class="o">]</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-8'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-8">#</a>
+ </div>
+ <p> JSON is a really great way to share information that&rsquo;s intended to be
+ consumed by someone else. This shows all of the programs a particular user
+ has made.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/programs/:username.json&quot;</span> <span class="k">do</span>
+ <span class="n">programs</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">all</span><span class="p">(</span><span class="ss">:creator_username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">programs</span><span class="o">.</span><span class="n">to_json</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-9'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-9">#</a>
+ </div>
+ <p> Each program that a user has created has its own page.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s2">&quot;/programs/:username/:slug&quot;</span> <span class="k">do</span>
+ <span class="vi">@program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:creator_username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:slug</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:slug</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">haml</span> <span class="ss">:&quot;programs/show&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-10'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-10">#</a>
+ </div>
+ <p> If your program is revised, you&rsquo;ll need to update it on the site too. We need
+ this to be API accessable, so that the desktop program can do it too!</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">put</span> <span class="s2">&quot;/programs/:username/:slug.json&quot;</span> <span class="k">do</span>
+ <span class="n">require_login_or_api!</span> <span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span>
+ <span class="k">if</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span> <span class="o">!=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span>
+ <span class="n">halt</span> <span class="mi">401</span>
+ <span class="k">end</span>
+ <span class="n">program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:creator_username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:slug</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:slug</span><span class="o">]</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">program</span><span class="o">.</span><span class="n">nil?</span>
+ <span class="n">program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
+ <span class="k">else</span>
+ <span class="n">program</span><span class="o">.</span><span class="n">update_attributes</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
+ <span class="n">program</span><span class="o">.</span><span class="n">save</span>
+ <span class="k">end</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Program updated!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/programs/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">creator_username</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">slug</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span>
+
+<span class="n">put</span> <span class="s2">&quot;/programs/:username/:slug&quot;</span> <span class="k">do</span>
+ <span class="n">require_login_or_api!</span> <span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span>
+ <span class="k">if</span> <span class="n">current_user</span><span class="o">.</span><span class="n">username</span> <span class="o">!=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Sorry, buddy&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/&quot;</span>
+ <span class="k">end</span>
+ <span class="n">program</span> <span class="o">=</span> <span class="no">Program</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:creator_username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="ss">:slug</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:slug</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">program</span><span class="o">.</span><span class="n">update_attributes</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:program</span><span class="o">]</span><span class="p">)</span>
+ <span class="n">program</span><span class="o">.</span><span class="n">save</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Program updated!&quot;</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/programs/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">creator_username</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">program</span><span class="o">.</span><span class="n">slug</span><span class="si">}</span><span class="s2">&quot;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
247 controllers/sessions_controller.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>sessions_controller.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="content_controller.html">content_controller.rb</a>
+ <a class="source" href="hackers_controller.html">hackers_controller.rb</a>
+ <a class="source" href="messages_controller.html">messages_controller.rb</a>
+ <a class="source" href="programs_controller.html">programs_controller.rb</a>
+ <a class="source" href="sessions_controller.html">sessions_controller.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>sessions_controller.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p>The session controller deals with users loggin in, logging out, and
+signing up. An important part of the site!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> New users sign up at /signup</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/signup&#39;</span> <span class="k">do</span>
+ <span class="n">haml</span> <span class="ss">:&quot;sessions/signup&quot;</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=&gt;</span> <span class="ss">:plain</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> The form for /signup sends a POST to /signup!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s1">&#39;/signup&#39;</span> <span class="k">do</span>
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:user</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="vi">@hacker</span> <span class="o">&amp;&amp;</span> <span class="vi">@hacker</span><span class="o">.</span><span class="n">valid?</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p>let&rsquo;s log them in, too.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span> <span class="o">=</span> <span class="vi">@hacker</span><span class="o">.</span><span class="n">id</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Account created.&quot;</span>
+ <span class="n">redirect</span> <span class="s1">&#39;/&#39;</span>
+ <span class="k">else</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s1">&#39;There were some problems creating your account. Please be sure you\&#39;ve entered all your information correctly.&#39;</span>
+
+ <span class="n">redirect</span> <span class="s1">&#39;/download&#39;</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> People can log in by going to /login</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/login&#39;</span> <span class="k">do</span>
+ <span class="n">haml</span> <span class="ss">:&quot;sessions/login&quot;</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=&gt;</span> <span class="ss">:plain</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-6'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-6">#</a>
+ </div>
+ <p> The form at /login sends a POST request to /login</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s1">&#39;/login&#39;</span> <span class="k">do</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-7'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-7">#</a>
+ </div>
+ <p>let&rsquo;s see if we got a correct username/password:</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">if</span> <span class="n">hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span> <span class="o">=</span> <span class="n">hacker</span><span class="o">.</span><span class="n">id</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Login successful.&quot;</span>
+
+ <span class="k">if</span> <span class="n">session</span><span class="o">[</span><span class="ss">:return_to</span><span class="o">]</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-8'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-8">#</a>
+ </div>
+ <p> Let&rsquo;s return back to where we were before.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">redirect_url</span> <span class="o">=</span> <span class="n">session</span><span class="o">[</span><span class="ss">:return_to</span><span class="o">]</span>
+ <span class="n">session</span><span class="o">[</span><span class="ss">:return_to</span><span class="o">]</span> <span class="o">=</span> <span class="kp">false</span>
+ <span class="n">redirect</span> <span class="n">redirect_url</span>
+ <span class="k">else</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-9'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-9">#</a>
+ </div>
+ <p> If we didn&rsquo;t go somewhere special, let&rsquo;s just go to the stream</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">redirect</span> <span class="s1">&#39;/stream&#39;</span>
+ <span class="k">end</span>
+ <span class="k">else</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;The username or password you entered is incorrect.&quot;</span>
+ <span class="n">redirect</span> <span class="s1">&#39;/login&#39;</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-10'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-10">#</a>
+ </div>
+ <p> Users can logout by going to /logout</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/logout&#39;</span> <span class="k">do</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-11'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-11">#</a>
+ </div>
+ <p>we need to remove our id from the session</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span> <span class="o">=</span> <span class="kp">nil</span>
+
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:notice</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Logout successful.&quot;</span>
+ <span class="n">redirect</span> <span class="s1">&#39;/&#39;</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-12'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-12">#</a>
+ </div>
+ <p> This method allows people to check their credentials. This is primarily used
+ by the desktop app to see if you&rsquo;ve entered correct information.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s1">&#39;/check_credentials&#39;</span> <span class="k">do</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-13'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-13">#</a>
+ </div>
+ <p>let&rsquo;s see if we got a correct username/password:</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">if</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
+ <span class="s2">&quot;Success&quot;</span>
+ <span class="k">else</span>
+ <span class="n">halt</span> <span class="mi">401</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-14'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-14">#</a>
+ </div>
+ <p> This method will let people sign up from within the app. Frankly this is
+ a really bad way to do it, but I&rsquo;m not sure what the best way is. It should
+ be combined with the signup method above. The issue is that signup via the
+ API should really just throw the message rather than redirect, but the site
+ should redirect. This probably should be managed via content negotiation. I&rsquo;m
+ doing it the dirty way now, and when I look at exposing a Real Api I&rsquo;ll worry
+ about making it 100% nice.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">post</span> <span class="s1">&#39;/signup_via_api&#39;</span> <span class="k">do</span>
+ <span class="vi">@hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span>
+ <span class="ss">:email</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:email</span><span class="o">]</span><span class="p">,</span>
+ <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="k">if</span> <span class="vi">@hacker</span> <span class="o">&amp;&amp;</span> <span class="vi">@hacker</span><span class="o">.</span><span class="n">valid?</span>
+ <span class="s2">&quot;Success&quot;</span>
+ <span class="k">else</span>
+ <span class="mi">404</span> <span class="c1">#is this right?</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
448 hackety.html
@@ -0,0 +1,448 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>hackety.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="hackety.html">hackety.rb</a>
+ <a class="source" href="helpers.html">helpers.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>hackety.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p> encoding: utf-8</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> This is the source code for the <a href="http://hackety-hack.com">Hackety Hack website</a>. Hackety Hack is
+ the easiest way to learn programming, and so our documentation should be
+ top-notch.</p>
+
+<p> To get started, you&rsquo;ll need to install some prerequisite software:</p>
+
+<p> <strong>Ruby</strong> is used to power the site. We&rsquo;re currently using ruby 1.9.2p0. I
+ highly reccomend that you use <a href="http://rvm.beginrescueend.com/">rvm</a> to install and manage your Rubies.
+ It&rsquo;s a fantastic tool. If you do decide to use <code>rvm</code>, you can install the
+ appropriate Ruby and create a gemset by simply <code>cd</code>-ing into the root project
+ directory; I have a magical <code>.rvmrc</code> file that&rsquo;ll set you up.</p>
+
+<p> <strong>MongoDB</strong> is a really awesome document store. We use it to persist all of
+ the data on the website. To get MongoDB, please visit their
+ <a href="http://www.mongodb.org/downloads">downloads page</a> to find a package for your
+ system.</p>
+
+<p> After installing Ruby and MongoDB, you need to aquire all of the Ruby gems
+ that we use. This is pretty easy, since we&rsquo;re using <strong>bundler</strong>. Just do
+ this:</p>
+
+<pre><code> $ gem install bundler
+ $ bundle install
+</code></pre>
+
+<p> That&rsquo;ll set it all up! Then, you need to make sure you&rsquo;re running MongoDB.
+ I have to open up another tab in my terminal and type</p>
+
+<pre><code> $ mongod
+</code></pre>
+
+<p> to get this to happen. When you&rsquo;re done hacking, you can hit ^-c to stop
+ <code>mongod</code> from running.</p>
+
+<p> To actually start up the site, just</p>
+
+<pre><code> $ rackup
+</code></pre>
+
+<p> and then visit <a href="http://localhost:9292">http://localhost:9292/</a>. You&rsquo;re good
+ to go!</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <h3>About hackety.rb</h3>
+
+<p> This file is the main entry point to the application. It has three main
+ purposes:</p>
+
+<ol>
+<li>Include all relevant gems and library code.</li>
+<li>Configure all settings based on our environment.</li>
+<li>Set up a few basic routes.</li>
+</ol>
+
+
+<p> Everything else is handled by code that&rsquo;s included from this file.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <h3>Including gems</h3>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> We need to require rubygems and bundler to get things going. Then we call
+ <code>Bundler.setup</code> to get all of the magic started.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
+<span class="nb">require</span> <span class="s1">&#39;bundler&#39;</span>
+<span class="no">Bundler</span><span class="o">.</span><span class="n">setup</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-6'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-6">#</a>
+ </div>
+ <p> We use <a href="http://sinatrarb.com/">sinatra</a> for our web framework. Sinatra is
+ very light and simple. Good stuff.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;sinatra&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-7'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-7">#</a>
+ </div>
+ <p> <a href="https://github.com/adamwiggins/pony">Pony</a> is used to send emails, just like the Pony express. Also, running <code>gem install pony</code> is really satisfying.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;pony&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-8'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-8">#</a>
+ </div>
+ <p> <a href="http://haml-lang.com/">haml</a> creates all of our templates. haml is concise
+ and expressive. I really enjoy it.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;haml&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-9'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-9">#</a>
+ </div>
+ <p> <a href="http://mongomapper.com/">MongoMapper</a> is a library we use to make it easy to
+ store our model classes into MongoDB.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;mongo_mapper&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-10'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-10">#</a>
+ </div>
+ <p> We need a secret for our sessions. This is set via an environment variable so
+ that we don&rsquo;t have to give it away in the source code. Heroku makes it really
+ easy to keep environment variables set up, so this ends up being pretty nice.
+ This also has to be included before rack-flash, or it blows up.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Session</span><span class="o">::</span><span class="no">Cookie</span><span class="p">,</span> <span class="ss">:secret</span> <span class="o">=&gt;</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;COOKIE_SECRET&#39;</span><span class="o">]</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-11'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-11">#</a>
+ </div>
+ <p> If you&rsquo;ve used Rails' flash messages, you know how convenient they are.
+ rack-flash lets us use them.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;rack-flash&#39;</span>
+<span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Flash</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-12'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-12">#</a>
+ </div>
+ <p> <a href="https://github.com/rtomayko/rdiscount">rdiscount</a> is a fast implementation
+ of the Markdown markup language. The web site renders most user submitted
+ comment with Markdown.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;rdiscount&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-13'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-13">#</a>
+ </div>
+ <p> Rails has a <code>content_for</code> helper that lets you place different parts of your
+ view into different places in your template. This helps a lot with
+ javascript, and conditional stylesheets or other includes. It&rsquo;s so nice that
+ foca has written
+ <a href="https://github.com/foca/sinatra-content-for">a Sinatra version</a>.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;sinatra/content_for&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-14'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-14">#</a>
+ </div>
+ <p> We moved lots of helpers into a separate file. These are all things that are
+ useful throughout the rest of the application. This file</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">require_relative</span> <span class="s1">&#39;helpers&#39;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-15'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-15">#</a>
+ </div>
+ <h3>Configure settings</h3>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-16'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-16">#</a>
+ </div>
+ <p> We use <a href="http://www.getexceptional.com/">Exceptional</a> to keep track of errors
+ that happen. This code is from their
+ <a href="http://docs.getexceptional.com/getting-started/sinatra/">example documentation</a>
+ for Sinatra. It <em>might</em> be better off inside of a config block, but I haven&rsquo;t
+ tested it in that role yet.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="k">if</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;RACK_ENV&#39;</span><span class="o">]</span> <span class="o">==</span> <span class="s1">&#39;production&#39;</span>
+ <span class="n">set</span> <span class="ss">:raise_errors</span><span class="p">,</span> <span class="kp">true</span>
+
+ <span class="nb">require</span> <span class="s1">&#39;exceptional&#39;</span>
+ <span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Exceptional</span><span class="p">,</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;EXCEPTIONAL_API_KEY&#39;</span><span class="o">]</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-17'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-17">#</a>
+ </div>
+ <p> This makes <a href="http://haml-lang.com/docs/yardoc/file.HAML_REFERENCE.html#options">Haml escape any html</a> by default.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">set</span> <span class="ss">:haml</span><span class="p">,</span> <span class="ss">:escape_html</span> <span class="o">=&gt;</span> <span class="kp">true</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-18'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-18">#</a>
+ </div>
+ <p> The <code>PONY_VIA_OPTIONS</code> hash is used to configure <code>pony</code>. Basically, we only
+ want to actually send mail if we&rsquo;re in the production environment. So we set
+ the hash to just be <code>{}</code>, except when we want to send mail.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">configure</span> <span class="ss">:test</span> <span class="k">do</span>
+ <span class="no">PONY_VIA_OPTIONS</span> <span class="o">=</span> <span class="p">{}</span>
+<span class="k">end</span>
+
+<span class="n">configure</span> <span class="ss">:development</span> <span class="k">do</span>
+ <span class="no">PONY_VIA_OPTIONS</span> <span class="o">=</span> <span class="p">{}</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-19'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-19">#</a>
+ </div>
+ <p> We&rsquo;re using <a href="http://sendgrid.com/">SendGrid</a> to send our emails. It&rsquo;s really
+ easy; the Heroku addon sets us up with environment variables with all of the
+ configuration options that we need.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">configure</span> <span class="ss">:production</span> <span class="k">do</span>
+ <span class="no">PONY_VIA_OPTIONS</span> <span class="o">=</span> <span class="p">{</span>
+ <span class="ss">:address</span> <span class="o">=&gt;</span> <span class="s2">&quot;smtp.sendgrid.net&quot;</span><span class="p">,</span>
+ <span class="ss">:port</span> <span class="o">=&gt;</span> <span class="s2">&quot;25&quot;</span><span class="p">,</span>
+ <span class="ss">:authentication</span> <span class="o">=&gt;</span> <span class="ss">:plain</span><span class="p">,</span>
+ <span class="ss">:user_name</span> <span class="o">=&gt;</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;SENDGRID_USERNAME&#39;</span><span class="o">]</span><span class="p">,</span>
+ <span class="ss">:password</span> <span class="o">=&gt;</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;SENDGRID_PASSWORD&#39;</span><span class="o">]</span><span class="p">,</span>
+ <span class="ss">:domain</span> <span class="o">=&gt;</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;SENDGRID_DOMAIN&#39;</span><span class="o">]</span>
+ <span class="p">}</span>
+
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-20'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-20">#</a>
+ </div>
+ <p> We don&rsquo;t want to bother with running our own MongoDB server in production;
+ that&rsquo;s what The Cloud &trade; is for! So we want to double check our environment
+ variables, and if it appears that we&rsquo;d like to connect to
+ <a href="https://mongohq.com/">MongoHQ</a>, let&rsquo;s do that. Otherwise, just connect to
+ our local server running on localhost.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">configure</span> <span class="k">do</span>
+ <span class="k">if</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_URL&#39;</span><span class="o">]</span>
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="no">Mongo</span><span class="o">::</span><span class="no">Connection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_HOST&#39;</span><span class="o">]</span><span class="p">,</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_PORT&#39;</span><span class="o">]</span><span class="p">)</span>
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">database</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_DATABASE&#39;</span><span class="o">]</span>
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">database</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_USER&#39;</span><span class="o">]</span><span class="p">,</span><span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_PASSWORD&#39;</span><span class="o">]</span><span class="p">)</span>
+
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">database</span> <span class="o">=</span> <span class="no">ENV</span><span class="o">[</span><span class="s1">&#39;MONGOHQ_DATABASE&#39;</span><span class="o">]</span>
+ <span class="k">else</span>
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">connection</span> <span class="o">=</span> <span class="no">Mongo</span><span class="o">::</span><span class="no">Connection</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s1">&#39;localhost&#39;</span><span class="p">)</span>
+ <span class="no">MongoMapper</span><span class="o">.</span><span class="n">database</span> <span class="o">=</span> <span class="s2">&quot;hackety-development&quot;</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-21'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-21">#</a>
+ </div>
+ <p> Since Sinatra doesn&rsquo;t automatically load anything, we have to do it
+ ourselves. Remember that helpers.rb file? Well, we made a handy
+ <code>require_directory</code> method that, well, <code>require</code>s a whole directory. So let&rsquo;s
+ include both of our models as well as our controllers.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">require_directory</span> <span class="s2">&quot;models&quot;</span>
+<span class="n">require_directory</span> <span class="s2">&quot;controllers&quot;</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-22'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-22">#</a>
+ </div>
+ <h3>Set up basic routes</h3>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre></pre></div>
+ </td>
+ </tr>
+ <tr id='section-23'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-23">#</a>
+ </div>
+ <p> The first thing you&rsquo;ll ever see when going to the website is here. It all
+ starts with <code>/</code>. If we&rsquo;re logged in, we want to just redirect to the main
+ activity stream. If not, let&rsquo;s show that pretty splash page that sings all of
+ our praises.</p>
+
+<p> One small note about rendering, though: Our main layout doesn&rsquo;t exactly work
+ for the main page, it&rsquo;s an exception. So we don&rsquo;t want to use our regular old
+ <code>layout.haml</code> file. So we tell Sinatra not to.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/&#39;</span> <span class="k">do</span>
+ <span class="k">if</span> <span class="n">logged_in?</span>
+ <span class="n">redirect</span> <span class="s2">&quot;/stream&quot;</span>
+ <span class="k">end</span>
+ <span class="n">haml</span> <span class="ss">:index</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=&gt;</span> <span class="ss">:plain</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-24'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-24">#</a>
+ </div>
+ <p> Hopefully, anyone visiting the site will think that Hackety Hack sounds
+ pretty cool. If they do, they&rsquo;ll visit the downloads page. This&rsquo;ll direct
+ them to download Hackety, and sign up for an account.</p>
+
+<p> Similar to the home page, we also don&rsquo;t want our layout here, either.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/download&#39;</span> <span class="k">do</span>
+ <span class="n">haml</span> <span class="ss">:download</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=&gt;</span> <span class="ss">:plain</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-25'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-25">#</a>
+ </div>
+ <p> The main activity stream is the main page for the site when a user is logged
+ in. It lets them share what they&rsquo;re doing with others, and also view all of
+ the content that others have posted. So we grab it all, and sort it in the
+ opposite order that it&rsquo;s been updated. Wouldn&rsquo;t want to see old stuff!</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">get</span> <span class="s1">&#39;/stream&#39;</span> <span class="k">do</span>
+ <span class="vi">@content_list</span> <span class="o">=</span> <span class="no">Content</span><span class="o">.</span><span class="n">all</span><span class="o">.</span><span class="n">sort</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">|</span> <span class="n">b</span><span class="o">.</span><span class="n">updated_at</span> <span class="o">&lt;=&gt;</span> <span class="n">a</span><span class="o">.</span><span class="n">updated_at</span> <span class="p">}</span>
+ <span class="n">haml</span> <span class="ss">:stream</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
199 helpers.html
@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html;charset=utf-8">
+ <title>helpers.rb</title>
+ <link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
+</head>
+<body>
+<div id='container'>
+ <div id="background"></div>
+ <div id="jump_to">
+ Jump To &hellip;
+ <div id="jump_wrapper">
+ <div id="jump_page">
+ <a class="source" href="hackety.html">hackety.rb</a>
+ <a class="source" href="helpers.html">helpers.rb</a>
+ </div>
+ </div>
+ </div>
+ <table cellspacing=0 cellpadding=0>
+ <thead>
+ <tr>
+ <th class=docs><h1>helpers.rb</h1></th>
+ <th class=code></th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr id='section-1'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-1">#</a>
+ </div>
+ <p> The <strong>helpers.rb</strong> file contains all of our Sinatra helpers. This is large
+ enough that including it in a separate file makes it much easier to find;
+ otherwise, I&rsquo;d be opening <strong>hackety.rb</strong> and searching for &lsquo;helpers,&rsquo; and
+ that&rsquo;s just stupid.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="n">helpers</span> <span class="k">do</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-2'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-2">#</a>
+ </div>
+ <p> A tiny bit of metaprogramming goes a long way. We want to generate three
+ methods (<code>development?</code>, <code>production?</code>, and <code>test?</code>) that let us know which
+ environment we happen to be in. This is useful in a few places.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="o">[</span><span class="ss">:development</span><span class="p">,</span> <span class="ss">:production</span><span class="p">,</span> <span class="ss">:test</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">environment</span><span class="o">|</span>
+ <span class="n">define_method</span> <span class="s2">&quot;</span><span class="si">#{</span><span class="n">environment</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">?&quot;</span> <span class="k">do</span>
+ <span class="k">return</span> <span class="n">settings</span><span class="o">.</span><span class="n">environment</span> <span class="o">==</span> <span class="n">environment</span><span class="o">.</span><span class="n">to_sym</span>
+ <span class="k">end</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-3'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-3">#</a>
+ </div>
+ <p> This incredibly useful helper gives us the currently logged in user. We
+ keep track of that by just setting a session variable with their id. If it
+ doesn&rsquo;t exist, we just want to return nil.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">current_user</span>
+ <span class="k">return</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">first</span><span class="p">(</span><span class="ss">:id</span> <span class="o">=&gt;</span> <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span><span class="p">)</span> <span class="k">if</span> <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span>
+ <span class="kp">nil</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-4'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-4">#</a>
+ </div>
+ <p> This very simple method checks if we&rsquo;ve got a logged in user. That&rsquo;s pretty
+ easy: just check our current_user.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">logged_in?</span>
+ <span class="n">current_user</span> <span class="o">!=</span> <span class="kp">nil</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-5'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-5">#</a>
+ </div>
+ <p> Our <code>admin_only!</code> helper will only let admin users visit the page. If
+ they&rsquo;re not an admin, we redirect them to either / or the page that we
+ specified when we called it.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">admin_only!</span><span class="p">(</span><span class="n">opts</span> <span class="o">=</span> <span class="p">{</span><span class="ss">:return</span> <span class="o">=&gt;</span> <span class="s2">&quot;/&quot;</span><span class="p">})</span>
+ <span class="k">unless</span> <span class="n">logged_in?</span> <span class="o">&amp;&amp;</span> <span class="n">current_user</span><span class="o">.</span><span class="n">admin?</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:error</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Sorry, buddy&quot;</span>
+ <span class="n">redirect</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:return</span><span class="o">]</span>
+ <span class="k">end</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-6'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-6">#</a>
+ </div>
+ <p> Similar to <code>admin_only!</code>, <code>require_login!</code> only lets logged in users access
+ a particular page, and redirects them if they&rsquo;re not.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">require_login!</span><span class="p">(</span><span class="n">opts</span> <span class="o">=</span> <span class="p">{</span><span class="ss">:return</span> <span class="o">=&gt;</span> <span class="s2">&quot;/&quot;</span><span class="p">})</span>
+ <span class="k">unless</span> <span class="n">logged_in?</span>
+ <span class="n">flash</span><span class="o">[</span><span class="ss">:error</span><span class="o">]</span> <span class="o">=</span> <span class="s2">&quot;Sorry, buddy&quot;</span>
+ <span class="n">redirect</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:return</span><span class="o">]</span>
+ <span class="k">end</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-7'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-7">#</a>
+ </div>
+ <p> We also want to have a way for the desktop application to make calls to the
+ site. For this, we allow a username and password to be passed in, and we
+ authenticate directly, rather than relying on a previously logged in
+ session.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">require_login_or_api!</span><span class="p">(</span><span class="n">opts</span><span class="o">=</span><span class="p">{})</span>
+ <span class="k">return</span> <span class="k">if</span> <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span>
+ <span class="n">hacker</span> <span class="o">=</span> <span class="no">Hacker</span><span class="o">.</span><span class="n">authenticate</span><span class="p">(</span><span class="n">opts</span><span class="o">[</span><span class="ss">:username</span><span class="o">]</span><span class="p">,</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:password</span><span class="o">]</span><span class="p">)</span>
+ <span class="k">if</span> <span class="n">hacker</span>
+ <span class="n">session</span><span class="o">[</span><span class="ss">:hacker_id</span><span class="o">]</span> <span class="o">=</span> <span class="n">hacker</span><span class="o">.</span><span class="n">id</span>
+ <span class="k">else</span>
+ <span class="n">halt</span> <span class="mi">401</span>
+ <span class="k">end</span>
+ <span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-8'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-8">#</a>
+ </div>
+ <p> <a href="http://gravatar.com/">Gravatar</a> is used for our avatars. Generating the
+ url for one is pretty simple, we just need the proper email address, and
+ then we make an md5 of it. No biggie.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre> <span class="k">def</span> <span class="nf">gravatar_url_for</span> <span class="n">email</span>
+ <span class="nb">require</span> <span class="s1">&#39;digest/md5&#39;</span>
+ <span class="s2">&quot;http://www.gravatar.com/avatar/</span><span class="si">#{</span><span class="no">Digest</span><span class="o">::</span><span class="no">MD5</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">(</span><span class="n">email</span><span class="o">.</span><span class="n">downcase</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>
+ <span class="k">end</span>
+
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-9'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-9">#</a>
+ </div>
+ <p> This handy helper method lets us require an entire directory of <code>rb</code> files.
+ It&rsquo;s much simpler than having to require them all directly.</p>
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="k">def</span> <span class="nf">require_directory</span> <span class="n">dirname</span>
+ <span class="no">Dir</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">#{</span><span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="bp">__FILE__</span><span class="p">))</span><span class="si">}</span><span class="s2">/</span><span class="si">#{</span><span class="n">dirname</span><span class="si">}</span><span class="s2">/*.rb&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
+ <span class="nb">require</span> <span class="n">f</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ <tr id='section-10'>
+ <td class=docs>
+ <div class="octowrap">
+ <a class="octothorpe" href="#section-10">#</a>
+ </div>
+ <p> This method is a handy monkeypatch on String. It allows us to turn any string
+ into a slug that&rsquo;s suitable for putting into URLs.</p>
+
+ </td>
+ <td class=code>
+ <div class='highlight'><pre><span class="k">class</span> <span class="nc">String</span>
+ <span class="k">def</span> <span class="nf">to_slug</span>
+ <span class="nb">self</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/[^a-zA-Z _0-9]/</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="sr">/\s/</span><span class="p">,</span> <span class="s2">&quot;_&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">downcase</span>
+ <span class="k">end</span>
+<span class="k">end</span></pre></div>
+ </td>
+ </tr>
+ </table>
+</div>
+</body>
View
57 models/comment.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
</