<?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; Web Development</title>
	<atom:link href="http://blog.sosedoff.com/category/web-development/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>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>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>Why rapid development is the best way to make web apps</title>
		<link>http://blog.sosedoff.com/2010/09/17/why-rapid-development-is-the-best-way-to-make-web-apps/</link>
		<comments>http://blog.sosedoff.com/2010/09/17/why-rapid-development-is-the-best-way-to-make-web-apps/#comments</comments>
		<pubDate>Sat, 18 Sep 2010 02:27:30 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[rapid]]></category>
		<category><![CDATA[sinatra]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=275</guid>
		<description><![CDATA[What do you know about rapid development? 
I guess something. Almost every developer experienced moments when you or someone have really interesting idea and wanted to jump on it right away. One of the obstacles &#8211; tools you use to achieve it. And the web framework is the first of them. Why? Because if you [...]]]></description>
			<content:encoded><![CDATA[<p>What do you know about rapid development? </p>
<p>I guess something. Almost every developer experienced moments when you or someone have really interesting idea and wanted to jump on it right away. One of the obstacles &#8211; tools you use to achieve it. And the web framework is the first of them. Why? Because if you want to create something cool without being stuck on technology level you should use things that you dont really notice while making your app. Of course it varies from person-to-person, but just imagine yourself in traffic jam driving stick-shift car, switching gears like crazy all the time. </p>
<p>Back to webdev, with my experience i can only say that the best tool for rapid development is <a href="http://www.sinatrarb.com/">Sinatra</a>.  Its so small and powerful that i got hooked on it since first day i found it. Almost all my personal/work projects on early stages have been developed with Sinatra. Another big plus &#8211; small and usefull extensions, big players like <a href="http://ar.rubyonrails.org/">AR</a> or <a href="http://datamapper.org">DataMapper</a>. It was extracted from Merb project, another small and powerful web framework i like to work with. Its like a one-file web application. Perfect for super-fast development. Wanna do simple music downloads page? No problem. API &#8211; again, no problem. Deployment is simple and similar to most of frameworks, as it built on top of <a href="http://rack.rubyforge.org/">Rack</a>: thin, passenger (nginx/apache).</p>
<p>What do you know about rapid development?<br />
<strong>I say &#8211; i love it.</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/09/17/why-rapid-development-is-the-best-way-to-make-web-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Disable auto-incremental field in Rails Migrations</title>
		<link>http://blog.sosedoff.com/2010/08/12/disable-auto-incremental-field-in-rails-migrations/</link>
		<comments>http://blog.sosedoff.com/2010/08/12/disable-auto-incremental-field-in-rails-migrations/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 03:16:05 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[migrations]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=262</guid>
		<description><![CDATA[Since i`ve been using both DataMapper (Merb/Sinatra) and ActiveRecord (Rails) a lot i noticed that AR acts weight when i manually set PK key, particularly ID field, which you dont have to define by default. In DM you have to define it as &#8216;Serial&#8217;. 
So, the task is to create/update records in your database which [...]]]></description>
			<content:encoded><![CDATA[<p>Since i`ve been using both DataMapper (Merb/Sinatra) and ActiveRecord (Rails) a lot i noticed that AR acts weight when i manually set PK key, particularly ID field, which you dont have to define by default. In DM you have to define it as &#8216;Serial&#8217;. </p>
<p>So, the task is to create/update records in your database which is supposes to represent data from primary database. In such cases all ID`s should be unique and equal to each other. </p>
<p>To disable autoincremental ID field in your AR models just use this option:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">create_table <span style="color:#ff3333; font-weight:bold;">:foo</span>, <span style="color:#ff3333; font-weight:bold;">:id</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;">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;">integer</span>   <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:options</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'PRIMARY KEY'</span>
  <span style="color:#008000; font-style:italic;"># .... rest of columns</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/08/12/disable-auto-incremental-field-in-rails-migrations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Debugging PHP applications in terminal</title>
		<link>http://blog.sosedoff.com/2010/07/03/debugging-php-applications-in-terminal/</link>
		<comments>http://blog.sosedoff.com/2010/07/03/debugging-php-applications-in-terminal/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 05:45:39 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[console]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[eventmachine]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=251</guid>
		<description><![CDATA[Most of Ruby web frameworks have terminal logging in development environments. It makes application debugging process much easier than using file logging. Especially for AJAX requests. Of course there is simple solution &#8211; use Firebug and javascript console. Unfortunately it is not that convenient. 
So, one day i came up with idea to make the [...]]]></description>
			<content:encoded><![CDATA[<p>Most of Ruby web frameworks have terminal logging in development environments. It makes application debugging process much easier than using file logging. Especially for AJAX requests. Of course there is simple solution &#8211; use Firebug and javascript console. Unfortunately it is not that convenient. </p>
<p>So, one day i came up with idea to make the same ruby-like style of application logging, even with colorized output.<br />
I decided to use <a href="http://eventmachine.rubyforge.org/">EventMachine</a> library as a server platform. And API is based on JSON packets, via <a href="http://flori.github.com/json/">json/pure</a>. Simple, isnt it?</p>
<p>And i called it DebugServer. Pretty understandable <img src='http://blog.sosedoff.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>Installation</h3>
<p>To install just type</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> debugserver</pre></div></div>

<p>And for information type:</p>

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

<pre>
Usage: debugserver [options]
    -h, --host HOSTNAME              Server hostname
    -p, --port PORT                  Server port
    -i, --info                       Get usage information
</pre>
<p>By default it will start on localhost:9000. </p>
<h3>Usage in PHP</h3>
<p>First, download library from GitHub repository: <a href="http://github.com/sosedoff/debugclient-php">http://github.com/sosedoff/debugclient-php</a></p>
<p>And then:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// place it into app initialization file</span>
<span style="color: #000088;">$debug</span> <span style="color: #339933;">=</span> DebugClient<span style="color: #339933;">::</span><span style="color: #004000;">instance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$debug</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// .... and write it to terminal output</span>
<span style="color: #000088;">$obj</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #208080;">0xFFFF</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Sample name'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'time'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #990000;">strftime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'%m-%d-%Y'</span><span style="color: #339933;">,</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// these functions are globally defined</span>
debug_clear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// clear terminal</span>
debug<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is a plain text message.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
debug_info<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is an informational message.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
debug_warning<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is a warning message.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
debug_error<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'This is an error message.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
debug_dump<span style="color: #009900;">&#40;</span><span style="color: #000088;">$obj</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// optional</span>
<span style="color: #000088;">$debug</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Results:<br />
<img src="http://blog.sosedoff.com/wp-content/uploads/2010/07/debugserver.png" alt="Output" /></p>
<h3>Sources</h3>
<p>DebugServer: <a href="http://github.com/sosedoff/debugserver">http://github.com/sosedoff/debugserver</a><br />
PHP Client: <a href="http://github.com/sosedoff/debugclient-php">http://github.com/sosedoff/debugclient-php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/07/03/debugging-php-applications-in-terminal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generate sitemaps with Ruby and XmlSitemap gem</title>
		<link>http://blog.sosedoff.com/2010/06/18/generate-sitemaps-with-ruby-and-xmlsitemap-gem/</link>
		<comments>http://blog.sosedoff.com/2010/06/18/generate-sitemaps-with-ruby-and-xmlsitemap-gem/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 23:10:38 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[gems]]></category>
		<category><![CDATA[generation]]></category>
		<category><![CDATA[merb]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[sinatra]]></category>
		<category><![CDATA[sitemap]]></category>
		<category><![CDATA[xml]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=244</guid>
		<description><![CDATA[Made a simple gem for website sitemap generation. Could be used in any Ruby/Rails/Merb/Sinatra application. It does not have any caching in that case if you want to use framework built-in cache methods. 
Installation:

$ sudo gem install xml-sitemap

Example

pages = Page.all&#40;:order =&#62; &#91;:updated_at.desc&#93; # DM model
map = XmlSitemap::Map.new&#40;'somedomain.com'&#41; do &#124;m&#124;
  m.add&#40;:url =&#62; '/', :period =&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>Made a simple gem for website sitemap generation. Could be used in any Ruby/Rails/Merb/Sinatra application. It does not have any caching in that case if you want to use framework built-in cache methods. </p>
<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> xml-sitemap</pre></div></div>

<h3>Example</h3>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">pages = Page.<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:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:updated_at</span>.<span style="color:#9900CC;">desc</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#008000; font-style:italic;"># DM model</span>
map = <span style="color:#6666ff; font-weight:bold;">XmlSitemap::Map</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'somedomain.com'</span><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>m<span style="color:#006600; font-weight:bold;">|</span>
  m.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/'</span>, <span style="color:#ff3333; font-weight:bold;">:period</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:daily</span>, <span style="color:#ff3333; font-weight:bold;">:priority</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1.0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  m.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/contractors'</span>, <span style="color:#ff3333; font-weight:bold;">:period</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:daily</span>, <span style="color:#ff3333; font-weight:bold;">:priority</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1.0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  pages.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>p<span style="color:#006600; font-weight:bold;">|</span>
    m.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span>
      <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> url_for_page<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">p</span><span style="color:#006600; font-weight:bold;">&#41;</span>,
      <span style="color:#ff3333; font-weight:bold;">:updated</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">updated_at</span>,
      <span style="color:#ff3333; font-weight:bold;">:priority</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0.5</span>,
      <span style="color:#ff3333; font-weight:bold;">:period</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:never</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:#008000; font-style:italic;"># render the sitemap</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> map.<span style="color:#9900CC;">render</span></pre></div></div>

<h3>Sinatra Example</h3>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># ... your code</span>
&nbsp;
get <span style="color:#996600;">'/sitemap.xml'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  map = <span style="color:#6666ff; font-weight:bold;">XmlSitemap::Map</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'domain.com'</span><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>m<span style="color:#006600; font-weight:bold;">|</span>
    m.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    m.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/posts'</span>, <span style="color:#ff3333; font-weight:bold;">:period</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:weekly</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  headers<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Content-Type'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'text/xml'</span>
  map.<span style="color:#9900CC;">render</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># ... more code</span></pre></div></div>

<h3>Options</h3>
<p>:url &#8211; page path, relative to domain (ex.: /test), String.<br />
:period &#8211; freqchange attribute, Symbol, :none, :never, :always, :hourly, :daily, :weekly, :monthly, :yearly<br />
:priority &#8211; priority attribute, Float class,(0.0..1.0)<br />
:updated &#8211; (optional) last_update attribute, Time class</p>
<h3>Source Code</h3>
<p><a href="http://github.com/sosedoff/xml-sitemap">http://github.com/sosedoff/xml-sitemap</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/06/18/generate-sitemaps-with-ruby-and-xmlsitemap-gem/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making HTTP requests from different network interfaces with Ruby and Curb</title>
		<link>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/</link>
		<comments>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 04:31:17 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[curb]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[get]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[net]]></category>
		<category><![CDATA[requests]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=228</guid>
		<description><![CDATA[At some point you will find that you have reached requests per IP limit while using some API or crawling resources. And if you`re doing it via standard Net::HTTP you`ll face the problem that you cannot assign request class to specified network interface (or IP). Bummer? No. Even if you cant do it with core [...]]]></description>
			<content:encoded><![CDATA[<p>At some point you will find that you have reached requests per IP limit while using some API or crawling resources. And if you`re doing it via standard <a href="http://ruby-doc.org/core/classes/Net/HTTP.html">Net::HTTP</a> you`ll face the problem that you cannot assign request class to specified network interface (or IP). Bummer? No. Even if you cant do it with core class you might take a look on <a href="http://curb.rubyforge.org/">Curb</a> &#8211; libcurl ruby binding. It has everything that you need to make regular get/post/etc requests. And of course &#8211; easy.</p>
<p>A simple example (real ip`s are changed):</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;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'curb'</span>
&nbsp;
ip_addresses = <span style="color:#006600; font-weight:bold;">&#91;</span>
  <span style="color:#996600;">'1.1.1.1'</span>,
  <span style="color:#996600;">'2.2.2.2'</span>,
  <span style="color:#996600;">'3.3.3.3'</span>,
  <span style="color:#996600;">'4.4.4.4'</span>,
  <span style="color:#996600;">'5.5.5.5'</span>
<span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
ip_addresses.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>ip<span style="color:#006600; font-weight:bold;">|</span>
  req = <span style="color:#6666ff; font-weight:bold;">Curl::Easy</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'http://www.ip-adress.com/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  req.<span style="color:#9900CC;">interface</span> = ip
  req.<span style="color:#9900CC;">perform</span>
  result_ip = req.<span style="color:#9900CC;">body_str</span>.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/&lt;</span>h2<span style="color:#006600; font-weight:bold;">&gt;</span>My IP address is: <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>\d\.<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">1</span>,<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&lt;</span>\<span style="color:#006600; font-weight:bold;">/</span>h2<span style="color:#006600; font-weight:bold;">&gt;/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;for #{ip} got response: #{result_ip}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Output (ip`s are changed):</p>
<pre>
for 1.1.1.1 got response: 1.1.1.1
for 2.2.2.2 got response: 2.2.2.2
for 3.3.3.3 got response: 3.3.3.3
for 4.4.4.4 got response: 4.4.4.4
for 5.5.5.5 got response: 5.5.5.5
</pre>
<p>At least its working. Havent done any performance tests.<br />
Sample on pastie: <a href="http://pastie.org/private/afxlcuk1npwjov3wer5hw">http://pastie.org/private/afxlcuk1npwjov3wer5hw</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2010/06/09/making-http-requests-from-different-network-interfaces-with-ruby-and-curb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to identify your clients` browser type</title>
		<link>http://blog.sosedoff.com/2009/10/02/how-to-identify-your-clients-browser-type/</link>
		<comments>http://blog.sosedoff.com/2009/10/02/how-to-identify-your-clients-browser-type/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 18:44:40 +0000</pubDate>
		<dc:creator>Dan Sosedoff</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[agent]]></category>
		<category><![CDATA[user]]></category>

		<guid isPermaLink="false">http://blog.sosedoff.com/?p=178</guid>
		<description><![CDATA[Some time ago i wrote a simple regex patterns to determine whether my client crawler bot, mobile client or just regular one. Easy to expand and to use.

function is_mobile&#40;$agent&#41; &#123;
    $pattern = '/(blackberry&#124;motorokr&#124;motorola&#124;sony&#124;windows ce&#124;240x320&#124;176x220&#124;palm&#124;mobile&#124;iphone&#124;ipod&#124;symbian&#124;nokia&#124;samsung&#124;midp)/i';
    return &#40;bool&#41;preg_match&#40;$pattern, $agent&#41;;
&#125;
&#160;
function is_crawler&#40;$agent&#41; &#123;
    pattern = '/(google&#124;yahoo&#124;baidu&#124;bot&#124;webalta&#124;ia_archiver)/';
    return [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago i wrote a simple regex patterns to determine whether my client crawler bot, mobile client or just regular one. Easy to expand and to use.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> is_mobile<span style="color: #009900;">&#40;</span><span style="color: #000088;">$agent</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$pattern</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/(blackberry|motorokr|motorola|sony|windows ce|240x320|176x220|palm|mobile|iphone|ipod|symbian|nokia|samsung|midp)/i'</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>bool<span style="color: #009900;">&#41;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$agent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> is_crawler<span style="color: #009900;">&#40;</span><span style="color: #000088;">$agent</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    pattern <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/(google|yahoo|baidu|bot|webalta|ia_archiver)/'</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>bool<span style="color: #009900;">&#41;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pattern</span><span style="color: #339933;">,</span> <span style="color: #000088;">$agent</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.sosedoff.com/2009/10/02/how-to-identify-your-clients-browser-type/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

