<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>tail -f development.log</title>
	<atom:link href="http://craigjolicoeur.com/blog/feed" rel="self" type="application/rss+xml" />
	<link>http://craigjolicoeur.com/blog</link>
	<description>code with a purpose</description>
	<lastBuildDate>Sun, 19 Jun 2011 13:25:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>guard-annotate Gem Released</title>
		<link>http://craigjolicoeur.com/blog/guard-annotate-gem-released</link>
		<comments>http://craigjolicoeur.com/blog/guard-annotate-gem-released#comments</comments>
		<pubDate>Sat, 21 May 2011 13:18:14 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=163</guid>
		<description><![CDATA[I&#8217;ve been meaning to look into the guard gem for a while now. After falling out of love with ZenTest/Autotest, and switching back and forth between watchr and autotest-standalone, I&#8217;ve had a few friends who recommended giving guard a try. Last night, one of those friends retweeted a request for a guard plugin to work [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been meaning to look into the <a href="http://rubygems.org/gems/guard">guard gem</a> for a while now.  After falling out of love with ZenTest/Autotest, and switching back and forth between <a href="http://rubygems.org/gems/watchr">watchr</a> and <a href="http://rubygems.org/gems/autotest-standalone">autotest-standalone</a>, I&#8217;ve had a few friends who recommended giving <a href="https://github.com/guard/guard">guard</a> a try.</p>
<p>Last night, one of those friends retweeted a request for a guard plugin to work with the <a href="http://rubygems.org/gems/annotate">annotate gem</a>.</p>
<p><a href="http://twitter.com/#!/jschoolcraft/status/71588152787214336"><img src="http://craigjolicoeur.com/blog/wp-content/uploads/2011/05/Screen-shot-2011-05-21-at-9.12.10-AM.png" alt="" title="twitter retweet" width="480" height="283" class="aligncenter size-full wp-image-164" /></a></p>
<p>I figured that was good a cause as any to finally dig in and give guard a try.  What better way to begin using and understanding a gem, then by writing an extension for it?</p>
<p>About two hours later, I released the first versions of <a href="http://rubygems.org/gems/guard-annotate">guard-annotate on rubygems.org</a> (<a href="http://github.com/cpjolicoeur/guard-annotate">source code on Github</a>).</p>
<p>So, if you use the annotate gem on your rails projects, as well as guard, feel free to give the gem a try and save your self some time re-running your annotations.</p>
<p>As always, comments and questions, as well as pull requests for features and bugfixes are welcome.</p>
<p><strong>** UPDATE **</strong></p>
<p>guard-annotate has now been officially added to the main guard repository on GitHub.  You can still install the gem the same way, but now you can also find the codebase on<a href="https://github.com/guard/guard-annotate"> the guard page at GitHub</a> as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/guard-annotate-gem-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Echowaves Notifier for OSX Beta Release</title>
		<link>http://craigjolicoeur.com/blog/echowaves-notifier-for-osx-beta-release</link>
		<comments>http://craigjolicoeur.com/blog/echowaves-notifier-for-osx-beta-release#comments</comments>
		<pubDate>Wed, 30 Dec 2009 21:07:33 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[osx]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[echowaves]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=149</guid>
		<description><![CDATA[I've released the first beta version of my Echowaves Notifier for OS X]]></description>
			<content:encoded><![CDATA[<div style="text-align:center;margin-bottom:20px;" class="centered"><img src="http://craigjolicoeur.com/blog/wp-content/uploads/2009/12/echowaves_icon.png" alt="echowaves_icon.png" border="0" width="185" height="185" /></div>
<p>Today I&#8217;m making publicly available the first beta version of my new <a href="http://craigjolicoeur.com/echowaves-notifier/">Echowaves Notofier for OS X</a>.</p>
<p>The Echowaves Notifier is a simple OS X status bar application that will provide updates for when you have new messages in any conversations you follow on <a href="http://echowaves.com">Echowaves.com</a>.</p>
<p>The app is pretty simple at this point, but the core functionality works and I&#8217;m hoping to get some people to test it out.  Next up is adding growl support and some user preference options.</p>
<p>The <a href="http://github.com/cpjolicoeur/echowaves-notifier-osx">source code is available on github.com</a> and the application is released under the <a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> so feel free to hack away on it if you like.  If you do, please submit back any modifications so they can be included back into the &#8220;official&#8221; release.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/echowaves-notifier-for-osx-beta-release/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cerberus 0.7 Released</title>
		<link>http://craigjolicoeur.com/blog/cerberus-0-7-released</link>
		<comments>http://craigjolicoeur.com/blog/cerberus-0-7-released#comments</comments>
		<pubDate>Wed, 05 Aug 2009 15:37:05 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[cerberus]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=142</guid>
		<description><![CDATA[This morning I released version 0.7 of the Cerberus continuous integration gem. The gem (and zip and tarballs) are all available now via RubyForge. Thanks to all who had a part in this release. Paul Hinze added bazaar SCM support. Joe Van Dyk did some general code cleanup and Git SCM updates. So, grab the [...]]]></description>
			<content:encoded><![CDATA[<p>This morning I released <a href="http://rubyforge.org/frs/?group_id=1794">version 0.7</a> of the <a href="http://cerberus.rubyforge.org">Cerberus continuous integration gem</a>.</p>
<p>The gem (and zip and tarballs) are all available now via RubyForge.</p>
<p>Thanks to all who had a part in this release.  Paul Hinze added bazaar<br />
SCM support.  Joe Van Dyk did some general code cleanup and Git SCM<br />
updates.</p>
<p>So, grab the new version and kick the tires with it.  Get the word out.</p>
<p>I&#8217;d really like to see Cerberus get some more usage and to see it grow<br />
into a really mature, lightweight tool in the coming months.</p>
<p>Here is the changelog details for version 0.7</p>
<p>== Version 0.7<br />
New config options, Bazaar SCM support, removed GMailer bugfixes</p>
<p>* added support for bazaar scm<br />
* fixed bug with ActionMailer 2.3.3<br />
* removed GMailer library.  Use default Mail publisher instead<br />
* added &#8216;build_dir&#8217; option for setting custom build directory<br />
* added &#8216;setup_script&#8217; option for a custom script to be run before build command<br />
* Projects using the Git SCM were not getting the full diff output in<br />
their Publishers</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/cerberus-0-7-released/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disable spindump on OS X to prevent system slowdowns</title>
		<link>http://craigjolicoeur.com/blog/disable-spindump-on-os-x-to-prevent-system-slowdowns</link>
		<comments>http://craigjolicoeur.com/blog/disable-spindump-on-os-x-to-prevent-system-slowdowns#comments</comments>
		<pubDate>Wed, 10 Jun 2009 16:20:17 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[osx]]></category>
		<category><![CDATA[spindump]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=137</guid>
		<description><![CDATA[How to disable ( or prevent ) spindump from running after an OS X application crash]]></description>
			<content:encoded><![CDATA[<p>Every notice how slow and sluggish your OS X Leopard system can be after an application crash?  </p>
<p>This is probably because of the <a href="http://developer.apple.com/documentation/Darwin/Reference/Manpages/man8/spindump.8.html">spindump</a> utility that OS X launches to create crash and &#8220;hang&#8221; reports located in /Library/Logs/HangReporter.</p>
<p>This is all fine and good, but spindump has an annoying habit of thrashing your system disk and eating up a sizable chunk of RAM.  Personally, the MAJOR annoyance isn&#8217;t worth the aggravation just to get a useless &#8220;hang&#8221; report like the following.</p>
<pre class="brush: plain;">
Date/Time:      2008-07-09 16:33:26 -0400
OS Version:     10.5.4 (Build 9E17)
Architecture:   i386
Report Version: 4

Command:        Skitch
Path:           /Applications/Skitch.app/Contents/MacOS/Skitch
Version:        1.0b6.2 (1.0b6.2 (v10678))
Parent:         launchd [107]

PID:            377
Event:          hang
Time:           7.75s
Steps:          1
</pre>
<p>I&#8217;m sure there are many ways to disable this utility, but here is a quick an easy method I used to prevent the &#8220;sluggishness&#8221; after an app crash</p>
<pre class="brush: bash;">
sudo -i
cd /usr/sbin
mv spindump spindump.disabled
ln -s /usr/bin/true /usr/sbin/spindump
</pre>
<p>Problem solved!</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/disable-spindump-on-os-x-to-prevent-system-slowdowns/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>How to integrate punBB into an existing Ruby on Rails application</title>
		<link>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application</link>
		<comments>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application#comments</comments>
		<pubDate>Sat, 30 May 2009 15:32:12 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[forums]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[punBB]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=133</guid>
		<description><![CDATA[A quick tutorial on how to integrate the punBB forum system into an existing Rails application with a single sign-on for both systems.]]></description>
			<content:encoded><![CDATA[<p>I released launched a rails side project, <a href="http://xboxmma.com">XBoxMMA.com</a>, and one of the most requested features by the initial users was the addition of forums to the site.</p>
<p>Thinking it over, I clearly had two options: 1) code my own custom forum system for the site, or 2) use an existing forum system.</p>
<p>While I don&#8217;t mind coding forums for the site, I really didn&#8217;t want to set aside the time needed for coding when I could have been working on plenty of other projects.  So, I set out researching existing forum software that I could utilize.</p>
<p>In searching for a third-party forum system, I really only had one major requirement &#8211; users needed to be able to login to the main website and be authenticated at the same time on the forums.  I didn&#8217;t want my users to have to maintain separate accounts and separate logins for the forums and the main website.  If I did, there would be no need for this tutorial as implementing standalone forums is a basic task.</p>
<p><span id="more-133"></span>First off, I researched existing forum systems that were already rails based, hoping there was something I could quickly integrate into my app.  I checked out all the regular suspects like Beast, <a href="http://github.com/courtenay/altered_beast/tree/master">Altered Beast</a>, <a href="http://code.google.com/p/savage-beast-2/">Savage Beast 2</a>, and the new <a href="http://github.com/radar/rboard/tree/master">rBoard</a>.</p>
<p>Of the existing rails forums, rBoard showed the most promise but none of them really work well for integrating into an existing, established rails app.  All of the rails options are really intended for standalone use as a forum only.</p>
<p>Next I proceeded to research non-Rails based forums like <a href="http://bbpress.org/">bbPress</a>, <a href="http://www.vbulletin.com/">vBulletin</a>, <a href="http://www.phpbb.com/">phpBB</a> and a handful of others.</p>
<p>I ended up settling on the <a href="http://punbb.informer.com/">punBB</a> forum software, written in PHP.  I chose punBB for a few reasons: 1) it was a lightweight forum system, 2) it seemed to get good reviews online, and 3) I was able to find some existing information online on integrating punBB with Rails.</p>
<p>Terrell Russell wrote two blog posts (<a href="http://weblog.terrellrussell.com/2008/01/running-php-within-rails/">post one</a>, <a href="http://weblog.terrellrussell.com/2008/01/generating-a-rails-and-punbb-and-dokuwiki-shared-cookie/">post two</a>) regarding running PHP from within a Rails environment and how to get punBB (and DokuWiki) running within a Rails app using single sign-on.  I used Terrell&#8217;s posts as a starting point for my project as some of his information is now outdated for both Rails 2.3x and punBB 1.3x.</p>
<p>Now, on to the tutorial.</p>
<p>My next decision was to choose how exactly to integrate the PHP code into my Rails app.  I could put the forum&#8217;s PHP code into my application&#8217;s
<pre class="brush: plain; light: true;">RAILS_ROOT/public/forums/</pre>
<p> directory, or I could install the forums somewhere else on my servers file system.</p>
<p>Since the forums really are their own separate application, and the code is independent of my Rails code, I decided to install punBB on its own and leave it out of my source repository.  This will allow me to maintain/upgrade/modify the forum software without touching my Rails repository.</p>
<blockquote><p>As a side note, your server must be able to run PHP.  My app server is a <a href="http://www.debian.org/">Debian Lenny</a> system and I installed PHP via the normal
<pre class="brush: bash; light: true;">$ sudo aptitude install</pre>
<p> routine.  (Installing PHP on your server is beyond the scope of this tutorial.)</p></blockquote>
<p>I went ahead and setup the punBB files into
<pre class="brush: plain; light: true;">/var/www/punbb</pre>
<p> on my server.  I want users to be able to access the forums by visiting <a href='http://xboxmma.com/forums/'>http://xboxmma.com/forums</a>, so there were a few additional steps I needed to take.</p>
<p>First, when I deploy my app via <a href="http://www.capify.org/">capistrano</a>, I setup a symlink in the public directory to point to my forum installation.  I also copy the forum config file into my Rails app config directory (I&#8217;ll explain why later).  Add the following code to your capistrano deploy file.</p>
<pre class="brush: ruby;">
# RAILS_ROOT/config/deploy.rb
desc &amp;quot;Setup settings for punBB forums&amp;quot;
task :after_symlink, :roles =&amp;gt; [:app] do
  run &amp;quot;ln -nfs /var/www/punbb #{release_path}/public/forums&amp;quot;
  run &amp;quot;cp /var/www/punbb/config.php #{release_path}/config&amp;quot;
end
</pre>
<p>My app server uses <a href="http://wiki.nginx.org/Main">Nginx</a> as the web front end, so I also needed to update my nginx configuration to properly route requests for the new forums.</p>
<p>My existing nginx configuration file looked like this</p>
<pre class="brush: plain;">
server {
        listen  80;
        server_name xboxmma.com;
        root /home/deploy/xboxmma.com/current/public;
        passenger_enabled on;
        access_log off;
        client_max_body_size 20M;

        location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
                expires max;
                break;
        }

        if (-f $request_filename) {
                break;
        if (-f $document_root/system/maintenance.html) {
                rewrite ^(.*)$ /system/maintenance.html break;
        }

        error_page 500 502 503 504 /500.html;
        location = /500.html {
                root /home/deploy/xboxmma.com/current/public;
        }
}
</pre>
<p>I updated it with the following sections</p>
<pre class="brush: plain;">
        location /forums {
                root /var/www/punbb;
                index index.php;

                if (-f $request_filename) {
                        expires 30d;
                        break;
                }

                if (!-e $request_filename) {
                        rewrite ^(.+)$ /forums/index.php?q=$1 last;
                }
        }

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /opt/nginx/conf/fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }
</pre>
<p>The
<pre class="brush: plain; light: true;">location /forums {}</pre>
<p> block will process all requests that are made to the /forums path on my site.  I set the document root to
<pre class="brush: plain; light: true;">/var/www/punbb</pre>
<p> where I installed the punBB software and set the index page to index.php.</p>
<p>The
<pre class="brush: plain; light: true;">location ~ \.php$ {}</pre>
<p> block catches any request for a php page and passes the request along to the php5-cgi processor to handle the request.</p>
<p>The end result config file looks like this:</p>
<pre class="brush: plain;">
server {
        listen  80;
        server_name xboxmma.com;
        root /home/deploy/xboxmma.com/current/public;
        passenger_enabled on;
        access_log off;
        client_max_body_size 20M;

        location ~* \.(ico|css|js|gif|jp?g|png)(\?[0-9]+)?$ {
                expires max;
                break;
        }

        location /forums {
                root /var/www/punbb;
                index index.php;

                if (-f $request_filename) {
                        expires 30d;
                        break;
                }

                if (!-e $request_filename) {
                        rewrite ^(.+)$ /forums/index.php?q=$1 last;
                }
        }

        location ~ \.php$ {
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include /opt/nginx/conf/fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }

        if (-f $request_filename) {
                break;
        if (-f $document_root/system/maintenance.html) {
                rewrite ^(.*)$ /system/maintenance.html break;
        }

        error_page 500 502 503 504 /500.html;
        location = /500.html {
                root /home/deploy/xboxmma.com/current/public;
        }
}
</pre>
<p>Now that the boring php processing and routing stuff is out of the way, lets get into the important stuff and look how to integrate the authentication system of punBB and the Rails application.</p>
<p>The &#8220;trick&#8221; we will be using, is to manually set the login cookie for punBB whenever a user logs into the main website (we&#8217;ll delete the cookie as well when the user logs out).  The login cookie format has changed a bit since <a href="http://weblog.terrellrussell.com/2008/01/generating-a-rails-and-punbb-and-dokuwiki-shared-cookie/">Terrell&#8217;s writeup</a>, so I had to get my hands dirty and dig into the punBB PHP codebase to see exactly how they are setting their cookies.</p>
<p>First, add the following code to your application controller (or another controller if you don&#8217;t want/need the methods to be available everywhere).</p>
<pre class="brush: ruby;">
# RAILS_ROOT/app/controllers/application_controller.rb
  def set_shared_cookie
    return true unless Rails.env.production?
    require 'base64'
    expires = Time.now.to_i + 1209600

    begin
      # this sets the punbb cookie
      # it should be called on login from main site to allow unified login
      forumconfig = get_forum_config_data() # private method at bottom
      forumuser = ForumAccount.find_by_username( current_user.username )

      forum_hash = Digest::SHA1.hexdigest( forumuser.salt + Digest::SHA1.hexdigest( expires.to_s ) )
      cookie_value = &amp;quot;#{forumuser.id}|#{forumuser.password}|#{expires.to_s}|&amp;quot;
      cookie_value &amp;lt;&amp;lt; Digest::SHA1.hexdigest( &amp;quot;#{forumuser.salt}#{forumuser.password}#{forum_hash}&amp;quot; )

      cookies[forumconfig[:cookie_name]] = {
        :value =&amp;gt; Base64.encode64( cookie_value ),
        :expires =&amp;gt; 14.days.from_now
      }
    rescue =&amp;gt; e
      Rails.logger.warn &amp;quot;Problem setting punBB cookie #{e.message}&amp;quot;
    end
  end

  def clear_shared_cookie
    return true unless Rails.env.production?
    begin
      # should be called on logout from main site
      forumconfig = get_forum_config_data() # private method at bottom
      cookies[forumconfig[:cookie_name]] = nil
    rescue =&amp;gt; e
      Rails.logger.warn &amp;quot;Problem clearing punBB cookie #{e.message}&amp;quot;
    end
  end

  private

  # Uses regex to parse the php punbb config file
  # taken from: ahgsoftware.com/punbb_sdk/
  def get_forum_config_data
    config_hash = Hash.new
    c = File.read( File.join( RAILS_ROOT, 'config', 'config.php' ) )
    c.scan(/\$(\w*)\s*=\s*['&amp;quot;](.*)['&amp;quot;];/).each do |pair|
      config_hash[pair[0].to_sym] = pair[1]
    end
    config_hash
  end
</pre>
<p>The
<pre class="brush: plain; light: true;">#get_forum_config_data</pre>
<p> private method simply reads the punBB config.php file to get the forum configuration info. (Remember we copied the config.php file over in our capistrano deploy addition.)</p>
<p>Both the
<pre class="brush: plain; light: &quot;true&quot;;">#set_shared_cookie</pre>
<p> method and the
<pre class="brush: plain; light: true;">#clear_shared_cookie</pre>
<p> method will only run during production mode.  I don&#8217;t have punBB setup on my dev system.  If you run a staging server you probably want to change it to check
<pre class="brush: plain; light: true;">Rails.env.development?</pre>
<p> so that the method will also be processed on your staging server.</p>
<p>You&#8217;ll also notice I wrap everything in both methods in a
<pre class="brush: ruby; light: true;">begin ... rescue</pre>
<p> block.  I don&#8217;t want errors in the cookie creation/deletion to throw errors to the users, so I just log then gracefully for now.</p>
<p>Let&#8217;s do a quick run through on the #set_shared_cookie method.  First we set an integer expiration date to 14 days in the future (the default punBB cookie length).  Next we read the forum config data and find the existing user record from the punBB database via the ForumAccount model.  We&#8217;ll look at the ForumAccount model in a bit.  </p>
<p>Next we set the cookie value so it appears in the same format the punBB will expect when it reads the cookie back in and write the cookie to the session.</p>
<p>For XBoxMMA.com I use <a href="http://github.com/binarylogic/authlogic/tree/master">Authlogic</a> as the authentication system, so I call the set_shared_cookie method from my user_sessions controller after a new session is created.  I also call it from my users_controller when a new user is created.  I call the clear_shared_cookie method when the user logs out.</p>
<p>Now that we&#8217;ve seen how to make the shared cookie, lets look at the models used to access the punBB database tables.</p>
<p>I use a separate database for punBB instead of dumping the tables into my rails app DB, so I added an extra section to my
<pre class="brush: plain; light: true;">RAILS_ROOT/config/database.yml</pre>
<p> file.</p>
<pre class="brush: plain;">
forums_production:
  adapter: mysql
  database: xboxmma_forum
  username: xboxmma
  password: password
  host: localhost
  encoding: utf8
  socket: /var/run/mysqld/mysqld.sock
</pre>
<p>If you are using a staging environment, be sure to add a &#8220;forums_staging&#8221; section as well.</p>
<p>Next, I added two new models to access the punBB DB.</p>
<pre class="brush: ruby;">
# app/models/forum.rb
class Forum &amp;lt; ActiveRecord::Base
  self.abstract_class = true
  establish_connection &amp;quot;forums_#{Rails.env}&amp;quot;
end

# app/models/forum_account.rb
class ForumAccount &amp;lt; Forum
  set_table_name 'users' # add the table prefix if you set one in punBB

  def encrypt_and_save_new_password( _password )
    write_attribute( &amp;quot;password&amp;quot;, forum_hash( _password ) )
    save
  end

  private

  def forum_hash( _str )
    Digest::SHA1.hexdigest( self.salt + Digest::SHA1.hexdigest( _str ) )
  end

end
</pre>
<p>The
<pre class="brush: ruby; light: true;">#encrypt_and_save_new_password</pre>
<p> method should be called anytime your user updates their password in your Rails app.  This method will update their forum password at the same time and keep the two in sync.</p>
<p>Now you have Rails models setup that will be able to access your punBB DB (you will remember the ForumAccount model we referenced earlier in the set_shared_cookie method).</p>
<p>Everything should now be working for you.  Don&#8217;t forget to run the
<pre class="brush: plain; light: true;">admin/install.php</pre>
<p> script as well to setup your initial punBB configuration.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/how-to-integrate-punbb-into-an-existing-ruby-on-rails-application/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Rails IE Bug with Excel Mime Types</title>
		<link>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types</link>
		<comments>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types#comments</comments>
		<pubDate>Thu, 28 May 2009 16:29:27 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[IE7]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=129</guid>
		<description><![CDATA[Another example of why IE is awful and a gotcha to lookout for in your Rails app]]></description>
			<content:encoded><![CDATA[<p>Came across a pretty interesting issue this week while trying to do some bugfixes for a project in IE6 and IE7.</p>
<p>The Rails project I&#8217;m working on has one action that accepts an *.xls format to deliver an excel spreadsheet to the user.  Getting this to work is very simple, but for the sake of explanation here is the process.</p>
<p>Simply register the mime type in an initializer file</p>
<pre class="brush: ruby;">
# config/initializers/mime_types.rb
Mime::Type.register &quot;application/vnd.ms-excel&quot;, :xls
</pre>
<p>Then in your controller action&#8217;s respond_to block you can simply reference the new format:</p>
<pre class="brush: ruby;">
# app/controllers/my_controller.rb
def my_action
  ...
  respond_to do |format|
    format.xls { send_file ... }
  end
end
</pre>
<p>Now, back to the &#8220;bug&#8221; or issue with IE6 and IE7.  Every time a user hit that specific action with a regular request (not requesting the *.xls format), they received both the expected HTML output AND the xls format output.  </p>
<p>Naturally, I don&#8217;t want to bombard the user with an IE popup dialog asking them to download an Excel file when they aren&#8217;t requesting one. </p>
<p>A quick trip to Google turned up <a href="http://dev.rubyonrails.org/ticket/9535">this old Rails ticket</a>.  The issue appears to be with how IE6 and IE7 set their HTTP_ACCEPT headers:</p>
<pre class="brush: plain;">
image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, */*
</pre>
<p>There are two easy work-around solutions.</p>
<p>First, you can manually check and set the format param for IE requests:</p>
<pre class="brush: ruby;">
before_filter :hijack_ie_default_format

def hijack_ie_default_format
  if request.user_agent =~ /MSIE/ and params['format'].nil?
    params['format'] = 'html'
  end
end
</pre>
<p>However, be careful when doing this.  If your action can also accept AJAX ( text/javascript ) requests, then this will override that as well and set the format to return as HTML which is obviously not what you want.  You would then end up spending a few hours wondering why IE6 and IE7 where returning javascript &#8220;Syntax Errors&#8221; on your AJAX actions.</p>
<p>What I ended up doing, since I needed that specific action to respond to javascript requests as well, was to simply extract the excel request into its own action.  Sure this may be overkill and not very DRY, but it is still a proper solution.  I just created a new #excel_export action and updated my excel links to point to the new action.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/rails-ie-bug-with-excel-mime-types/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using Cerberus to Build Rails</title>
		<link>http://craigjolicoeur.com/blog/using-cerberus-to-build-rails</link>
		<comments>http://craigjolicoeur.com/blog/using-cerberus-to-build-rails#comments</comments>
		<pubDate>Sun, 24 May 2009 18:38:18 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[cerberus]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=127</guid>
		<description><![CDATA[A nice guide on how to use the latest version of Cerberus to build Rails with multiple versions of Ruby.]]></description>
			<content:encoded><![CDATA[<p>Over the weekend, I released version 0.5 of the <a href="http://cerberus.rubyforge.org">Cerberus gem</a>.</p>
<p>The release included some better test support, as well as support for git branches and custom settings file inclusion for the Maven2 builder.</p>
<p>No, sooner had version 0.5 been released, then we began work in earnest on version 0.6</p>
<p><a href="http://twitter.com/mikeg1">Mike Gunderloy</a> has been working on adding features to Cerberus to support using a custom Ruby script as a project builder.  The main reason, is to build the Rails project using their ci_setup.rb, CruiseControl build script.</p>
<p>The current code with Ruby builder support can be found in the <a href="http://github.com/cpjolicoeur/cerberus/tree/ruby_builder">ruby_builder branch of the main repository</a> at the moment.</p>
<p>In addition, <a href="http://afreshcup.com/2009/05/24/building-rails-with-cerberus-and-multiruby/">Mike wrote an excellent blog post on how he is building Rails using Cerberus and multiruby</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/using-cerberus-to-build-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting Static Asset Expires Headers with nginx and Passenger</title>
		<link>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger</link>
		<comments>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger#comments</comments>
		<pubDate>Wed, 20 May 2009 19:01:17 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[headers]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=125</guid>
		<description><![CDATA[How to set HTTP expires headers for your static assets when running nginx+passenger]]></description>
			<content:encoded><![CDATA[<p>On a recent project I launched, I&#8217;m using the combination <a href="http://www.modrails.com/install.html">nginx+passenger</a> for my front end my my Ruby on Rails application.</p>
<p>While trying to boost my <a href="http://developer.yahoo.com/yslow/">YSlow</a> score, I was having a bit of difficulty trying to figure out how to set HTTP expires headers on all the static assets served by my app.</p>
<p>Rails will set an internal time stamp on static assets (images, css files, javascript files, etc&#8230;) by appending a integer value onto the end of the asset filename</p>
<pre class="brush: plain; light: true;">http://mydomain.com/images/asset.png?12345678</pre>
<p>My original attempt at getting nginx to set an expires header for these assets had me adding the following location block to my nginx config file:</p>
<pre class="brush: plain;">
location ~* \.(ico|css|js|gif|jpe?g|png)\?[0-9]+$ {
    expires max;
    break;
}
</pre>
<p>The regexp I was using was incorrect however as it didn&#8217;t take into account that the ?timestamp might not exist in the URI.</p>
<p><a href="http://izumi.plan99.net/blog/">Hongli Lai</a> kindly pointed me in the right direction and showed me the proper regexp that he is using.</p>
<pre class="brush: plain;">
location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
    expires max;
    break;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/setting-static-asset-expires-headers-with-nginx-and-passenger/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Rails plugin install from specific git branch</title>
		<link>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch</link>
		<comments>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch#comments</comments>
		<pubDate>Tue, 19 May 2009 18:07:55 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[git]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=100</guid>
		<description><![CDATA[How to install a rails plugin from a specific tag or branch in a git repository]]></description>
			<content:encoded><![CDATA[<p>Recently while working on a Ruby on Rails plugin, I came across the need to install the plugin from a specific git branch instead of the default master branch.</p>
<pre class="brush: bash; light: true;">
./script/plugin install -h
</pre>
<p>yielded the helpful information I needed.  Last July, <a href="http://github.com/rails/rails/commit/5c086070824bf7dd2bc4c9ce97956d82ac3fa206">a patch was committed</a> to Rails that added the -r ( or &#8211;revision ) parameter.</p>
<p>The -r parameter will take either the name of a git branch or a tag string to checkout instead of the default master branch.</p>
<p>So issuing the following command:</p>
<pre class="brush: bash; light: true;">
./script/plugin install git://github.com/cpjolicoeur/my_plugin.git -r BRANCH_NAME
</pre>
<p>will checkout the BRANCH_NAME branch of the git repository.</p>
<p>Very helpful when testing and debugging new features and bugfixes in a plugin. </p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/rails-plugin-install-from-specific-git-branch/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Getting Capistrano&#8217;s web:disable To Work With Nginx</title>
		<link>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx</link>
		<comments>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx#comments</comments>
		<pubDate>Sun, 17 May 2009 17:13:25 +0000</pubDate>
		<dc:creator>Craig</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://craigjolicoeur.com/blog/?p=92</guid>
		<description><![CDATA[Recently I deployed a new Ruby on Rails application using nginx+passenger instead of the usual apache+passenger configuration. As a result, I couldn&#8217;t use the traditional Apache rewrite rules to display the maintenance.html page if it existed. Here are the necessary corresponding rewrite rules for nginx to achieve the same effect. if (-f $document_root/system/maintenance.html) { rewrite [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I deployed a new Ruby on Rails application using <a href="http://www.modrails.com/install.html">nginx+passenger</a> instead of the usual apache+passenger configuration.</p>
<p>As a result, I couldn&#8217;t use the traditional Apache rewrite rules to display the maintenance.html page if it existed.</p>
<p>Here are the necessary corresponding rewrite rules for nginx to achieve the same effect.</p>
<pre class="brush: plain;">
if (-f $document_root/system/maintenance.html) {
    rewrite ^(.*)$ /system/maintenance.html break;
}
</pre>
<p>Place this inside your server {} block and you should be able to run cap deploy:web:disable and cap deploy:web:enable with no problems.</p>
]]></content:encoded>
			<wfw:commentRss>http://craigjolicoeur.com/blog/getting-capistranos-webdisable-to-work-with-nginx/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

