<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Epoch's Blog]]></title>
  <link href="http://epochwolf.com/atom.xml" rel="self"/>
  <link href="http://epochwolf.com/"/>
  <updated>2013-01-19T11:24:01-08:00</updated>
  <id>http://epochwolf.com/</id>
  <author>
    <name><![CDATA[epochwolf]]></name>
    <email><![CDATA[me@epochwolf.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Singleforest and litsocial down]]></title>
    <link href="http://epochwolf.com/blog/2013/01/10/singleforest-and-litsocial-down/"/>
    <updated>2013-01-10T07:26:00-08:00</updated>
    <id>http://epochwolf.com/blog/2013/01/10/singleforest-and-litsocial-down</id>
    <content type="html"><![CDATA[<p>I had to disable singleforest.com and staging.litsocial.com. There&#8217;s a extremely <a href="https://groups.google.com/forum/#!topic/rubyonrails-security/61bkgvnSGTQ/discussion">bad security bug</a> in rails I haven&#8217;t had time to patch. The bug is already in metasploit which means an automated attack could compromise my servers.</p>

<p>I&#8217;ll be working over the weekend to patch my applications. I have several applications at my current job that are going to need emergency patches.</p>

<p><em>Update 2013-01-19:</em> Both sites are back online.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why autosave doesn't work on belongs_to associations]]></title>
    <link href="http://epochwolf.com/blog/2012/07/15/rails-and-assocation-autosave/"/>
    <updated>2012-07-15T12:53:00-07:00</updated>
    <id>http://epochwolf.com/blog/2012/07/15/rails-and-assocation-autosave</id>
    <content type="html"><![CDATA[<p><em>This post relates to Rails 3.2. It probably applies all the way back to Rails 2 but I make no guarantees of past or future applicability.</em></p>

<p>The rails docs on association autosave for belongs_to currently reads</p>

<blockquote><p>If true, always save the associated object or destroy it if marked for destruction, when saving the parent object. If false, never save or destroy the associated object. By default, only save the associated object if it’s a new record.</p><footer><strong>ActiveRecord::Associations::ClassMethods</strong> <cite><a href='http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to'>Rails Docs</a></cite></footer></blockquote>


<p>Clear enough. So you would expect this code to work.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Story</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:user</span>
</span><span class='line'>  <span class="n">belongs_to</span> <span class="ss">:series</span>
</span><span class='line'>
</span><span class='line'>  <span class="c1"># nested_attributes_for doesn&#39;t work on belongs_to association</span>
</span><span class='line'>  <span class="c1"># so we duplicate a subset of that behavior for new records</span>
</span><span class='line'>  <span class="kp">attr_accessor</span> <span class="ss">:series_title</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">before_save</span> <span class="ss">:save_series_title</span><span class="p">,</span> <span class="k">if</span><span class="p">:</span> <span class="o">-&gt;</span><span class="p">(</span><span class="n">o</span><span class="p">){</span> <span class="n">o</span><span class="o">.</span><span class="n">series_id</span><span class="o">.</span><span class="n">nil?</span> <span class="o">&amp;&amp;</span> <span class="n">o</span><span class="o">.</span><span class="n">series_title</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">save_series_title</span>
</span><span class='line'>    <span class="nb">self</span><span class="o">.</span><span class="n">series</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">series</span><span class="o">.</span><span class="n">find_or_initialize_by_title</span><span class="p">(</span><span class="n">series_title</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>What the documentation doesn&#8217;t tell you is that this autosave for a <em>belongs_to</em> association is implemented as a <em>before_save</em> callback. This is obviously going to throw a wrench in things. Other associations like has_may and has_one are implemented in a after_create/after_update callback.</p>

<p>The solution for the example is rather simple.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">save_series_title</span>
</span><span class='line'>  <span class="nb">self</span><span class="o">.</span><span class="n">series</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">series</span><span class="o">.</span><span class="n">find_or_initialize_by_title</span><span class="p">(</span><span class="n">series_title</span><span class="p">)</span>
</span><span class='line'>  <span class="c1"># Need to manually save since the autosave callbacks have already been called.</span>
</span><span class='line'>  <span class="nb">self</span><span class="o">.</span><span class="n">series</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Calling save at the last line of the function will maintain the same functionality of the autosave callbacks. If the association fails to save, the callback returns false, the save is aborted and the transaction is rolled back.</p>

<h2>Why this behavior exists</h2>

<p>The save order for belongs_to callbacks is different for a very simple and logical reason. The foreign key for a belongs_to association is on the record that is being saved. So the association needs to to be saved before the record it&#8217;s on so it can set the field before the query is executed. For the same reasons has_many and has_one associations save after the query executes since those associations need to wait for the record to have an id before they can be saved.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[New blog.]]></title>
    <link href="http://epochwolf.com/blog/2012/04/08/new-blog/"/>
    <updated>2012-04-08T20:48:00-07:00</updated>
    <id>http://epochwolf.com/blog/2012/04/08/new-blog</id>
    <content type="html"><![CDATA[<p>Working on moving my blog from posterous to my own hosting.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Net::HTTPBadResponse: wrong status line: "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">&#8221;]]></title>
    <link href="http://epochwolf.com/blog/2011/12/06/nethttpbadresponse-wrong-status-line-doctype/"/>
    <updated>2011-12-06T17:19:00-08:00</updated>
    <id>http://epochwolf.com/blog/2011/12/06/nethttpbadresponse-wrong-status-line-doctype</id>
    <content type="html"><![CDATA[<p>If you ever see: <code>Net::HTTPBadResponse: wrong status line "&lt;!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"&gt;"</code></p>

<p>Then you probably forgot to use ssl with your request to port 443. Apache coughed up a 400 error page over ssl in a way that caused the ruby standard library Net::HTTP to vomit exceptions all over your application.</p>

<p>This behavior was discovered on with Ruby 1.8.7 patch level 352. Judging by how it affected all the development system at my work, it affects all Ruby 1.8.7 patch levels equally. I have no ideal what happens with Ruby 1.9.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Singleforest Beta Soon (for real)]]></title>
    <link href="http://epochwolf.com/blog/2011/04/14/singleforest-beta-soon-for-real/"/>
    <updated>2011-04-14T16:15:00-07:00</updated>
    <id>http://epochwolf.com/blog/2011/04/14/singleforest-beta-soon-for-real</id>
    <content type="html"><![CDATA[<p>So close, I can taste it. Singleforest is nearly ready for beta. I&#8217;ve hammered the most the major bugs I&#8217;m aware of.</p>

<p>What&#8217;s left before launch?</p>

<ul>
<li>Some of the custom logging code is storing passwords. That needs to get fixed before the site can go live.</li>
<li>Moving the server from Rackspace to WebbyNode. Waiting on WebbyNode to get debian 6 out. Will go with Ubuntu in a pinch.</li>
<li>Need to write up Terms of Service and Rules documents.</li>
</ul>


<p>Some of the issues getting the site ready:</p>

<ul>
<li>Getting SSL/nonSSL redirection working properly was not happening.

<ul>
<li>Moved the entire site to ssl instead. Easier and more secure anyway.</li>
</ul>
</li>
<li>Getting tests written for some of the code. RSpec fought me every step of the install process.

<ul>
<li>Releasing the beta with only minimal test coverage, will add tests as bugs pop up.</li>
</ul>
</li>
<li>Writing my own css was taking way too much time.

<ul>
<li>Purchased a theme for $20</li>
<li>Will fix some of the icky coloration later. (background too bright, link color too light)</li>
</ul>
</li>
<li>Event system was pretty complicated and was breaking a lot of code

<ul>
<li>Stripped events and notifications to the minimum that was required and stopped trying to ensure they get saved.</li>
</ul>
</li>
<li>Spending too much time making the ajax stuff nicer

<ul>
<li>Stopped working on writing my own widget library and settled on a just works solution for now.</li>
</ul>
</li>
</ul>


<p>I can&#8217;t wait to for this thing to be live. It&#8217;s been way too long.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Why I'm Using Rails 3 and SQL]]></title>
    <link href="http://epochwolf.com/blog/2011/01/10/why-im-using-rails-3-and-sql/"/>
    <updated>2011-01-10T05:25:00-08:00</updated>
    <id>http://epochwolf.com/blog/2011/01/10/why-im-using-rails-3-and-sql</id>
    <content type="html"><![CDATA[<p>Anyone who has followed my modest blog will be familiar with the various frameworks and databases I have tried using for singleforest.com. Well, I have finally come to a conclusion. A real conclusion this time. Since August 2010 I have been working with Rails 3 using SQLite3 as a database backend. For anyone on Hacker News that has met me in Chicago, this is the version I demoed on my iPad at the Publican.</p>

<p>I would like to review the frameworks and database previous iterations of singleforest.com used and why I am not using them today.</p>

<h2>Frameworks</h2>

<h3>Rails 2</h3>

<p>I originally started coding with rails 2. It was an easy decision to make since I had learned rails during my internship and I had continued to use it after the end of my internship. The first rails 3 beta was released early in my development process. I found rails 3 to be cleaner than earlier versions. The routing api was elegant instead of clunky. (Yes, specifying :controller and :action for every route is clunky even if you can scope them.) The addition of AREL to active record was also important once I started using sql databases, my current code base relies on it for automatic sorting and pagination.  As a result I made several attempts to use rails 3 which resulted in enormous amount of pain. During the betas several key gems such as authlogic, formtastic, and various active record gems were either not compatible or buggy. I was forced back to rails 2 until rails 3 was out of beta. Once 3 was out of beta I switched back to it.</p>

<h3>Django</h3>

<p>I had given Django some thought initially. I had played around with Django before and found it to be at least as large of a framework as Rails. I went with rails because of ruby. I hadn’t used python for almost a year when I started singleforest.com and I was looking at the start of a new semester in a few weeks.</p>

<h3>Pylons</h3>

<p>During my fights over whether to use Rails 2 or Rails 3, I decided to give a python framework a try. I dismissed Django for the same reasons as before, it’s too large of a framework to learn quickly. I figured I would be up to relearning python since I had enough free time between classes. Turns out relearning python wasn’t the problem, the documentation on pylons was. At the time I was learning pylons, the available documentation on the internet was out of date and pydoc refused to build the documentation for the version I was using. The only decent tutorial I could find was a half finished book on the previous version. I quickly ran into issues with the book. A quick trip to irc revealed to me there was no authoritative documentation, no tutorials for the current version, and no one had any idea how to actually build a pylons project from scratch. I was told to download a sample application (the pylon’s project website) and modify that. Upon doing that I found out I now had three different version of pylons on my system and all of them hated each other. I also had issues with python’s tooling. (Pydoc, virtualenv, and multiple package managers) In the end I went back to rails because I didn’t have the patience or time to deal with a pylons.</p>

<h2>Databases</h2>

<h3>CouchDB</h3>

<p>What’s not to love about CouchDB? From a system administrative perspective it’s the most awesome database ever. It’s crash-only, you can back it up with rsync, and it scales like nuts. From a programming perspective it’s a little more work. You need to define every query you will ever do before you do it. It’s not as bad as you think. CouchDB has a development mode that will run any query you want without an index. Slow as hell but flexible, you just have to define the indexes before you deploy. I can live with that. Data is stored as json documents in a single silo. I can live with that. For an old version of my application it would work fine. I would have loved to use it.</p>

<p>Why didn’t I? I need joins in the future. CouchDB could work if I was willing to make trade offs on future design. I plan to add groups to singleforest. The queries I would need can’t run on couchdb without a lot of denormalization. Adding and removing users from groups and calculating activity on groups would be expensive and require cron jobs. Ironically, groups wouldn’t be able to scale on CouchDB.</p>

<h3>MongoDB</h3>

<p>I liked using mongodb but the tradeoffs make me uncomfortable from a system administration perspective. MongoDB plays fast and loose with data to get high speeds as a result, it requires two servers for data safety. I don’t currently have the resources to deploy two database servers. I did not feel comfortable trying to maintain a single server against strong recommendations not to. Later I found another reason not to use MongoDB: I need joins.</p>

<h2>In Conclusion</h2>

<p>Since rails 3 has matured it has been an absolute joy to work with. I do not regret having spent so much time switching between databases and frameworks. It’s given me a better appreciation for the tools I’m using now. Learning to model data in json has allowed me to model data better in sql. Fighting with python’s toolset has made me thankful for ruby version manager and bundler.</p>

<h2>Project Update</h2>

<p>Screenshots of the current version available on my <a href="http://epochwolf.deviantart.com/gallery/27711539">deviantArt</a> account.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A look at singleforest.com: polls]]></title>
    <link href="http://epochwolf.com/blog/2010/08/11/a-look-at-singleforestcom-polls/"/>
    <updated>2010-08-11T18:19:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/08/11/a-look-at-singleforestcom-polls</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been getting a lot of work done on singleforest.com. I&#8217;ve got a week left to add features before I start tracking down bugs and getting my server ready for an August 30th deployment.</p>

<p>Today I finished creating polls. I wasn&#8217;t going to have polls as a feature to start with but they where so easy to create I figured, why not? (Still took two days&#8230;)</p>

<p>This is what a poll looks like.</p>

<p><img src="http://epochwolf.com/images/sf/monday_bad_poll.png"></p>

<p>Nothing too fancy. It works though. One design note: I wanted people to be able to see what the current votes are before they decide what to vote.</p>

<p>Here&#8217;s what it looks like when you click vote!</p>

<p><img src="http://epochwolf.com/images/sf/monday_that_bad_voted.png"></p>

<p>The asterisk tells you what you voted on and the green bar below the main navigation tells you that your vote has been saved.</p>

<p>And for a bonus, you can optionally make polls that allow people to vote on multiple answers!</p>

<p><img src="http://epochwolf.com/images/sf/multiple_votes_poll.png"></p>

<p>As you can see, there are two asterisks on this one. You also get a preview of fully functioning editable comments.</p>

<p>Here&#8217;s a bonus screen shot of that comment&#8217;s edits.</p>

<p><img src="http://epochwolf.com/images/sf/comment_history.png"></p>

<p>I&#8217;ve been very busy. :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Some stuff is allowed to break on purpose.]]></title>
    <link href="http://epochwolf.com/blog/2010/08/10/some-stuff-is-allowed-to-break-on-purpose/"/>
    <updated>2010-08-10T17:13:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/08/10/some-stuff-is-allowed-to-break-on-purpose</id>
    <content type="html"><![CDATA[<p>I was playing around with markdown and I discovered attempting to submit indented text breaks things rather nicely.</p>

<p>This is what indented text looks like when viewed.</p>

<p><img src="http://epochwolf.com/images/sf/breaking_indents.png"></p>

<p>With a black background you have no hope of reading the submission. Editing is even worse.</p>

<p><img src="http://epochwolf.com/images/sf/missing_editor.png"></p>

<p>The text box for editing has completely disappeared&#8230; wait, there is a horizontal scrollbar!</p>

<p><img src="http://epochwolf.com/images/sf/missing_editor_found.png"></p>

<p>Ah, there it is. That&#8217;s going to be a pain to edit.</p>

<p>I didn&#8217;t plan on breaking indented text this badly but it certainly works. I don&#8217;t want any user-submitted content to have indentation. I have a very specific reason for this. I want to present every submission in the same, readable format. If you want indented text, I would be happy to use css to properly indent it for you! I want the text on singleforest to be readable and consistent when submitted. Using markdown enforces some level of standardization. Restricting allowed html helps even more. (CSS may work in the preview but you ain&#8217;t getting colored fonts in your literature. Yeah, I remove the <font> tag too.)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails 3 RC injuries.]]></title>
    <link href="http://epochwolf.com/blog/2010/07/27/rails-3-rc-injuries/"/>
    <updated>2010-07-27T09:26:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/07/27/rails-3-rc-injuries</id>
    <content type="html"><![CDATA[<p>If you&#8217;re going to run bleeding edge, you will bleed profusely. I nearly lost an arm today. I upgraded my application to Rails 3 rc from Rails 3 beta4. The list of problems I&#8217;ve encounter is not long but very annoying..</p>

<ol>
<li>gem install rails &#8211;pre on top of existing rails beta causes vague untraceable errors just like upgrading to beta2 and beta3..

<ol>
<li>Solution is to remove all installed gems. <strong>manually</strong>.</li>
<li>Happily discover rvm has support for this. (rvm gemset clear)</li>
<li>Install rails 3 rc and all dependencies..</li>
<li>While gems download find out in #rails-contrib that rails 3 rc isn&#8217;t loading the lib/ folder

<ol>
<li>Add &#8220;config.autoload_paths += %W(#{config.root}/lib)&#8221; to application.rb</li>
</ol>
</li>
<li>Ruby 1.9.1 segfautls on load.. Joy of joys but not surprising.</li>
</ol>
</li>
<li>Try ruby 1.9.2-preview1

<ol>
<li>Remove all installed gems</li>
<li>Install rails 3 rc. and application gems</li>
<li>Instant sigabrt on running rails server</li>
<li>Discover in #rails-contrib that preview1 is buggy as hell&#8230; (then why does rvm install 1.9.2 install preview1?)</li>
</ol>
</li>
<li>Try ruby 1.9.2-head

<ol>
<li>No gems to remove because I need to update the head anyway.</li>
<li>Download, compile, and install ruby 1.9.2-head</li>
<li>Install rails 3 rc and application gems</li>
<li>Instant internal server errors relating to failsafe failing.</li>
<li>#rails-contrib recommends 1.9.2-rc2</li>
</ol>
</li>
<li>Try ruby 1.9.2-rc2

<ol>
<li>Not installed</li>
<li>Download, compile, and install ruby-1.9.2-rc2</li>
<li>Install rails 3 rc and application gems</li>
<li>Instant internal server errors relating to failsafe failing.</li>
</ol>
</li>
<li>Swear quietly and profusely</li>
<li>Start testing

<ol>
<li>Build new rails 3 rc application.

<ol>
<li>launches okay with simple controller and view</li>
<li>compare boot.rb, application.rb, environment/ and initializers/ with non-working app.</li>
<li>no difference&#8230;</li>
</ol>
</li>
<li>Test difference configurations with non-working application

<ol>
<li>Throw exception in home#index</li>
<li>Works, controllers are probably okay</li>
<li>Render index view without layout</li>
<li>500 Error</li>
<li>Render index using erb instead of haml</li>
<li>Works&#8230;</li>
</ol>
</li>
<li>Back to new rails 3 rc app

<ol>
<li>Add haml gem to Gemfile and make a basic haml view</li>
<li>Works okay..</li>
<li>Add haml configuration initializer from non-working application</li>
<li>500 Error</li>
<li>Start playing around with different configuration options</li>
<li>Discovered setting. :encoding to :&#8221;utf-8&#8221; (notice the colon, :&#8221;&#8221; is a symbol, not a string)</li>
<li>Using &#8220;UTF-8&#8221; (string) instead of :&#8221;utf-8&#8221; (symbol) works&#8230;</li>
</ol>
</li>
<li>Change :&#8221;utf-8&#8221; to &#8220;UTF-8&#8221; in non-working application

<ol>
<li>Application works now.</li>
</ol>
</li>
</ol>
</li>
</ol>


<p>I am now able to continue working on singleforest.com but I&#8217;m ready for a nap. I estimated this morning I would spend several hours just getting my application working again. For once I was correct. It only took several hours instead of the entire day.</p>

<p>I would like to thank elux and nbibler in #rails-contrib on freenode for helping me out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Old version of singleforest.com available on github]]></title>
    <link href="http://epochwolf.com/blog/2010/07/07/old-version-of-singleforestcom-available-on-g/"/>
    <updated>2010-07-07T11:48:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/07/07/old-version-of-singleforestcom-available-on-g</id>
    <content type="html"><![CDATA[<p>I&#8217;ve deployed an old copy of singleforest.com on github at <a href="http://github.com/epochwolf/singleforest-old">http://github.com/epochwolf/singleforest-old</a> for all you voyeurs to see. It&#8217;s the same copy you see in the screen shots.</p>

<p>My current version of singleforest.com is quite different. I&#8217;m not using openid anymore. I wish I could have used OpenID but the rack-openid gem has issues with ruby 1.9&#8217;s encoding scheme. My current version also uses Rails 3 and MongoDB instead of Rails 2.3.5 and SQLite.</p>

<p>In other news, this blog is now linked to on my public cv at careers.stackoverflow.com. I won&#8217;t link you directly to it but those of you interested can now find my real name.  (I give my family about a week before one of them discovers my posts to a certain art website.) My real name would have come out anyway, I figure now is as good as a time as any to let the cat<sup>H<sup>H<sup>Hwolf</sup></sup></sup> out of the bag.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A brief, fragmented update on everything.]]></title>
    <link href="http://epochwolf.com/blog/2010/06/16/a-brief-fragmented-update-on-everything/"/>
    <updated>2010-06-16T10:10:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/06/16/a-brief-fragmented-update-on-everything</id>
    <content type="html"><![CDATA[<p>I&#8217;ve finally graduated with a Computer Science degree. My GPA was 2.866 or so. I&#8217;m just glad that&#8217;s over with. I can&#8217;t help that nagging feeling that I&#8217;ve wasted 4 years of my life.</p>

<p>I hammered out less ambitious plans for my literature website (singleforest.com) last night. I&#8217;ve decided to try getting rid of every feature that most art websites have. This isn&#8217;t the most brilliant move I&#8217;ve had (yet) but it&#8217;s one I need to get anything done. I want to experiment with using email and rss instead of a traditional message center. I&#8217;ll probably need to rethink this at some point. That point being a significant number of annoyed users which I expect to happen a few months into the life of the site.</p>

<p>My maternal grandfather has been in the hospital for over two weeks now because of complications from lung surgery. He&#8217;s going to need heart surgery for an eventually fatal heart defect but he needs to heal from the last surgery. It&#8217;s been fairly stressful for me and my family. It&#8217;s not the reason I&#8217;ve been silent for so long but it certainly isn&#8217;t helping things.</p>

<p>On top of this, I&#8217;m getting depressed from lack of motivation and useful things to do. I&#8217;m still living at home with my parents and I really want to move out and start living my own life. I&#8217;ve having a difficult time with looking for jobs. It&#8217;s a task that has very limited feedback if any, which is something I don&#8217;t handle as well as I want to. I&#8217;m also frustrated by the lack of interesting programming opportunities in Wisconsin. I&#8217;d love to relocate but I can&#8217;t take the financial risk unless I&#8217;d have a job waiting for me. I&#8217;ve applied at local java and .net shops but those jobs are absolutely flooded and given my lack of experience I&#8217;m not getting much consideration. Those of you that know me on irc will remember my trip to Eau Claire, I didn&#8217;t get the job.</p>

<p>If you read all of that I thank you. Don&#8217;t let my bad week keep you from enjoying yours!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Another snag! (I gotta stop doing this)]]></title>
    <link href="http://epochwolf.com/blog/2010/05/13/another-snag-i-gotta-stop-doing-this/"/>
    <updated>2010-05-13T13:23:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/05/13/another-snag-i-gotta-stop-doing-this</id>
    <content type="html"><![CDATA[<p>Well, I haven&#8217;t done any programming related to singleforest.com for about two weeks. I&#8217;ve been working pretty hard on my final project. I just finished the presentation with my group and the professor said it was good enough to pass. I should be officially graduated in a week or two.</p>

<p>I&#8217;ve come to realize my issues with this website are not based on technology. Took 5 months to realize this. I&#8217;m pretty sure if I had someone else to look over my shoulder this website would be done by now. I never sat down and hammered out what features I needed and how some of the stuff was going to work. You can&#8217;t just tack on a full notifications system. You can&#8217;t be working on a website this big without some automated testing. (Yes, my bad. I never learned to use testing.)</p>

<p>I had exactly 10 versions of singleforest.com sitting in my project folder. Five of them are working but incomplete versions. I don&#8217;t know what I&#8217;m doing. I keep trying to add extra layers to things that don&#8217;t need them because I don&#8217;t know where to put stuff. I&#8217;m going to take a deep breath and relax tonight.</p>

<p>The last SciFi Club meeting of the year is tonight. I&#8217;m going to party with all my friends that I made before I leave this school permanently. Tomorrow, I&#8217;m going to go to an all day party and enjoy myself. Only after that will I sit down and figure out what I&#8217;m going to put into singleforest.com using ruby on rails. An anemic bullet list isn&#8217;t going to be good enough this time.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Singleforest.com is open for signup]]></title>
    <link href="http://epochwolf.com/blog/2010/05/05/singleforestcom-is-open-for-signup/"/>
    <updated>2010-05-05T13:44:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/05/05/singleforestcom-is-open-for-signup</id>
    <content type="html"><![CDATA[<p>TL;DR Singleforest.com is deviantArt for literature.</p>

<p>I created Singleforest.com to solve a problem that has long bothered me. Places like deviantArt are just not made for posting literature. Literature is listed and categorized in a way that makes it difficult for members to find an audience and for visitors to find stuff that they like.</p>

<p>Singleforest is designed to address this in two ways.</p>

<p>First, there is no visual artwork on the site. Literature should not have to compete with visual art. Visual art has a very low barrier to entry when it comes to enjoyment. It takes very little time to browse from image to image. Literature takes more time to enjoy. On Singleforest, everyone will be there to read.</p>

<p>Second, the list views are designed to be quickly scanned if you want to look for a specific story. If you look at the browse page, you will see the following information: title, author, word count, tags, and submission date. This list quickly provides information you will be looking for. The title and author are obvious. The word count gives you an idea of it&#8217;s length. The list of tags supplement the title in helping describe the content of the story. Finally the submission date tells you how old the story is. If you just visited yesterday, you&#8217;ll want to know what&#8217;s new.</p>

<p>This is what separates Singleforest apart from it&#8217;s competitors. Singleforest has forums, user journals, and some other features, like a user-editable wiki, that most community sites have equivalents for. The hope is to attract a community that enjoys reading and writing because no matter how many features the site has, it&#8217;s the community that will ultimately define Singleforest.com.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Lack of Immunity]]></title>
    <link href="http://epochwolf.com/blog/2010/05/05/a-lack-of-immunity/"/>
    <updated>2010-05-05T13:44:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/05/05/a-lack-of-immunity</id>
    <content type="html"><![CDATA[<h2>Context</h2>

<p>One of my favorite furry stories I&#8217;ve written. (If you don&#8217;t know what a furry is, I have an explaination <a href="http://epochwolf.com/pages/what-is-a-furry">here</a>)</p>

<h2>Story</h2>

<p>David woke up late in an unfamiliar room. His sandy-brown fur was matted, his tail had a kink in it, and he had a bad taste in his mouth. There was enough sunlight leaking through the shades to read comfortably. As he sat up the room began to look more familiar. He was at his aunt Julia&#8217;s house in New York City. The room on the tiny third floor. The peaked roof of the house was the room&#8217;s ceiling. His bed was against the front wall. A mexican rug was spread across the center of the room with one end of it at the side of his bed. His suitcases and backpack lay against the left wall opposite a desk. He stood up, careful not to hit his head on the ceiling which was so low he couldn&#8217;t stretch out his arms fully, and yawned loudly. A clock on the desk read 10:20.</p>

<p>He retrieved his suitcases and began moving clothing from his suitcases to the dresser next to the desk. Neither piece of furniture could fit anywhere near the edge of the floor because of the slope of the wall/ceiling. He placed his wallet, blue US passport and gray Israeli passport on the top of the dresser before unpacking his second suitcase. He had dual citizenship because of an accident. His parents had been visiting in this very house when he mother when into labor six weeks early. His father had called it a gift from God. His mother called it chance. David found it convenient because he didn&#8217;t need a visa to get through customs.</p>

<p>David started unpacking his second suitcase which contained his dress uniform with full insignia and several similar uniforms without insignia. He had several locked cases inside the second suitcase. He removed one and placed it under his uniforms in the bottom of the dresser. The remaining cases stayed in the second suitcase. The suitcase was designed to fit inside the first one he had taken his clothes out from so his fitted it inside and stashed both behind the dresser.</p>

<p>Finally unpacked, David grabbed his travel kit and walked across the bedroom to the door. Outside the door was stairs to the second floor and a door to the bathroom. He headed into the bathroom and locked the door behind him. While he was brushing his teeth someone came up the stairs. &#8220;I&#8217;m in here, &#8221; he said through the toothbrush.</p>

<p>&#8220;Hey, you&#8217;re up,&#8221; the voice of his vulpine cousin Michael said through the door. &#8220;Mom&#8217;s headed out with Kyle to get him some summer clothes. She asked me to go to the fish market, did you want to come?&#8221;</p>

<p>David begged for at least 15 minutes to get ready. He figured he could skip showering since he was going to be walking several miles anyway. He rushed through combing his fur and was forced to let the cowlick on his left temple win. There was more important things to attend to than his fur before he when downstairs. He darted into his bedroom but forgot to close the door. He pulled an undershirt out of his dresser and pulled it on so he would be wearing more than just his boxers if his cousin happened to come back up. He took a deep breath. Rushing wasn&#8217;t going to help he was going to be late getting downstairs anyway.</p>

<p>David opened his backpack and removed a rosary and an empty shell casing from a side pocket. He held the rosary to his muzzle and closed his eyes. The shell casing was cold as he rolled it in his fingers. He recalled being back in Israel, a young private with ambition. It wasn&#8217;t so long ago. He was eighteen at the time. He was 23 now which made it only five years ago. He slowly opened his eyes and put the shell casing back in the pocket. Kneeling on the rug with both hands holding the rosary he prayed.</p>

<p>&#8220;Lord, let me set aside revenge today. I have willingly followed your path for the last eight years and it has been especially difficult as of late. Your servant Paul said, &#8216;If it is possible, as far as it depends on you, live at peace with everyone.&#8217; Peace is difficult for one that is called to war. I do not doubt that you want me here even through I don&#8217;t know why. Paul also said, &#8216;Do not repay anyone evil for evil.&#8217; I ask again for you to forgive me my sins and keep me from sin today.&#8221;</p>

<p>He bowed his head and meditated on his prayer.</p>

<p>&#8220;You&#8217;re holding the beads wrong,&#8221; Michael said from the door.</p>

<p>David put the rosary back in his backpack and stood up. &#8220;I don&#8217;t think God cares Michael. I&#8217;ll be right down after I dress.&#8221;</p>

<p>&#8220;Please hurry, I don&#8217;t want to be walking through rush hour traffic near the house,&#8221; Michael sighed and closed the door before heading down the stairs leaving David alone to dress.</p>

<p>David stripped off his boxers and traded them for briefs. He donned one of his khaki-colored unmarked uniforms and a pair of combat boots. Since he stood only 173 centimeters tall and weighed just 54 kilos, the uniform was a little baggy. As far as he was concerned the fit was perfect. He removed the locked case from from the bottom of the dresser. It was fairly large. About as large as two hardcover books. He set it on the desk and opened it. Inside was a M1911A1 pistol, 4 empty magazines, 40 .45 ACP Ranger SXT hollow-point bullets, two holsters, and a black passport containing a laminated card and several folded sheets of paper.</p>

<p>The holsters were designed to hook on to a belt and hang inside a pair pants just behind the point of the hip. The right holster carried the pistol and the left held two magazines. David attached both of them to his belt before turning his attention to the gun. The magazines had been emptied to prevent the springs from wearing out. It took him five minutes to load three of the four magazines. He holstered two of the magazines and was moving to put the third in his pistol when he heard the Michael coming up the stairs.</p>

<p>&#8220;What&#8217;s taking so long,&#8221; Michael inquired through the door.</p>

<p>David sighed. He picked up his pistol and double checked that the safety was on. &#8220;I&#8217;ll be out in a minute,&#8221; he replied as he slid the magazine into the pistol and worked the slide to chamber a round. He removed the magazine and pushed another bullet into it. He slid the magazine back in the pistol and holstered it on his right hip. With the clothing being slightly oversized, the pistol and magazines disappeared under his pants and jacket. As long as he was careful no one would know he was armed, including Michael. Perhaps especially Michael. Aunt Julia had no love of guns.</p>

<p>&#8220;Seriously, does it take ten minutes to pick out a pair of jeans?&#8221;</p>

<p>David chuckled. &#8220;You clearly haven&#8217;t had a girlfriend before.&#8221;</p>

<p>&#8220;You&#8217;re not a girl. It shouldn&#8217;t take you forever to get ready,&#8221; Michael protested and headed back down the stairs.</p>

<p>David pulled his black passport off of the desk and placed it in his jacket &#8216;s inner pocket before opening the door. Michael was standing in a white t-shirt and blue jeans. His gray fur was ruffled as if he didn&#8217;t bother to comb it.</p>

<p>&#8220;Just so you know, I do have a girlfriend,&#8221; Michael said as he crossed his arms. He looked over David critically. &#8220;It&#8217;s 80 degrees outside right now. It&#8217;s only going to get hotter.&#8221;</p>

<p>&#8220;Back home I wear this with armor. I&#8217;ll be fine.&#8221;</p>

<p>Michael gave him another weird look and headed down the stairs. David followed. They both walked out into the humid heat of a New York early summer. David waited as Michael locked the front door.</p>

<p>They headed away from the house towards the fish market some four miles away. Michael started asking questions almost immediately.</p>

<p>&#8220;You got in late last night. Your plane was supposed to get in at seven o&#8217;clock but you didn&#8217;t get to our place until eleven. What happened and why didn&#8217;t we pick you up from the airport?&#8221;</p>

<p>&#8220;I came on a US Air Force C-17.&#8221;</p>

<p>Michael&#8217;s ears perked up. &#8220;How did you get on one of those? What was it like?&#8221;</p>

<p>David sighed inwardly but smiled for his cousin&#8217;s benefit. He explained that the ride had been arranged by a friend he had in the US Embassy. The ride had been long and very bumpy but he didn&#8217;t mind. Unlike his father, he didn&#8217;t get airsick in turbulence. He was silent for a few steps as he considered what to else he could tell his cousin. A version of the truth was always better than an outright lie.</p>

<p>&#8220;I checked in with the Israeli embassy after my plane landed. Even though I&#8217;m on leave, my superiors want to be able to contact me so I had to let them know were I was. Besides,&#8221; David smiled, &#8220;one of the secretaries caught my eye. I waited for her to finish some paperwork and then we went out for a late dinner.&#8221;</p>

<p>As he expected Michael was extremely inquisitive about who he had dined with. It was easy to indulge him with the details. They went to a small pizzeria and ordered a large sausage pizza. The conversation was largely about hockey. The topic was unusual but interesting. By the time David was finished, he noticed they were in a rather dilapidated neighborhood. His fur was standing on end despite the lack of any visible danger. It was a feeling that he had learned to trust.</p>

<p>&#8220;Michael, are you sure we should be here?&#8221; he asked keeping a firm clamp on his nervousness.</p>

<p>&#8220;Yeah, this place looks a little weird but it&#8217;s safe enough. We&#8217;re almost there anyway.&#8221;</p>

<p>David made sure his jacket was loose before continuing their conversation.</p>

<p>&#8220;So, what have you been doing since I last visited?&#8221;</p>

<p>Michael&#8217;s tone was cheerful. &#8220;I graduated from high school with a 4.0. Now, I&#8217;m studying biology at UW-Madison. I picked UW-Madision because grandma Mae lives near there and I can get in-state tuition. I&#8217;m between semesters at the moment.&#8221;</p>

<p>As they turned the corner they walked into a group of felines standing around. David barely had time to notice several of them had handguns before shots rang out from across the street. One of the felines fell screaming. He half-dragged Michael away from the group and drew his own weapon. Two spotted cats pointed their pistols in his direction. Everything slowed down. The safety on his weapon clicked off and he fired two shots into the cat on the right while he dodged left. The range was barely 6 meters. The other cat fired too quickly and missed. David downed him with two shots to the head.</p>

<p>The rest happened too quickly for David to think about it. There were two tigers standing in front of him. One on them started to turn on him and David fired twice without hesitating. The last feline of the group looked at his friends before getting shot from across the street. With no threats in front of him he turned to look across the street. A group of 3 canines were standing across the street looking at him wide-eyed. He turned towards them keeping the gun aimed low but ready to fire if necessary. They scattered.</p>

<p>His attention immediately turned to the 4 canines laying in the street. A collie was still holding a pistol. He shouted at the collie to drop it. He shouted a second time before firing three unfortunately lethal rounds and reloaded. An eerie silence fell on the street. A car turned into the street only to stop suddenly. David held his gun low in one hand and kept an eye on the car as he checked out the single injured feline. She was gasping for breath and holding a bleeding wound in her stomach. The car backed out of the street and sped off. He kicked the pistol away from the gasping cat and ran over to Michael.</p>

<p>Michael&#8217;s head and chest was covered in blood and he wasn&#8217;t moving. A quick check showed he was still breathing. David holstered his pistol and removed his jacket and undershirt. He used his undershirt to wipe the blood off Michael&#8217;s head. His cousin had a head wound and only God knew what else. When he stripped off Michael&#8217;s shirt he thankfully didn&#8217;t find any additional wounds. He used the blood soaked shirt to wrap the head wound and rolled him on his side. David was still high on adrenaline as he looked around to assess the situation. He had basic first aid training but he didn&#8217;t even have the basic equipment he would have carried with him when on duty. He needed to call an ambulance. With Michael unconscious he fished through his pants to find a phone if he had one. David pulled out a fancy flip phone from Michael&#8217;s left pocket. He dialed 112 and hope that the phone would dial the correct local emergency number.</p>

<p>&#8220;Police, Fire, or Rescue?&#8221; A male operator answered.</p>

<p>David mental thanked God and replied, &#8220;I need police and medical. There has been a gun fight.&#8221;</p>

<p>&#8220;What is your location?&#8221;</p>

<p>David looked around for street signs or house numbers. He didn&#8217;t know were he was. &#8220;I don&#8217;t know,&#8221; he responded.</p>

<p>&#8220;Please stay on the line while I locate your phone.&#8221;</p>

<p>One of the dogs across the street was trying to get up. David drew his pistol and double checked the safety was on. With one hand he aimed the gun and shouted, &#8220;Stay down!&#8221;</p>

<p>&#8220;What is happening? Is there still fighting?, &#8221; the operator asked.</p>

<p>David watched at the canine laid back down. &#8220;No, one of injured was going for his gun.&#8221;</p>

<p>&#8220;Okay. I have your phone located. I am sending police and rescue to your location. Are you armed?&#8221;</p>

<p>&#8220;Yes, I have a pistol. I have the situation in control.&#8221;</p>

<p>&#8220;How any other people have weapons?&#8221;</p>

<p>&#8220;There are a number of guns on the ground but I don&#8217;t see anyone else holding one.&#8221;</p>

<p>The operator was silent for a few seconds. &#8220;Okay, how many people are injured.&#8221;</p>

<p>David swallowed. &#8220;I think seven. There are eleven people on the ground and I am sure four of them are dead. Most of the injuries are serious.&#8221;</p>

<p>&#8220;How can you tell they are dead?&#8221;</p>

<p>&#8220;Three of them have fatal headshots and the other doesn&#8217;t enough chest left to live.&#8221;</p>

<p>He thinks over the situation as the operator is silent. If he stays until the police arrives, the best he can hope for is to be arrested. He doesn&#8217;t have diplomatic immunity and his briefing didn&#8217;t cover this situation. As the operator starts to say something he hangs up and calls the Israeli Embassy in Washington D.C. He hopes they can sort this out.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Singleforest.com hits a major snag]]></title>
    <link href="http://epochwolf.com/blog/2010/04/27/singleforestcom-hits-a-major-snag/"/>
    <updated>2010-04-27T18:29:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/04/27/singleforestcom-hits-a-major-snag</id>
    <content type="html"><![CDATA[<p>Well I&#8217;ve been working on singleforest.com for a while. I made the mistake of choosing the Rails 3.0 beta with Ruby 1.9 for my application. I&#8217;ve spent almost at much time dealing with framework and library bugs as I have with writing code. Today I hit the final bug. The openid library I&#8217;ve been using doesn&#8217;t work with several openid providers due to the way Ruby 1.9 handles string encoding. The library throws unhandled exceptions that I can&#8217;t work around. I could try patching the library myself but I&#8217;m already working with 4 patched libraries that will likely not survive the next Rails 3.0 beta release.</p>

<p>So, I&#8217;ve decided to walk away from rails for a bit. I know I could use Rails 2.3.5 with Ruby 1.8 but I would like a change of scenery. I have previous experience with python so I have been looking at using Django or Pylons. Many people have wasted time on debating the merits of various framework for weeks before choosing one. I will have chosen a framework by this time tomorrow.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Capistrano: use git repository on the same server you deploy to]]></title>
    <link href="http://epochwolf.com/blog/2010/04/15/capistrano-use-git-repository-on-the-same-ser/"/>
    <updated>2010-04-15T18:32:00-07:00</updated>
    <id>http://epochwolf.com/blog/2010/04/15/capistrano-use-git-repository-on-the-same-ser</id>
    <content type="html"><![CDATA[<p>I ran across an interesting problem the other night. I finally convinced myself that I need to set up automated deployment for a personal website I was working on. The website is written in Ruby on Rails and I decided to use capistrano for deployment like ever other person I know that uses rails. The first problem I had was the capistrano docs are really really lacking in details. The tutorial covers the basics but that only works if you aren&#8217;t doing something wacky.</p>

<p>I&#8217;m using git for version control which isn&#8217;t all that odd. What is odd is that I don&#8217;t have a remote repository. I don&#8217;t really need to because I backup my laptop almost every night.  I don&#8217;t want capistrano to use the copy method for deployment because I don&#8217;t want to be trying to push several hundred kilobytes of data over a coffee shop&#8217;s overloaded public wifi for every deployment.</p>

<p>I didn&#8217;t want to use a git host like github or any one of a hundred others because I already rent a Virtual Private Server from slicehost.com. (256 slice to be specific) So I decided to just use git over ssh and store a copy of my repository on my server. It was pretty easy to create an empty repository on my server and push my local copy over. Capistrano however did not like this. My website needed to deploy to the same sever my remote repository was sitting on. There is no tutorial or examples for doing this. I googled for over an hour and read all the docs on capistrano.</p>

<p>The problem with capistrano is that by default the :repository variable only paths to urls or files on your local machine. I couldn&#8217;t find a way to tell capistrano to look on the deployment server for the repository.</p>

<p>The solution:</p>

<pre><code>set :repository, "file:///srv/git/repository.git"
set :local_repository, "file://."
</code></pre>

<p>The above works because setting undocumented variable :local_repository tells capistrano that :repository is a location on the app server. Suddenly, I&#8217;m able to deploy using export instead of copy. I hope I saved someone else hours of searching to figure out how to do this.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Singleforest: Registration with OpenID]]></title>
    <link href="http://epochwolf.com/blog/2010/02/12/singleforest-registration-with-openid/"/>
    <updated>2010-02-12T13:22:00-08:00</updated>
    <id>http://epochwolf.com/blog/2010/02/12/singleforest-registration-with-openid</id>
    <content type="html"><![CDATA[<p>Another screenshot from my development version of Singleforest.com. This is the sign up process.</p>

<p><img src="http://epochwolf.com/images/sf/registration.png"></p>

<p>And once you sign in.</p>

<p><img src="http://epochwolf.com/images/sf/choose_your_name.png"></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Singleforest: screenshot ]]></title>
    <link href="http://epochwolf.com/blog/2010/02/03/singleforest-screenshot/"/>
    <updated>2010-02-03T10:37:00-08:00</updated>
    <id>http://epochwolf.com/blog/2010/02/03/singleforest-screenshot</id>
    <content type="html"><![CDATA[<p>After 2 days of really hard work, I&#8217;ve gotten comments working on both literature and the forums. It would have been easier if ruby on rails didn&#8217;t have such a bungled acts_as_tree implementation. I was forced to use awesome_nested_set to implement a sane scheme for loading threaded comments. I figured it was better to use a decent plugin that I could drop later if I needed to than spend a week to write a better version of acts_as_tree now. (Nested set plugins have a rather nasty O(n) update scheme) As a result I can load an entire forum thread with only 3 queries.</p>

<p>Enjoy the screenshot. (The website is probably <strike>1-2 months</strike> 2-4 years<sup>*</sup> out from public beta tests)</p>

<p><img src="http://epochwolf.com/images/sf/screenshot.png"></p>

<p>*Rule of estimates: double and increase by one order of magnitude. (Months = Years, Years = Decades)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Bluecloth 2.0]]></title>
    <link href="http://epochwolf.com/blog/2010/01/18/using-bluecloth-20/"/>
    <updated>2010-01-18T11:04:00-08:00</updated>
    <id>http://epochwolf.com/blog/2010/01/18/using-bluecloth-20</id>
    <content type="html"><![CDATA[<p>This is a quick reference for how to use the BlueCloth 2.0 gem. I couldn&#8217;t find anything anywhere on how to use this gem so I used irb and the C source of the plugin to figure it out.</p>

<p>Require the gem in a generic ruby project.</p>

<pre><code>require 'rubygems'  #needed to load gems.
gem 'bluecloth', '&gt;= 2.0.0'  #need to specify we want the 2.0 version, not the 1.0 version.
require 'bluecloth'
</code></pre>

<p>If you are using Ruby on Rails just add the line below to your environment file.</p>

<pre><code>config.gem 'bluecloth', :version =&gt; '&gt;= 2.0.0' 
</code></pre>

<p>Once you have the gem included you can make a wrapper function</p>

<pre><code>def markdown_parse(str)
  bc = BlueCloth.new(str)
  bc.to_html
end
</code></pre>

<p>or a one-liner</p>

<pre><code>html = BlueCloth.new(str).to_html()
</code></pre>

<p>If you want to get more complicated and change the default options.</p>

<pre><code>def markdown_parse(str, options={})
  options = {
    :escape_html =&gt; true,
    :strict_mode =&gt; false,
  }.update(options)
  bc = BlueCloth.new(str, options)
  bc.to_html
end
</code></pre>

<p>A full list of options supported by BlueCloth 2.0.5 is below. Be sure to read the notes, some of them are important. You need to be using an html sanitizer with BlueCloth (such as rgrove&#8217;s sanitize) if you allow user-submitted html to be used with markdown.</p>

<h2>:remove_links => false</h2>

<p>Disable links in markdown. This will ignore the link syntax and break a tags in an unsafe manner. Recommend using a sanitizer instead.</p>

<p>WARNING <code>&lt;a href="testing"&gt;test&lt;/a&gt;</code> is converted to <code>&amp;lt;a href="testing"&gt;test&lt;/a&gt;</code> which leaves a trailing <code>&lt;/a&gt;</code> which is unsafe. It&#8217;s not dangerous but it could break the html on your site. It might also be possible to slip a tag past this using unicode or other tricks which is why I recommend using a sanitizer instead of this option.</p>

<h2>:remove_images => false</h2>

<p>Disable images in markdown. This will ignore the link syntax and break image tags naively using the same method as above. Recommend using a sanitizer instead.</p>

<h2>:smartypants => true</h2>

<p>Enable smartypants with markdown</p>

<h2>:pseudoprotocols => false</h2>

<p>Allow url syntax to create named anchors using id: and styled span tags using class:. Unsafe, allows duplicate ids in h tags. Html spec requires ids to be unique.</p>

<pre><code>[just as he said](id:foo) converts to &lt;a id="foo"&gt;just as he said&lt;/a&gt; 
[just as he said](class:foo) converts to &lt;span class="foo"&gt;just as he said&lt;/span&gt;
</code></pre>

<h2>:pandoc_headers => false</h2>

<p>Enable Discount extension named &#8220;pandoc_headers</p>

<p>This the unit test for this feature, I&#8217;ve never used it myself.</p>

<pre><code>it "correctly applies the :pandoc_headers option" do
  input = "% title\n% author1, author2\n% date\n\nStuff."
  bc = BlueCloth.new( input, :pandoc_headers =&gt; true )
  bc.header.should == {
    :title =&gt; 'title',
    :author =&gt; 'author1, author2',
    :date =&gt; 'date'
  }
  bc.to_html.should == '&lt;p&gt;Stuff.&lt;/p&gt;'
end
</code></pre>

<h2>:header_labels => false</h2>

<p>Auto generate ids for h tags. Unsafe, allows duplicate ids in h tags. Html spec requires ids to be unique.</p>

<pre><code># A header
Some stuff

## A header
More stuff.
is converted to

&lt;h1 id="A+header"&gt;A header&lt;/h1&gt;
&lt;p&gt;Some stuff&lt;/p&gt;
&lt;h2 id="A+header"&gt;A header&lt;/h2&gt;
&lt;p&gt;More stuff.&lt;/p&gt;
</code></pre>

<h2>:escape_html => false</h2>

<p>Escape any html the parser finds. Given how naive the html escaping is in :remove_links I would recommend using a sanitizer on top of this.</p>

<h2>:strict_mode => true</h2>

<p>When on, it follows the markdown spec strictly allowing the use of intraword emphasis. (<code>T*hi*s</code> converts to <code>T<i>hi</i>s</code>) When off, intraword emphasis are disabled and a subscript notation is added. I recommend setting this to false because intraword emphasis is annoying.</p>

<h2>:auto_links => false</h2>

<p>Convert bare urls in text into clickable links.</p>

<h2>:safe_links => false</h2>

<p>Only allow links that have recognized protocols to be parsed. Turning this on prevents relative urls from working. I recommend leaving this off and using a sanitizer instead.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scott Grimes]]></title>
    <link href="http://epochwolf.com/blog/2010/01/14/scott-grimes/"/>
    <updated>2010-01-14T13:58:00-08:00</updated>
    <id>http://epochwolf.com/blog/2010/01/14/scott-grimes</id>
    <content type="html"><![CDATA[<h2>Context</h2>

<p>Scott Grimes is adapted from a story I wrote in 2007 for nanowrimo. I&#8217;ve come to the conclusion that nanowrimo just frustrates me. (If you like it, keep at it.) I&#8217;ve gotten far more enjoyment plunking down in a coffee for an evening to enjoy coffee and writing. I care more about enjoying what I write than I do about making a novel. If it&#8217;s not fun for me to write, I doubt it will be fun for you to read.</p>

<h2>Story</h2>

<p>It was a cold winter day in Minnesota. Arctic air was blowing out of Canada. The forecast over the local grocery&#8217;s intercom predicted a major snow storm would be closing in over the night. Scott Grimes was one of many people in the small town just south of a military base stocking up supplies for the next few days. Scott was trying very hard to ignore the large number of angry stares and fearful glances he was attracting. Several of the people in the store were carrying holstered stun pistols.</p>

<p>Scott was a decorated combat veteran. He had six extra-planetary mission stars and a silver star on his dress uniform. He had joined the military when he turned eighteen against his father&#8217;s demands he go to business school. Joining the military was an act of rebellion, which he didn&#8217;t regret. After basic training he signed on with the marines. Most of the recruits were required to under go genetic modification. Scott choose the most extreme, most special of companies: the Winter Commandos.</p>

<p>Officially the marines designated a Winter Commando as a GeneMod A441. Unofficially GeneMod A441s were called &#8220;Anthos&#8221; by the rest of the marines. Doctors had found a way to turn a baseline human into a two-legged feline predator complete with prehensile tail, and white whiskers. The end result was barely human in form or temperament. The Marines wanted a predator specifically built for urban combat but flexible enough to handle any planetary terrain. They got exactly want they wanted.</p>

<p>The program had been in place for nearly 50 years with great success. The marines considered the Winter Commandos as a valuable assest. They had executed a total of 67 missions with minimal loss of life until New Africa.</p>

<p>New Africa had declared war on Earth citing racial and economic discrimination. All available Winter Commandos where sent along with as large as a task force Earth and it&#8217;s allies could send. The entire force of Winter Commandos had been airdropped into several of New Africa&#8217;s largest cities. The goal was to destroy all utilities and power stations in those cities and force the New African government to surrender. The end result was horrifying to both sides. The Winter Commandos dropped on several cities went on killing sprees resulting in enormous civilian causalities. Later analysis would point to the ecological term &#8220;surplus killing&#8221; as a possible explanation. Nearly two-thirds of the Winter Commandos dropped had to be killed by Earth marines. New Africa surrendered quicker than had been expected but no-one had cared about the war any more.</p>

<p>The fallout was extreme. An interplanetary conference was called and the city of Chicago on Earth was chosen as a meeting place. The Treaty of Chicago was drafted and signed three months later. The treaty banned the use of genetically modified soldiers and defined unlawful combatants which had been ignored by the Geneva Conventions.</p>

<p>Scott was honorably discharged after the signing of the treaty. He was one of the few commandos fortunate enough to be in a city that wasn&#8217;t littered with civilian bodies. His platoon was cleared of any possible war crimes. As a result he was able to receive a meager pension. Unfortunately being cleared of war crimes didn&#8217;t mean anything to an angry public.</p>

<p>Scott winced as some kid pulled on his tail. He heard the mother scolding her kid. Instead of lecturing her son or daughter about being polite she said the cat man might eat any offensive kids. The words spoken behind his back were the worst ones. He wasn&#8217;t a person, just some werewolf people told stories about to their kids. At least one person&#8217;s hand moved closer to his stunner.</p>

<p>He picked through the fruits and vegetables, adding a bag of apples, a bunch of bananas, several bags of spinach, and several yams to his cart. He moved on to the freezers and grabbed a dozen frozen stir-fry mixes. A large bag of rice was thrown in later. He always avoiding purchasing fresh meat from the grocery store. Only once had he done that and it seemed to make everyone more nervous. Instead he purchased any meat he would need from a butcher shop in the next town nearly twenty miles away.</p>

<p>Once he reached the checkout he was nearly panting. He had worn his knee length coat during his entire time in the store. The combination of a coat, his uniform, and his fur was stifling. The A441 genetic modifications had removed sweat glands from most of his body. Like a cat only the pads on his hands and feet would sweat. He quickly paid his bill in cash and carried his groceries outside. The dogsled he had brought with him was still outside the store. He piled his groceries onto it and started walking the mile to his apartment.</p>

<p>He reached his apartment complex as clouds obscured the sun. His apartment was on the sunken ground floor so he could drag his sled inside. The landlord was a veteran of some war that happened before he was born and was the only person in town that wasn&#8217;t afraid of him. He was the also the only person that would rent him a room. It wasn&#8217;t the best room in the building. Scott suspected the building used to be a nursing home or clinic and his room had been a store room. It was always cold because of some issue with the heating ducts and the floor was sealed concrete. At least it had a full bath. Cleaning fur in a small shower stall would had been difficult.</p>

<p>After getting his dogsled past the door, he hung his coat up in the closet. Getting his boots off was more involved than he liked. Normal shoes wouldn&#8217;t fit his paw-like feet so he was forced to walk barefoot or wear one of his pairs of combat boots. Finally free of his outerwear he dragged the dogsled into the kitchen to put the food his purchased away. His fridge was well stocked with fresh fruit and vegetables. It had little else in it. Another side effect of the gene modifications had been an intolerance to lactose in most of those receiving the mods. He also needed to eat larger amounts of meat than any human would need. That was one side effect he didn&#8217;t mind.</p>

<p>With the food finally put away and the water from the melted snow he dragged in mopped up, Scott could finally take a few minutes to relax. He was looking forward to the storm. He was planning to hike several miles out of town and build a shelter to spend a few days in the harshest terrestrial conditions he&#8217;d ever been in. He turned off all the lights, leaving the apartment in pitch black, and settled cross-legged on a small rug in front of a candle. With the flick of a lighter he lit the candle and then turned around. With his sensitive night-vision, he didn&#8217;t want to look directly into the candle. The light reflected on the wall was perfect to mediate on. He inhaled deeply, cleared his mind, and waited for the coming storm.</p>
]]></content>
  </entry>
  
</feed>
