<?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>dan.thoughts &#187; Ruby</title>
	<atom:link href="http://blog.sosedoff.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sosedoff.com</link>
	<description>Web-development, PHP, Ruby, Sinatra, Merb, Rails, MySQL, SQLite, Web Services.</description>
	<lastBuildDate>Wed, 25 Jan 2012 18:54:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Adding code revision header to your apps</title>
		<link>http://blog.sosedoff.com/2012/01/25/adding-code-revision-header-to-your-apps/</link>
		<comments>http://blog.sosedoff.com/2012/01/25/adding-code-revision-header-to-your-apps/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 18:54:45 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[rack]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=423</guid>
		<description><![CDATA[Sometimes its necessary to have a code revision tag somewhere on the website. Use cases are usually different and vary from just checking against the current revision, automatic upgrades and such. 
If you&#8217;re rolling deployments with capistrano, it will insert the REVISION file under the app&#8217;s root dir with git sha or svn revision or [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes its necessary to have a code revision tag somewhere on the website. Use cases are usually different and vary from just checking against the current revision, automatic upgrades and such. </p>
<p>If you&#8217;re rolling deployments with capistrano, it will insert the REVISION file under the app&#8217;s root dir with git sha or svn revision or whatever tag based on SCM of your choice.</p>
<p>Here is the simple rack middleware that injects that revision as a &#8216;X-REVISION&#8217; header in responses.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Rack
  <span style="color:#9966CC; font-weight:bold;">class</span> Revision
    @@revision = <span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span> = ::<span style="color:#CC00FF; font-weight:bold;">File</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>app, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@app</span>   = app
      <span style="color:#0066ff; font-weight:bold;">@block</span> = block
      <span style="color:#0066ff; font-weight:bold;">@file</span>  = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">pwd</span>, <span style="color:#996600;">'REVISION'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> call<span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      status, headers, body = <span style="color:#0066ff; font-weight:bold;">@app</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      headers<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'X-Revision'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = revision
      <span style="color:#006600; font-weight:bold;">&#91;</span>status, headers, body<span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    protected
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> revision
      @@revision <span style="color:#006600; font-weight:bold;">||</span>= read_revision
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> read_revision
      <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>@file<span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#40;</span>@file<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">strip</span> : <span style="color:#996600;">'UNDEFINED'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For instance, just put that file as lib/rack/revision.rb and change your config.ru file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> ::<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'../config/environment'</span>,  <span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span>
use <span style="color:#6666ff; font-weight:bold;">Rack::Revision</span>
run <span style="color:#6666ff; font-weight:bold;">YOUR_APP::Application</span></pre></div></div>

<p>You&#8217;ll need to restart the app to apply the changes.</p>
<p>To test if it works just run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">curl <span style="color: #660033;">-i</span> <span style="color: #660033;">-X</span> HEAD <span style="color: #ff0000;">&quot;http://YOUR_WEBSITE/&quot;</span></pre></div></div>

<p>Sample output would be:</p>
<pre>
ETag: "8d6228d86642025c31e3d54e9a67b14b"
Cache-Control: max-age=0, private, must-revalidate
X-Runtime: 0.001491
X-Rack-Cache: miss
X-Revision: f8c51630843898e88848261dd5ebac3fdebc5e48
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2012/01/25/adding-code-revision-header-to-your-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploying Rails application with Capistrano and Unicorn</title>
		<link>http://blog.sosedoff.com/2011/10/23/deploying-rails-application-with-capistrano-and-unicorn/</link>
		<comments>http://blog.sosedoff.com/2011/10/23/deploying-rails-application-with-capistrano-and-unicorn/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 22:15:13 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[unicorn]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=405</guid>
		<description><![CDATA[I&#8217;ve been switching all my new applications to Unicorn (nginx+unicorn) from Passenger (nginx+passenger). Passenger comes with an extension to nginx and needs to be compiled with nginx as a plugin. That requires additional maintenance on server and not a good idea in general when having more that just 1 ruby runtime on the server. 
I [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been switching all my new applications to <a href="http://unicorn.bogomips.org/">Unicorn</a> (nginx+unicorn) from <a href="http://www.modrails.com/">Passenger</a> (nginx+passenger). Passenger comes with an extension to nginx and needs to be compiled with nginx as a plugin. That requires additional maintenance on server and not a good idea in general when having more that just 1 ruby runtime on the server. </p>
<p>I use <a href="https://github.com/capistrano/capistrano">capistrano</a> for all my apps and find it very useful for quick and handy deployments. After switch to unicorn i&#8217;ve been copying-and-pasting the same code over and over again, so i decided to move it to a separate gem. </p>
<p>Check out code on github &#8211; <a href="https://github.com/sosedoff/capistrano-unicorn">capistrano-unicorn</a>.</p>
<h3>Usage</h3>
<p>Assuming that you already have your capistrano script ready, add gem to the Gemfile:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">group <span style="color:#ff3333; font-weight:bold;">:development</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  gem <span style="color:#996600;">'capistrano-unicorn'</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Then, add requirement to the deploy.rb file (after all hooks):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'capistrano-unicorn'</span></pre></div></div>

<h3>Configuration</h3>
<p>All unicorn configs should be placed under APP_ROOT/config/unicorn/ENVIRONMENT.rb<br />
So, for each environment there should be a separate file.</p>
<p>Test if that worked:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">cap unicorn:start
cap unicorn:stop
cap unicorn:reload</pre></div></div>

<p>For more information check out github repository &#8211; <a href="https://github.com/sosedoff/capistrano-unicorn">capistrano-unicorn</a>.<br/><br />
It is still under development, but basic functionality works fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/10/23/deploying-rails-application-with-capistrano-and-unicorn/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Capistrano MySQL Backups for Rails</title>
		<link>http://blog.sosedoff.com/2011/08/10/capistrano-mysql-backups-for-rails/</link>
		<comments>http://blog.sosedoff.com/2011/08/10/capistrano-mysql-backups-for-rails/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 00:34:50 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[backups]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=395</guid>
		<description><![CDATA[If you need to backup your application before each deployment, here is the small manual.
Capistrano versions: >= 2.5
Configuration
First, you need to define application environment:

# Define server-side rails environment
set :rails_env, &#34;production&#34;
&#160;
# Primary deployment location
set :deploy_to, &#34;/home/#{user}/#{application}&#34;
&#160;
# Place where all backups will be dumped
set :backup_to, &#34;/home/#{user}/#{application}/backups&#34;

Also, add this function. It allows capistrano to check if remote file [...]]]></description>
			<content:encoded><![CDATA[<p>If you need to backup your application before each deployment, here is the small manual.</p>
<p>Capistrano versions: >= 2.5</p>
<h2>Configuration</h2>
<p>First, you need to define application environment:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Define server-side rails environment</span>
set <span style="color:#ff3333; font-weight:bold;">:rails_env</span>, <span style="color:#996600;">&quot;production&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Primary deployment location</span>
set <span style="color:#ff3333; font-weight:bold;">:deploy_to</span>, <span style="color:#996600;">&quot;/home/#{user}/#{application}&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Place where all backups will be dumped</span>
set <span style="color:#ff3333; font-weight:bold;">:backup_to</span>, <span style="color:#996600;">&quot;/home/#{user}/#{application}/backups&quot;</span></pre></div></div>

<p>Also, add this function. It allows capistrano to check if remote file exists:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> remote_file_exists?<span style="color:#006600; font-weight:bold;">&#40;</span>full_path<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#996600;">'true'</span> ==  capture<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;if [ -e #{full_path} ]; then echo 'true'; fi&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">strip</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, we need to add a backup task:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">namespace <span style="color:#ff3333; font-weight:bold;">:utils</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  desc <span style="color:#996600;">'Backup database before deploy'</span>
  task <span style="color:#ff3333; font-weight:bold;">:backup</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:db</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:primary <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    run <span style="color:#996600;">&quot;mkdir -p #{backup_to}&quot;</span> <span style="color:#008000; font-style:italic;"># Create a backup folder unless exists</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Primary backup filename</span>
    filename = <span style="color:#996600;">&quot;#{backup_to}/#{application}_predeploy_#{Time.now.strftime(&quot;</span><span style="color:#006600; font-weight:bold;">%</span>m<span style="color:#006600; font-weight:bold;">%</span>d<span style="color:#006600; font-weight:bold;">%</span>Y<span style="color:#006600; font-weight:bold;">%</span>H<span style="color:#006600; font-weight:bold;">%</span>I<span style="color:#006600; font-weight:bold;">%</span>S<span style="color:#996600;">&quot;)}.sql.gz&quot;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Check if we've got database config</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> remote_file_exists?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{deploy_to}/current/config/database.yml&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>    
      text = capture<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;cat #{deploy_to}/current/config/database.yml&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      config = <span style="color:#CC00FF; font-weight:bold;">YAML</span>::<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span>text<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>rails_env<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
      on_rollback <span style="color:#006600; font-weight:bold;">&#123;</span> run <span style="color:#996600;">&quot;rm #{filename}&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
      run <span style="color:#996600;">&quot;mysqldump -u #{config['username']} -p #{config['database']} | gzip --best &gt; #{filename}&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>ch, stream, out<span style="color:#006600; font-weight:bold;">|</span>
        ch.<span style="color:#9900CC;">send_data</span> <span style="color:#996600;">&quot;#{config['password']}<span style="color:#000099;">\n</span>&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> out =~ <span style="color:#006600; font-weight:bold;">/</span>^Enter password:<span style="color:#006600; font-weight:bold;">/</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      logger.<span style="color:#9900CC;">debug</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;[Backup] No configuration file was found.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And finally, add the capistrano before hook:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">before <span style="color:#996600;">&quot;deploy&quot;</span>, <span style="color:#996600;">&quot;utils:backup&quot;</span></pre></div></div>

<h2>Testing</h2>
<p>To test if the task works, run:</p>
<pre>cap utils:backup</pre>
<p>On the server side you should see a backup file:</p>
<pre>/home/USER/APP/backups/APP_predeploy_MMDDYYHHMMSS.sql.gz.</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/08/10/capistrano-mysql-backups-for-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Processing emails with Postfix and Rails</title>
		<link>http://blog.sosedoff.com/2011/08/10/processing-emails-with-postfix-and-rails/</link>
		<comments>http://blog.sosedoff.com/2011/08/10/processing-emails-with-postfix-and-rails/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 00:28:44 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Gems]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[mail processing]]></category>
		<category><![CDATA[postfix]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=391</guid>
		<description><![CDATA[This is a short manual on how to setup postfix and rails application to receive and process email messages.
Stack:

Debian / Ubuntu Server
Postix
Ruby 1.9
Rails 3.0

Overview
You have an application where users get email notifications. And you want to allow them to reply directly to the email.
In order to do so, each email should have an unique (depends [...]]]></description>
			<content:encoded><![CDATA[<p>This is a short manual on how to setup postfix and rails application to receive and process email messages.</p>
<p>Stack:</p>
<ul>
<li>Debian / Ubuntu Server</li>
<li>Postix</li>
<li>Ruby 1.9</li>
<li>Rails 3.0</li>
</ul>
<h2>Overview</h2>
<p>You have an application where users get email notifications. And you want to allow them to reply directly to the email.<br />
In order to do so, each email should have an unique (depends on situation) reply-to address. Usually its something like that:</p>
<pre><code>P946d272cf7da4dd6b0cb613605bced65@yourdomain.com
</code></pre>
<p>This means that the mailserver you use should support dynamic/virtual email addresses and forwarding.</p>
<h2>Postfix Configuration</h2>
<p>First, you&#8217;ll need to install postfix (in not installed):</p>
<pre><code>apt-get install postfix
</code></pre>
<p>Configuration should look like this:</p>
<pre><code># See /usr/share/postfix/main.cf.dist for a commented, more complete version

default_privs = apps

# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = ap

smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# TLS parameters
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls=no
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.

myhostname = YOUR_APP_HOSTNAME
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydomain = YOUR_APP_DOMAIN
mydestination = YOUR_APP_DOMAIN, localhost
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
relay_domain = localhost
recipient_canonical_maps = regexp:/etc/postfix/recipient_canonical
</code></pre>
<p>Last option <strong>recipient_canonical_maps</strong> allows you to define a dynamic email addresses and forward them to the specific system mailbox for processing.</p>
<p>Create a file /etc/postfix/recipient_canonical:</p>
<pre><code>/^P[0-9abcdef]{1,}(M[0-9]{1,})?/ apps
</code></pre>
<p>This will add a virtual recipient addresses and forward messages to user apps.</p>
<p><strong>NOTE:</strong> <em>Regular expressions should be in POSIX format</em>. For test you can use <a href="http://www.regextester.com/">regextester.com</a></p>
<h2>Email Aliases</h2>
<p>After you added support for virtual addresses all mail will be delivered to the system user mailbox (apps). But, we need to drive all that traffic into our app. In order to do so we will have to setup mail piping directly into your application script.</p>
<p>Edit /etc/aliases:</p>
<pre><code>apps: "| /home/apps/APP_NAME/current/script/email_receiver_script"
</code></pre>
<p>And rebuild the aliases db by running:</p>
<pre><code>newaliases
</code></pre>
<p>Do not forget to restart postfix:</p>
<pre><code>/etc/init.d/postfix restart
</code></pre>
<p>You can test out the email delivery. For errors check /var/log/mail.info</p>
<h2>Mail Receiver Script</h2>
<p>Since all mail will be forwarded directly to our mail receiver script via piping there are few things to consider:</p>
<ul>
<li>Email receiver should consume as less memory as possible.</li>
<li>Email receiver should not load the whole application (because of item above).</li>
<li>Email receiver should only validate and preprocess incoming messages and leave actual processing to another subsystem via queue.</li>
</ul>
<h3>Configuration</h3>
<p>There are few ruby libraries that are well suited for this case:</p>
<ul>
<li><a href="https://github.com/mikel/mail">mail</a> &#8211; Email processing, ruby 1.9.2 compatible (comparing to tmail which is not)</li>
<li><a href="https://github.com/antirez/redis">redis</a> &#8211; Simple key-value in-memory database.</li>
<li><a href="https://github.com/defunkt/resque">resque</a> &#8211; Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them.</li>
</ul>
<p>Install gems:</p>
<pre><code>gem install mail redis resque
</code></pre>
<p>Here is an example email receiver script:</p>
<div class="highlight">
<pre><span class="c1">#!/usr/bin/env ruby</span> 

<span class="nb">require</span> <span class="s1">&#39;rubygems&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;mail&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;redis&#39;</span>
<span class="nb">require</span> <span class="s1">&#39;resque&#39;</span> 

<span class="k">class</span> <span class="nc">EmailReply</span>
  <span class="vi">@queue</span> <span class="o">=</span> <span class="ss">:email_replies</span> 

  <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
    <span class="n">mail</span>    <span class="o">=</span> <span class="no">Mail</span><span class="o">.</span><span class="n">read_from_string</span><span class="p">(</span><span class="n">content</span><span class="p">)</span>
    <span class="n">from</span>    <span class="o">=</span> <span class="n">mail</span><span class="o">.</span><span class="n">from</span><span class="o">.</span><span class="n">first</span>
    <span class="n">to</span>      <span class="o">=</span> <span class="n">mail</span><span class="o">.</span><span class="n">to</span><span class="o">.</span><span class="n">first</span> 

    <span class="k">if</span> <span class="n">mail</span><span class="o">.</span><span class="n">multipart?</span>
      <span class="n">part</span> <span class="o">=</span> <span class="n">mail</span><span class="o">.</span><span class="n">parts</span><span class="o">.</span><span class="n">select</span> <span class="p">{</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span> <span class="nb">p</span><span class="o">.</span><span class="n">content_type</span> <span class="o">=~</span> <span class="sr">/text\/plain/</span> <span class="p">}</span><span class="o">.</span><span class="n">first</span> <span class="k">rescue</span> <span class="kp">nil</span>
      <span class="k">unless</span> <span class="n">part</span><span class="o">.</span><span class="n">nil?</span>
        <span class="n">message</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">decoded</span>
      <span class="k">end</span>
    <span class="k">else</span>
      <span class="n">message</span> <span class="o">=</span> <span class="n">part</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">decoded</span>
    <span class="k">end</span> 

    <span class="k">unless</span> <span class="n">message</span><span class="o">.</span><span class="n">nil?</span>
      <span class="no">Resque</span><span class="o">.</span><span class="n">enqueue</span><span class="p">(</span><span class="no">EmailReply</span><span class="p">,</span> <span class="n">from</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="n">message</span><span class="p">)</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span> 

<span class="no">EmailReply</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="vg">$stdin</span><span class="o">.</span><span class="n">read</span><span class="p">)</span>
</pre>
</div>
<p>This script receives the mail message then tries to extract the plaintext body. If the email message is valid it adds it to the queue for future processing.</p>
<h2>Mail Queue processing</h2>
<p>After we put emails into the queue we&#8217;ll need to create a worker.</p>
<p>If you need to extract a reply from the body, use (mail_extract)[https://github.com/sosedoff/mail_extract]:</p>
<pre><code>gem install mail_extract
</code></pre>
<p>Simple worker (resque job worker), extracted from one of the projects. (RAILS_ROOT/lib/email_reply.rb):</p>
<div class="highlight">
<pre><span class="k">class</span> <span class="nc">InvalidReplyUUID</span>    <span class="o">&lt;</span> <span class="no">StandardError</span> <span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">InvalidReplyUser</span>    <span class="o">&lt;</span> <span class="no">StandardError</span> <span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">InvalidReplyProject</span> <span class="o">&lt;</span> <span class="no">StandardError</span> <span class="p">;</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">InvalidReplyMessage</span> <span class="o">&lt;</span> <span class="no">StandardError</span> <span class="p">;</span> <span class="k">end</span> 

<span class="k">class</span> <span class="nc">EmailReply</span>
  <span class="vi">@queue</span> <span class="o">=</span> <span class="ss">:email_replies</span> 

  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">parse_email_uuid</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">str</span> <span class="o">=~</span> <span class="sr">/^P[0-9abcdef]+(M[\d]+)?@/i</span>
      <span class="n">parts</span> <span class="o">=</span> <span class="n">str</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="sr">/^P([0-9abcdef]+)(M([\d]+))?/</span><span class="p">)</span><span class="o">.</span><span class="n">flatten</span>
      <span class="n">project_uuid</span> <span class="o">=</span> <span class="n">parts</span><span class="o">.</span><span class="n">first</span>
      <span class="n">message_id</span> <span class="o">=</span> <span class="n">parts</span><span class="o">.</span><span class="n">size</span> <span class="o">==</span> <span class="mi">3</span> <span class="o">?</span> <span class="n">parts</span><span class="o">.</span><span class="n">last</span> <span class="p">:</span> <span class="kp">nil</span> 

      <span class="n">result</span> <span class="o">=</span> <span class="p">{</span><span class="ss">:project_uuid</span> <span class="o">=&gt;</span> <span class="n">project_uuid</span><span class="p">}</span>
      <span class="n">result</span><span class="o">[</span><span class="ss">:message_id</span><span class="o">]</span> <span class="o">=</span> <span class="n">message_id</span> <span class="k">unless</span> <span class="n">message_id</span><span class="o">.</span><span class="n">nil?</span>
      <span class="n">result</span>
    <span class="k">else</span>
      <span class="k">raise</span> <span class="no">InvalidReplyUUID</span><span class="p">,</span> <span class="s2">&quot;Invalid UUID: </span><span class="si">#{</span><span class="n">str</span><span class="si">}</span><span class="s2">&quot;</span>
    <span class="k">end</span>
  <span class="k">end</span> 

  <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">perform</span><span class="p">(</span><span class="n">from</span><span class="p">,</span> <span class="n">to</span><span class="p">,</span> <span class="n">body</span><span class="p">)</span>
    <span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">find_by_email</span><span class="p">(</span><span class="n">from</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">user</span><span class="o">.</span><span class="n">nil?</span>
      <span class="k">raise</span> <span class="no">InvalidReplyUser</span><span class="p">,</span> <span class="s2">&quot;User with email = </span><span class="si">#{</span><span class="n">from</span><span class="si">}</span><span class="s2"> is not a member of the app.&quot;</span>
    <span class="k">end</span> 

    <span class="n">info</span> <span class="o">=</span> <span class="n">parse_email_uuid</span><span class="p">(</span><span class="n">to</span><span class="p">)</span> 

    <span class="n">project</span> <span class="o">=</span> <span class="no">Project</span><span class="o">.</span><span class="n">find_by_uuid</span><span class="p">(</span><span class="n">info</span><span class="o">[</span><span class="ss">:project_uuid</span><span class="o">]</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">project</span><span class="o">.</span><span class="n">nil?</span>
      <span class="k">raise</span> <span class="no">InvalidReplyProject</span><span class="p">,</span> <span class="s2">&quot;Project with UUID = </span><span class="si">#{</span><span class="n">info</span><span class="o">[</span><span class="ss">:project_uuid</span><span class="o">]</span><span class="si">}</span><span class="s2"> was not found.&quot;</span>
    <span class="k">end</span> 

    <span class="k">if</span> <span class="n">info</span><span class="o">.</span><span class="n">key?</span><span class="p">(</span><span class="ss">:message_id</span><span class="p">)</span>
      <span class="n">message</span> <span class="o">=</span> <span class="n">project</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">find_by_id</span><span class="p">(</span><span class="n">info</span><span class="o">[</span><span class="ss">:message_id</span><span class="o">]</span><span class="p">)</span>
      <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">nil?</span>
        <span class="k">raise</span> <span class="no">InvalidReplyMessage</span><span class="p">,</span> <span class="s2">&quot;Message with ID = </span><span class="si">#{</span><span class="n">info</span><span class="o">[</span><span class="ss">:message_id</span><span class="o">]</span><span class="si">}</span><span class="s2"> was not found on project &#39;</span><span class="si">#{</span><span class="n">project</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">&#39;&quot;</span>
      <span class="k">end</span>
    <span class="k">end</span> 

    <span class="n">params</span> <span class="o">=</span> <span class="p">{</span>
      <span class="ss">:project</span>  <span class="o">=&gt;</span> <span class="n">project</span><span class="p">,</span>
      <span class="ss">:body</span>     <span class="o">=&gt;</span> <span class="no">MailExtract</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">body</span><span class="p">)</span><span class="o">.</span><span class="n">body</span><span class="p">,</span>
      <span class="ss">:markup</span>   <span class="o">=&gt;</span> <span class="s1">&#39;plain&#39;</span><span class="p">,</span>
      <span class="ss">:sent_via</span> <span class="o">=&gt;</span> <span class="s1">&#39;email&#39;</span>
    <span class="p">}</span>
    <span class="n">params</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">=</span> <span class="n">message</span> <span class="k">unless</span> <span class="n">message</span><span class="o">.</span><span class="n">nil?</span> 

    <span class="n">message</span> <span class="o">=</span> <span class="n">user</span><span class="o">.</span><span class="n">messages</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">params</span><span class="p">)</span>
    <span class="k">unless</span> <span class="n">message</span><span class="o">.</span><span class="n">save</span>
      <span class="k">raise</span> <span class="no">RuntimeError</span><span class="p">,</span> <span class="s2">&quot;Unable to save message. Errors: </span><span class="si">#{</span><span class="n">message</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">inspect</span><span class="si">}</span><span class="s2">&quot;</span>
    <span class="k">end</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<p><strong>NOTE:</strong> <em>Its important that both mail receiver and worker are using the same queue.</em></p>
<p>Create a resque.rake in RAILS_ROOT/lib/tasks:</p>
<div class="highlight">
<pre><span class="nb">require</span> <span class="s1">&#39;resque/tasks&#39;</span>
<span class="n">task</span> <span class="s2">&quot;resque:setup&quot;</span> <span class="o">=&gt;</span> <span class="ss">:environment</span>
</pre>
</div>
<p>And fire it up:</p>
<pre><code>rake resque:work QUEUE=email_replies
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/08/10/processing-emails-with-postfix-and-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Foreman + Capistrano for Rails 3 applications</title>
		<link>http://blog.sosedoff.com/2011/07/24/foreman-capistrano-for-rails-3-applications/</link>
		<comments>http://blog.sosedoff.com/2011/07/24/foreman-capistrano-for-rails-3-applications/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 03:27:41 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[foreman]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=387</guid>
		<description><![CDATA[Foreman is a Procfile based process spawner.
Source: https://github.com/ddollar/foreman
Installation
gem install foreman

Configuration
Lets assume you have a resque worker, which you execute with rake:
bundle exec rake resque:work QUEUE=* RAILS_ENV=production

Now, you will need to create a Procfile inside your rails root folder (Procfile):
worker: bundle exec rake resque:work QUEUE=* RAILS_ENV=production

Start your workers with foreman:
foreman start


Foreman will start all of the [...]]]></description>
			<content:encoded><![CDATA[<p>Foreman is a Procfile based process spawner.</p>
<p>Source: <a href="https://github.com/ddollar/foreman">https://github.com/ddollar/foreman</a></p>
<h2>Installation</h2>
<pre><code>gem install foreman
</code></pre>
<h2>Configuration</h2>
<p>Lets assume you have a resque worker, which you execute with rake:</p>
<pre><code>bundle exec rake resque:work QUEUE=* RAILS_ENV=production
</code></pre>
<p>Now, you will need to create a Procfile inside your rails root folder (Procfile):</p>
<pre><code>worker: bundle exec rake resque:work QUEUE=* RAILS_ENV=production
</code></pre>
<p>Start your workers with foreman:</p>
<pre><code>foreman start

</code></pre>
<p>Foreman will start all of the processes associated with your app and display stdout and stderr of each process. Processes are color-coded by type to make them easy to read. $PORT will be automatically assigned by foreman and made available to each underlying process.</p>
<h2>Export to system</h2>
<p>While foreman is great for running your application in development, there are some great existing tools for managing processes in production. Foreman can export to either upstart or standard unix init.</p>
<p>Exporting to upstart:</p>
<div class="highlight">
<pre><span class="nv">$ </span>foreman <span class="nb">export </span>upstart /etc/init

<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp.conf
<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-web.conf
<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-web-1.conf

<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-worker.conf
<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-worker-1.conf
<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-clock.conf

<span class="o">[</span>foreman <span class="nb">export</span><span class="o">]</span> writing: /etc/init/testapp-clock-1.conf
</pre>
</div>
<h2>Capistrano integration</h2>
<p>Assuming you got your capistrano recipe working, here is a set of foreman tasks:</p>
<div class="highlight">
<pre><span class="c1"># Foreman tasks</span>

<span class="n">namespace</span> <span class="ss">:foreman</span> <span class="k">do</span>
  <span class="n">desc</span> <span class="s1">&#39;Export the Procfile to Ubuntu upstart scripts&#39;</span>
  <span class="n">task</span> <span class="ss">:export</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="ss">:app</span> <span class="k">do</span>

    <span class="n">run</span> <span class="s2">&quot;cd </span><span class="si">#{</span><span class="n">release_path</span><span class="si">}</span><span class="s2"> &amp;&amp; sudo bundle exec foreman export upstart /etc/init -a </span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2"> -u </span><span class="si">#{</span><span class="n">user</span><span class="si">}</span><span class="s2"> -l </span><span class="si">#{</span><span class="n">release_path</span><span class="si">}</span><span class="s2">/log/foreman&quot;</span>

  <span class="k">end</span>

  <span class="n">desc</span> <span class="s2">&quot;Start the application services&quot;</span>
  <span class="n">task</span> <span class="ss">:start</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="ss">:app</span> <span class="k">do</span>

    <span class="n">sudo</span> <span class="s2">&quot;start </span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2">&quot;</span>
  <span class="k">end</span>

  <span class="n">desc</span> <span class="s2">&quot;Stop the application services&quot;</span>

  <span class="n">task</span> <span class="ss">:stop</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="ss">:app</span> <span class="k">do</span>
    <span class="n">sudo</span> <span class="s2">&quot;stop </span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2">&quot;</span>

  <span class="k">end</span>

  <span class="n">desc</span> <span class="s2">&quot;Restart the application services&quot;</span>
  <span class="n">task</span> <span class="ss">:restart</span><span class="p">,</span> <span class="ss">:roles</span> <span class="o">=&gt;</span> <span class="ss">:app</span> <span class="k">do</span>

    <span class="n">run</span> <span class="s2">&quot;sudo start </span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2"> || sudo restart </span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2">&quot;</span>
  <span class="k">end</span>
<span class="k">end</span>
</pre>
</div>
<p>Just add deploy hooks and its ready to go:</p>
<div class="highlight">
<pre><span class="n">after</span> <span class="s2">&quot;deploy:update&quot;</span><span class="p">,</span> <span class="s2">&quot;foreman:export&quot;</span>    <span class="c1"># Export foreman scripts</span>
<span class="n">after</span> <span class="s2">&quot;deploy:update&quot;</span><span class="p">,</span> <span class="s2">&quot;foreman:restart&quot;</span>   <span class="c1"># Restart application scripts</span>
</pre>
</div>
<h2>Documentation</h2>
<ul>
<li>Github repo &#8211; <a href="https://github.com/ddollar/foreman">https://github.com/ddollar/foreman</a></li>
<li>Blog post &#8211; <a href="http://blog.daviddollar.org/2011/05/06/introducing-foreman.html">http://blog.daviddollar.org/2011/05/06/introducing-foreman.html</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/07/24/foreman-capistrano-for-rails-3-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serving maintenance page with Rack Middleware</title>
		<link>http://blog.sosedoff.com/2011/04/09/serving-maintenance-page-with-rack-middleware/</link>
		<comments>http://blog.sosedoff.com/2011/04/09/serving-maintenance-page-with-rack-middleware/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 02:14:17 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[rack]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=377</guid>
		<description><![CDATA[Its not that important to show message while doing a regular app update, which takes seconds to complete, but when you need to perform some maintenance tasks (tuning, configuration, installation) its better to give users information when its going to be finished. All big websites have their own fancy maintenance page, but for small projects [...]]]></description>
			<content:encoded><![CDATA[<p>Its not that important to show message while doing a regular app update, which takes seconds to complete, but when you need to perform some maintenance tasks (tuning, configuration, installation) its better to give users information when its going to be finished. All big websites have their own fancy maintenance page, but for small projects it does not matter. </p>
<p>Here is a Rack::Maintenance module that provides such functionality:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Rack
  <span style="color:#9966CC; font-weight:bold;">class</span> Maintenance
    <span style="color:#CC00FF; font-weight:bold;">File</span> = ::<span style="color:#CC00FF; font-weight:bold;">File</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>app, dir=<span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>block<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@app</span> = app
      <span style="color:#0066ff; font-weight:bold;">@block</span> = block
      <span style="color:#0066ff; font-weight:bold;">@dir</span> = dir <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">pwd</span>
      <span style="color:#0066ff; font-weight:bold;">@file</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>@dir<span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#996600;">'.maintenance'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> call<span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>@file<span style="color:#006600; font-weight:bold;">&#41;</span>
        body = <span style="color:#0066ff; font-weight:bold;">@block</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? ? default_prompt<span style="color:#006600; font-weight:bold;">&#40;</span>time_info<span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#0066ff; font-weight:bold;">@block</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>time_info<span style="color:#006600; font-weight:bold;">&#41;</span>
        res = Response.<span style="color:#9900CC;">new</span>
        res.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>body<span style="color:#006600; font-weight:bold;">&#41;</span>
        res.<span style="color:#9900CC;">finish</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#0066ff; font-weight:bold;">@app</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    private
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> time_info
      t_since, t_until = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">nil</span>, <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@file<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
        t_since = f.<span style="color:#9900CC;">mtime</span>
        t_until = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>f.<span style="color:#CC0066; font-weight:bold;">gets</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#0000FF; font-weight:bold;">nil</span>
        t_until = <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> t_until.<span style="color:#9900CC;">kind_of</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> t_until <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>:since <span style="color:#006600; font-weight:bold;">=&gt;</span> t_since, <span style="color:#ff3333; font-weight:bold;">:until</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> t_until<span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> default_prompt<span style="color:#006600; font-weight:bold;">&#40;</span>t<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> t<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:until</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#008000; font-style:italic;"># no idea when do we end</span>
        msg = <span style="color:#996600;">&quot;We're doing stuff on our servers and will be back shortly.&lt;br/&gt;&lt;br/&gt;&quot;</span>
        msg <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;&lt;small&gt;started: #{t[:since]}&lt;/small&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        msg = <span style="color:#996600;">&quot;We'll be back online on &lt;b&gt;#{t[:until]}&lt;/b&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#996600;">&quot;&lt;center&gt;&lt;br/&gt;&lt;br/&gt;&lt;h1&gt;Maintenance.&lt;/h1&gt;&lt;p&gt;#{msg}&lt;/p&gt;&lt;/center&gt;&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Usage</h3>
<p>By default middleware will look into current working directory for file with filename &#8220;.maintenance&#8221;.<br />
Request will be passed next if no file found.</p>
<p>Simpliest example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">use <span style="color:#6666ff; font-weight:bold;">Rack::Maintenance</span></pre></div></div>

<p>Set custom directory:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">use <span style="color:#6666ff; font-weight:bold;">Rack::Maintenance</span>, <span style="color:#996600;">'/path/to/dir'</span></pre></div></div>

<p>Customize default maintenance prompt:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">use <span style="color:#6666ff; font-weight:bold;">Rack::Maintenance</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#996600;">&quot;We're doing some stuff. Come back later.&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If you want to use timestamps in your prompt just put a valid time string<br />
into your .maintenance file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'.maintenance'</span>, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">3600</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>and then use it in your prompt:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">use <span style="color:#6666ff; font-weight:bold;">Rack::Maintenance</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#996600;">&quot;We're doing some stuff since #{t[:since} will be done at #{t[:until]}.&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Results</h3>
<p><img src="http://blog.sosedoff.com/wp-content/uploads/2011/04/Screen-shot-2011-04-09-at-8.57.40-PM.png" alt="Screen shot 2011-04-09 at 8.57.40 PM" title="Screen shot 2011-04-09 at 8.57.40 PM" width="471" height="188" class="alignnone size-full wp-image-380" /><br />
<br/><br />
<img src="http://blog.sosedoff.com/wp-content/uploads/2011/04/Screen-shot-2011-04-09-at-9.09.46-PM.png" alt="Screen shot 2011-04-09 at 9.09.46 PM" title="Screen shot 2011-04-09 at 9.09.46 PM" width="423" height="118" class="alignnone size-full wp-image-381" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/04/09/serving-maintenance-page-with-rack-middleware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restrict access to all mobile and bot clients with Rack Middleware</title>
		<link>http://blog.sosedoff.com/2011/04/09/restrict-access-to-all-mobile-and-bot-clients-with-rack-middleware/</link>
		<comments>http://blog.sosedoff.com/2011/04/09/restrict-access-to-all-mobile-and-bot-clients-with-rack-middleware/#comments</comments>
		<pubDate>Sun, 10 Apr 2011 01:54:37 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[middleware]]></category>
		<category><![CDATA[rack]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=371</guid>
		<description><![CDATA[Rack middleware is a convenient way to process request before it gets to the application level. Of course, a lot of tasks might be performed within the app, but its not even necessary to do so. Since every ruby web framework is based on rack it makes sense to handle it with middleware. 
Here is [...]]]></description>
			<content:encoded><![CDATA[<p>Rack middleware is a convenient way to process request before it gets to the application level. Of course, a lot of tasks might be performed within the app, but its not even necessary to do so. Since every ruby web framework is based on rack it makes sense to handle it with middleware. </p>
<p>Here is a small module to bounce off all non-desktop clients (mobile devices, crawlers):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Rack
  <span style="color:#9966CC; font-weight:bold;">class</span> Restrict
    REGEX_MOBILE = <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>blackberry<span style="color:#006600; font-weight:bold;">|</span>motorokr<span style="color:#006600; font-weight:bold;">|</span>motorola<span style="color:#006600; font-weight:bold;">|</span>sony<span style="color:#006600; font-weight:bold;">|</span>windows ce<span style="color:#006600; font-weight:bold;">|</span>240x320<span style="color:#006600; font-weight:bold;">|</span>176x220<span style="color:#006600; font-weight:bold;">|</span>palm<span style="color:#006600; font-weight:bold;">|</span>mobile<span style="color:#006600; font-weight:bold;">|</span>iphone<span style="color:#006600; font-weight:bold;">|</span>ipod<span style="color:#006600; font-weight:bold;">|</span>symbian<span style="color:#006600; font-weight:bold;">|</span>nokia<span style="color:#006600; font-weight:bold;">|</span>samsung<span style="color:#006600; font-weight:bold;">|</span>midp<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>i
    REGEX_BOTS = <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>google<span style="color:#006600; font-weight:bold;">|</span>yahoo<span style="color:#006600; font-weight:bold;">|</span>baidu<span style="color:#006600; font-weight:bold;">|</span>bot<span style="color:#006600; font-weight:bold;">|</span>webalta<span style="color:#006600; font-weight:bold;">|</span>ia_archiver<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>app<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@app</span> = app
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> call<span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      str = env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'HTTP_USER_AGENT'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      restrict = !str.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span>REGEX_MOBILE<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#006600; font-weight:bold;">||</span> !str.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span>REGEX_BOTS<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      restrict ? forbidden! : <span style="color:#0066ff; font-weight:bold;">@app</span>.<span style="color:#9900CC;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> forbidden!
      <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">403</span>, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">'Content-Type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'text/html'</span>, <span style="color:#996600;">'Content-Length'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'0'</span> <span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Usage: (sample config.ru):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rack'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rack/contrib'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'app.rb'</span>
&nbsp;
use <span style="color:#6666ff; font-weight:bold;">Rack::Restrict</span>
run <span style="color:#6666ff; font-weight:bold;">Sinatra::Application</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/04/09/restrict-access-to-all-mobile-and-bot-clients-with-rack-middleware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic settings for Ruby/Rails applications</title>
		<link>http://blog.sosedoff.com/2011/02/07/dynamic-settings-for-ruby-or-rails-applications/</link>
		<comments>http://blog.sosedoff.com/2011/02/07/dynamic-settings-for-ruby-or-rails-applications/#comments</comments>
		<pubDate>Tue, 08 Feb 2011 05:10:47 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Gems]]></category>
		<category><![CDATA[dynymic settings]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[utils]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=364</guid>
		<description><![CDATA[Few times i needed to build dynamic-settings support into the application, which means that users (admins) can redefine website parameters like html keywords, notification email adresses and other simple data, that cannot be put into application environment settings. So, i extracted a small helper that will give me such ability across multiple apps &#8211; AppConfig
AppConfig [...]]]></description>
			<content:encoded><![CDATA[<p>Few times i needed to build dynamic-settings support into the application, which means that users (admins) can redefine website parameters like html keywords, notification email adresses and other simple data, that cannot be put into application environment settings. So, i extracted a small helper that will give me such ability across multiple apps &#8211; <a href="https://github.com/sosedoff/app-config">AppConfig</a></p>
<p>AppConfig is a library to manage your (web) application dynamic settings with flexible access and configuration strategy. Primary datasource for AppConfig is an ActiveRecord model.</p>
<h3>Installation</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git clone git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>sosedoff<span style="color: #000000; font-weight: bold;">/</span>app-config.git
<span style="color: #7a0874; font-weight: bold;">cd</span> app-config
gem build
gem <span style="color: #c20cb9; font-weight: bold;">install</span> app-config-x.y.z.gem</pre></div></div>

<h3>Data Formats</h3>
<p>You can use following formats:</p>
<ul>
<li>String</li>
<li>Boolean</li>
<li>Array</li>
<li>Hash</li>
</ul>
<p>String format is a default format. Everything is a string by default.</p>
<p>Boolean format is just a flag, values ‘true’, ‘on’, ‘yes’, ‘y’, ‘1’ are equal to True. Everything else is False.</p>
<p>Array format is a multiline text which is transformed into array. Each evelemnt will be trimmed. Empty strings are ignored.</p>
<p>Hash format is special key-value string, &#8220;foo: bar, user: username&#8221;, which is transformed into Hash instance. Only format &#8220;keyname: value, keyname2: value2&#8243; is supported. No nested hashes allowed.</p>
<h3>Usage</h3>
<p>AppConfig is designed to work with ActiveRecord model. Only ActiveRecord >= 3.0.0 is supported.<br />
By default model &#8220;Setting&#8221; will be used as a data source.</p>
<p>Here is default structure:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">ActiveRecord::Schema</span>.<span style="color:#9900CC;">define</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  create_table <span style="color:#ff3333; font-weight:bold;">:settings</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:keyname</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:value</span>
    t.<span style="color:#CC0066; font-weight:bold;">string</span> <span style="color:#ff3333; font-weight:bold;">:value_format</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, configure:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">configure</span></pre></div></div>

<p>If your settings model has a different schema, you can redefine columns:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">configure</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:model</span>  <span style="color:#006600; font-weight:bold;">=&gt;</span> Setting,           <span style="color:#008000; font-style:italic;"># define your model as a source</span>
  <span style="color:#ff3333; font-weight:bold;">:key</span>    <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'KEYNAME_FIELD'</span>,   <span style="color:#008000; font-style:italic;"># field that contains name</span>
  <span style="color:#ff3333; font-weight:bold;">:format</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'FORMAT_FIELD'</span>,    <span style="color:#008000; font-style:italic;"># field that contains key format</span>
  <span style="color:#ff3333; font-weight:bold;">:value</span>  <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'VALUE_FIELD'</span>,     <span style="color:#008000; font-style:italic;">#field that contains value data</span>
<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Load all settings somewhere in your application. In Rails it should be initializer file.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#CC0066; font-weight:bold;">load</span></pre></div></div>

<p>AppConfig gives you 2 ways to access variables:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">my_setting</span>      <span style="color:#008000; font-style:italic;"># method-like</span>
AppConfig<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:my_setting</span><span style="color:#006600; font-weight:bold;">&#93;</span>    <span style="color:#008000; font-style:italic;"># hash-like by symbol key</span>
AppConfig<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'my_setting'</span><span style="color:#006600; font-weight:bold;">&#93;</span>   <span style="color:#008000; font-style:italic;"># hash-like by string key</span></pre></div></div>

<p>You can define settings items manually. NOTE: THESE KEYS WILL BE REMOVED ON RELOAD/LOAD.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">set</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'KEYNAME, '</span>VALUE<span style="color:#996600;">', '</span><span style="color:#CC0066; font-weight:bold;">FORMAT</span><span style="color:#996600;">')</span></pre></div></div>

<p>Everytime you change your settings on the fly, use reload:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">reload</span></pre></div></div>

<p>Cleanup everything:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">AppConfig.<span style="color:#9900CC;">flush</span></pre></div></div>

<p>Github source: <a href="https://github.com/sosedoff/app-config">https://github.com/sosedoff/app-config</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/02/07/dynamic-settings-for-ruby-or-rails-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rendering custom tags with Liquid on Rails</title>
		<link>http://blog.sosedoff.com/2011/01/31/rendering-custom-tags-with-liquid-on-rails/</link>
		<comments>http://blog.sosedoff.com/2011/01/31/rendering-custom-tags-with-liquid-on-rails/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 02:30:42 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[liquid]]></category>
		<category><![CDATA[snippets]]></category>
		<category><![CDATA[template engine]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=353</guid>
		<description><![CDATA[Liquid is a flexible and safe template engine that allows you to write code inside the actual template. It was extracted from Shopify and is pretty awesome if you need your templates be editable by non-programmers. This is a most important part, as such users might break the whole application. In this case Liquid is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.liquidmarkup.org/">Liquid</a> is a flexible and safe template engine that allows you to write code inside the actual template. It was extracted from Shopify and is pretty awesome if you need your templates be editable by non-programmers. This is a most important part, as such users might break the whole application. In this case Liquid is perfect. Also, its kind of similar to <a href="http://alexeyrybak.com/blitz/blitz_en.html">Blitz template engine</a>, which i was using on PHP. </p>
<p>The documentation is not the perfect, but enough to understand the concepts, so i&#8217;ll just jump straight to the matter.</p>
<h3>Subject</h3>
<p>Lets assume that all our templates are stored in database and we dont store anything in filesystem. And we need to use small parts as snippets to embed into actual template.</p>
<h3>Implementation</h3>
<p>The model where we store all snippets with be named Snippet. Fields:</p>
<ul>
<li>ID &#8211; Primary key</li>
<li>Name &#8211; Actual name of the snippet used in tempates</li>
<li>Body &#8211; Content of the snippet</li>
<li>Created/Updated timestamps &#8211; DateTime stamps for internal use</li>
</ul>
<p>And the active record model:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Snippet <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  NAME_FORMAT = <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#006600; font-weight:bold;">&#91;</span>a<span style="color:#006600; font-weight:bold;">-</span>z\d\_\<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">2</span>,<span style="color:#006666;">64</span><span style="color:#006600; font-weight:bold;">&#125;</span>$<span style="color:#006600; font-weight:bold;">/</span>i    <span style="color:#008000; font-style:italic;"># Define your own name format</span>
&nbsp;
  validates_presence_of   <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:body</span>
  validates_length_of     <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:within</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> 2..64
  validates_format_of     <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:with</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> NAME_FORMAT
  validates_uniqueness_of <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:case_sensitive</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, lets define the custom liquid tag &#8220;snippet&#8221;:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> SnippetTag <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Liquid::Tag</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>tag_name, snippet_name, tokens<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span> = snippet_name
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> render<span style="color:#006600; font-weight:bold;">&#40;</span>context<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># You might want to define caching mechanism here</span>
    snippet = Snippet.<span style="color:#9900CC;">find_by_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>@name<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">unless</span> snippet.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      <span style="color:#6666ff; font-weight:bold;">Liquid::Template</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>snippet.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">render</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#996600;">&quot;Error: Snippet #{@name} was not found!&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, register the tag:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#6666ff; font-weight:bold;">Liquid::Template</span>.<span style="color:#9900CC;">register_tag</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'snippet'</span>, SnippetTag<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>And use it within your template:</p>
<pre>
This is a custom tag that renders a widget: {% snippet sample_snippet %}
</pre>
<p>If the requested snippet was not found or does not exists renderer will replace the tag with error message, which might be adjusted for your personal needs or hidden. Also, you can use nested snippets, but in this case you have to think about right snippet template caching approach. </p>
<h3>Using Liquid drops</h3>
<p>A drop in liquid is a class which allows you to use predefined data collection methods in the template. If you would like to make data available to the web designers which you don’t want loaded unless needed then a drop is a great way to do that.</p>
<p>Lets make a drop for a basic dataset for Post model (blog posts for example):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> PostsDrop <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Liquid::Drop</span>
  <span style="color:#008000; font-style:italic;"># fetch all posts</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> all
    Post.<span style="color:#9900CC;">all</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># fetch N most popular posts</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> popular<span style="color:#006600; font-weight:bold;">&#40;</span>num=<span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Post.<span style="color:#9900CC;">all</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'pageviews DESC'</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> num<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Define a template for this collection:</p>
<pre>
Popular posts:<br/>
{% for post in posts.popular %}
Post: {{ post.title }}
{% endfor %}
</pre>
<p>Load a drop into the template:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">template = <span style="color:#6666ff; font-weight:bold;">Liquid::Template</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>YOUR_TEMPLATE<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">render</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'posts'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> PostsDrop.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>With such scheme you can hook up custom snippet that renders a list of objects from your drop.<br />
Pretty cool.  Works on Rails 3.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/01/31/rendering-custom-tags-with-liquid-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Discover hidden API services with Proxie</title>
		<link>http://blog.sosedoff.com/2011/01/25/discover-hidden-api-services-with-proxie/</link>
		<comments>http://blog.sosedoff.com/2011/01/25/discover-hidden-api-services-with-proxie/#comments</comments>
		<pubDate>Tue, 25 Jan 2011 12:05:54 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[API's]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Gems]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[http-proxy]]></category>
		<category><![CDATA[sinatra]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=343</guid>
		<description><![CDATA[Need to figure out closed/private API? Not a problem. Its always fun and challenging. There are few tools i use for that:

Firefox LiveHTTP Headers extension
Charles Web Debugging Proxy Application
Proxie

Proxie is another project of mine, which i finally extracted from a script written a while ago and published it as a ruby gem.
I used it to [...]]]></description>
			<content:encoded><![CDATA[<p>Need to figure out closed/private API? Not a problem. Its always fun and challenging. There are few tools i use for that:</p>
<ul>
<li><a href="https://addons.mozilla.org/en-us/firefox/addon/live-http-headers/">Firefox LiveHTTP Headers extension</a></li>
<li><a href="http://www.charlesproxy.com/">Charles Web Debugging Proxy Application</a></li>
<li><a href="https://github.com/sosedoff/proxie">Proxie</a></li>
</ul>
<p>Proxie is another project of mine, which i finally extracted from a script written a while ago and published it as a ruby gem.<br />
I used it to track Grooveshark API and it worked out great. Here is the list of features:</p>
<ul>
<li>Bind proxy server to any port (default is 8080)
<li>Define output database. It uses SQLite3 by default, but you can extend it with any other types</li>
<li>Sinatra-base web interface to browse all your collected data</li>
</ul>
<p>Installation:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> proxie</pre></div></div>

<p>Start a server:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">proxie <span style="color: #660033;">-d</span> DATABASE_NAME</pre></div></div>

<p>After data collection just run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">proxie <span style="color: #660033;">--web</span></pre></div></div>

<p>The web interface runs on localhost:4567 by default.</p>
<p>Usage summary:</p>
<pre>
Usage: proxie [options]
    -i, --info                       Display this information.
    -p, --port PORT                  Listen on port (8080 default)
    -d, --db NAME                    Store results to database
    -w, --web                        Start a Web UI for databases
    -f, --flush                      Delete all local databases
</pre>
<p>Project on GitHub: <a href="http://github.com/sosedoff/proxie">http://github.com/sosedoff/proxie</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2011/01/25/discover-hidden-api-services-with-proxie/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

