<?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"
	>

<channel>
	<title>Netphase</title>
	<atom:link href="http://blog.netphase.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.netphase.com</link>
	<description>for a connected world</description>
	<pubDate>Thu, 06 Mar 2008 14:48:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
	<language>en</language>
			<item>
		<title>nested error_messages_for</title>
		<link>http://blog.netphase.com/2008/03/06/nested-error_messages_for/</link>
		<comments>http://blog.netphase.com/2008/03/06/nested-error_messages_for/#comments</comments>
		<pubDate>Thu, 06 Mar 2008 03:20:55 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2008/03/06/nested-error_messages_for/</guid>
		<description><![CDATA[I think lots of folks have run into this problem of using error_messages_for to display errors of nested or subordinate objects.  The current Rails method doesn't handle it well.  In addition, there's the problem of not being able to specify the full message.  So... I tackled this problem today and came up [...]]]></description>
			<content:encoded><![CDATA[<p>I think lots of folks have run into this problem of using error_messages_for to display errors of nested or subordinate objects.  The current Rails method doesn't handle it well.  In addition, there's the problem of not being able to specify the full message.  So... I tackled this problem today and came up with a pretty good solution using recursion.</p>
<div class="syntax_hilite">
<div id="ruby-2">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> nested_error_messages_for<span style="color:#006600; font-weight:bold;">&#40;</span>object<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; object = instance_variable_get<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">"@#{object}"</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>Symbol, <span style="color:#CC0066; font-weight:bold;">String</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">member</span>? object.<span style="color:#9966CC; font-weight:bold;">class</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">unless</span> object.<span style="color:#0000FF; font-weight:bold;">nil</span>? || object.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">count</span>.<span style="color:#9900CC;">zero</span>?&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; error_messages = object.<span style="color:#9900CC;">errors</span>.<span style="color:#9900CC;">to_a</span>.<span style="color:#9900CC;">uniq</span>.<span style="color:#9900CC;">map</span> <span style="color:#9966CC; font-weight:bold;">do</span> |key, value|<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object2 = object.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span>key<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> object2.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">Array</span><span style="color:#006600; font-weight:bold;">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; object2.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span>|obj| content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:li, nested_error_messages_for<span style="color:#006600; font-weight:bold;">&#40;</span>obj<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">elsif</span> object2.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>ActiveRecord::Base<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:li, nested_error_messages_for<span style="color:#006600; font-weight:bold;">&#40;</span>object2<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">elsif</span> value.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span>/^\^/<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:li, value<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span>..<span style="color:#9900CC;">value</span>.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:li, <span style="color:#996600;">"#{key.underscore.split('_').join(' ').humanize} #{value}"</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:div, <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:div, <span style="color:#996600;">"#{object.class} has errors"</span>, :<span style="color:#9966CC; font-weight:bold;">class</span> =&gt; 'error_field'<span style="color:#006600; font-weight:bold;">&#41;</span> +<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content_tag<span style="color:#006600; font-weight:bold;">&#40;</span>:ul, error_messages<span style="color:#006600; font-weight:bold;">&#41;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; :<span style="color:#9966CC; font-weight:bold;">class</span> =&gt; 'error_block'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ''<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<p>To use it, just replace your current call to error_messages_for with nested_error_messages_for.  There's nothing extra that needs to be done in the controller as with some recipes.  You'll also want to make it look good with some CSS.</p>
<p>I'm pretty sure there's more that could be done with this, but thought I'd present it here first and try to get some feedback before turning it into a gem.  Let me know how it works for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2008/03/06/nested-error_messages_for/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Extending ActiveRecord with count_since</title>
		<link>http://blog.netphase.com/2008/02/23/extending-activerecord-with-count_since/</link>
		<comments>http://blog.netphase.com/2008/02/23/extending-activerecord-with-count_since/#comments</comments>
		<pubDate>Sat, 23 Feb 2008 02:29:15 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[rails]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2008/02/23/extending-activerecord-with-count_since/</guid>
		<description><![CDATA[I just implemented a statistics page for an application and found that I was using this pattern over and over again:


User.count&#40;:conditions =&#62; &#91;'created_at&#62; ?', 30.days.ago&#93;&#41;



Here's a simple extension I made to ActiveRecord to DRY it up:


module ActiveRecord
&#160; class Base
&#160; &#160; &#160; def self.count_since&#40;time_ago&#41;
&#160; &#160; &#160; &#160; count&#40;:conditions =&#62; &#91;'created_at&#62; ?', time_ago&#93;&#41;
&#160; &#160; &#160; end
&#160; end
end



Put [...]]]></description>
			<content:encoded><![CDATA[<p>I just implemented a statistics page for an application and found that I was using this pattern over and over again:</p>
<div class="syntax_hilite">
<div id="ruby-6">
<div class="ruby">User.<span style="color:#9900CC;">count</span><span style="color:#006600; font-weight:bold;">&#40;</span>:conditions =&gt; <span style="color:#006600; font-weight:bold;">&#91;</span>'created_at&gt; ?', <span style="color:#006666;">30</span>.<span style="color:#9900CC;">days</span>.<span style="color:#9900CC;">ago</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p></p>
<p>Here's a simple extension I made to ActiveRecord to <abbr title="Don't Repeat Yourself">DRY</abbr> it up:</p>
<div class="syntax_hilite">
<div id="ruby-7">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">module</span> ActiveRecord<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">class</span> Base<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">count_since</span><span style="color:#006600; font-weight:bold;">&#40;</span>time_ago<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; count<span style="color:#006600; font-weight:bold;">&#40;</span>:conditions =&gt; <span style="color:#006600; font-weight:bold;">&#91;</span>'created_at&gt; ?', time_ago<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<p>Put that snippet in a file in your lib directory.  I called mine rails_extensions.rb.  Then add <em>require 'rails_extensions'</em> to the bottom of your environment.rb file.</p>
<p>Now you can just do:</p>
<div class="syntax_hilite">
<div id="ruby-8">
<div class="ruby">User.<span style="color:#9900CC;">count_since</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">30</span>.<span style="color:#9900CC;">days</span>.<span style="color:#9900CC;">ago</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p></p>
<p>That's a little cleaner, don't you think?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2008/02/23/extending-activerecord-with-count_since/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Uninstall Apache</title>
		<link>http://blog.netphase.com/2008/01/30/uninstall-apache/</link>
		<comments>http://blog.netphase.com/2008/01/30/uninstall-apache/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 18:21:35 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2008/01/30/uninstall-apache/</guid>
		<description><![CDATA[So, I'm sure many others have made the same mistake.  You downloaded the latest Apache, did the 3 step: 

configure --prefix=/usr/local --enable-mods-shared=all --enable-ssl --enable-proxy
make
sudo make install

Doh! That's probably not what you wanted.  Now you have stuff like

/usr/local/build
/usr/local/icons

You'd have been better off going with Apache 2's default prefix which is /usr/local/apache2.  The problem [...]]]></description>
			<content:encoded><![CDATA[<p>So, I'm sure many others have made the same mistake.  You downloaded the latest Apache, did the 3 step: </p>
<ol>
<li>configure --prefix=/usr/local --enable-mods-shared=all --enable-ssl --enable-proxy</li>
<li>make</li>
<li>sudo make install</li>
</ol>
<p>Doh! That's probably not what you wanted.  Now you have stuff like</p>
<ul>
<li>/usr/local/build</li>
<li>/usr/local/icons</li>
</ul>
<p>You'd have been better off going with Apache 2's default prefix which is /usr/local/apache2.  The problem is there's no uninstall!  If that's happened to you and you just made the mistake a short time ago, try this:</p>
<ol>
<li>Make sure you have enough free space for a backup of /usr/local
<p>$ sudo du -sh /usr/local<br />
2.2G    /usr/local</p>
<p>$ df -h
</li>
<li>Back it up
<p>$ tar cvf /tmp/usr_local.tar /usr/local
</li>
<li>Find out which files you just installed
<p>$ sudo find . -type f -newerct '60 minutes ago' > /tmp/uninstall_files.txt</p>
<p>$ sudo find . -type d -newerct '60 minutes ago' > /tmp/uninstall_dirs.txt
</li>
<li>Inspect the file you just created and remove things that don't belong (e.g. mysql)</li>
<li>Remove the files (don't get creative and add -r to rm -- <b>you did backup, right?</b>)
<p>$ cat uninstall_files.txt | sudo xargs rm</p>
<p>$ cat uninstall_dirs.txt | sudo xargs rmdir
</li>
</ol>
<p>Now, take off that prefix and try the 3-step again.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2008/01/30/uninstall-apache/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Autotest CPU Fix</title>
		<link>http://blog.netphase.com/2008/01/05/autotest-cpu-fix/</link>
		<comments>http://blog.netphase.com/2008/01/05/autotest-cpu-fix/#comments</comments>
		<pubDate>Sat, 05 Jan 2008 22:17:57 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2008/01/05/autotest-cpu-fix/</guid>
		<description><![CDATA[
Update 1/15/2008
Autotest and rspec both posted updates today.  Now, the way to fix this issue is slightly different:


Autotest.add_hook :run do &#124;autotest&#124;
&#160; autotest.add_exception&#40;/^\.\/vendor/&#41;
&#160; autotest.add_exception&#40;/\.svn/&#41;
end



Thanks Ryan and David for the updates!

I've been noticing in my current project that running autotest was constantly consuming about 25-30% of my cpu and causing my macbook pro to run really [...]]]></description>
			<content:encoded><![CDATA[<div style="background:#eee">
<b>Update 1/15/2008</b><br />
Autotest and rspec both posted updates today.  Now, the way to fix this issue is slightly different:</p>
<div class="syntax_hilite">
<div id="ruby-13">
<div class="ruby">Autotest.<span style="color:#9900CC;">add_hook</span> :run <span style="color:#9966CC; font-weight:bold;">do</span> |autotest|<br />
&nbsp; autotest.<span style="color:#9900CC;">add_exception</span><span style="color:#006600; font-weight:bold;">&#40;</span>/^\.\/vendor/<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; autotest.<span style="color:#9900CC;">add_exception</span><span style="color:#006600; font-weight:bold;">&#40;</span>/\.<span style="color:#9900CC;">svn</span>/<span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p>
Thanks <a href="http://blog.zenspider.com/">Ryan</a> and <a href="http://blog.davidchelimsky.net/">David<a/> for <a href="http://blog.davidchelimsky.net/articles/2008/01/15/rspec-1-1-2-and-zentest-3-8-0">the updates</a>!
</div>
<p>I've been noticing in my current project that running autotest was constantly consuming about 25-30% of my cpu and causing my macbook pro to run really hot.  I did a little googling and found <a href="http://rails.aizatto.com/2007/11/28/taming-the-autotest-beast-with-fsevents/">this discussion</a> on the topic.</p>
<p>For me, my problem was definitely the vendor directory (~3500 files in 4 plugins: rspec, rspec_on_rails, restful_open_id_authentication and active_merchant).  I tried excluding the entire directory by adding this to my ~/.autotest file:</p>
<div class="syntax_hilite">
<div id="ruby-14">
<div class="ruby">Autotest.<span style="color:#9900CC;">add_hook</span> :initialize <span style="color:#9966CC; font-weight:bold;">do</span> |autotest|<br />
&nbsp; &nbsp;autotest.<span style="color:#9900CC;">exceptions</span> &lt;&lt;%r%^\./<span style="color:#006600; font-weight:bold;">&#40;</span>?:coverage|db|doc|log|public|script|vendor|previous_failures.<span style="color:#9900CC;">txt</span><span style="color:#006600; font-weight:bold;">&#41;</span>%<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<p>However, that didn't work.  After some investigation, I found out that the rspec_on_rails plugin in my vendor directory was subclassing Autotest::Rspec and setting it's own exceptions string like this:</p>
<div class="syntax_hilite">
<div id="ruby-15">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> initialize <span style="color:#008000; font-style:italic;"># :nodoc:</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">super</span><br />
&nbsp; @exceptions = %r%^\./<span style="color:#006600; font-weight:bold;">&#40;</span>?:coverage|db|doc|log|public|script|vendor\/rails|previous_failures.<span style="color:#9900CC;">txt</span><span style="color:#006600; font-weight:bold;">&#41;</span>%<br />
...</div>
</div>
</div>
<p></p>
<p>See the problem?  It dutifully calls super so AutoTest:initialize can do it's stuff (including calling my hook) and then wipes out the exception string with it's own.</p>
<p>So, I browsed the lib/autotest.rb code and found another hook.  Adding this to my ~/.autotest now lowers the cpu usage to about 5%.  Huzzah!</p>
<div class="syntax_hilite">
<div id="ruby-16">
<div class="ruby">Autotest.<span style="color:#9900CC;">add_hook</span> :run <span style="color:#9966CC; font-weight:bold;">do</span> |autotest|<br />
&nbsp; autotest.<span style="color:#9900CC;">exceptions</span> = Regexp.<span style="color:#9900CC;">union</span><span style="color:#006600; font-weight:bold;">&#40;</span>/^\.\/vendor/, autotest.<span style="color:#9900CC;">exceptions</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2008/01/05/autotest-cpu-fix/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Drudge afraid of Forbes?  Not!</title>
		<link>http://blog.netphase.com/2007/11/08/drudge-afraid-of-forbes-not/</link>
		<comments>http://blog.netphase.com/2007/11/08/drudge-afraid-of-forbes-not/#comments</comments>
		<pubDate>Thu, 08 Nov 2007 15:36:51 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[Facebook]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/11/08/drudge-afraid-of-forbes-not/</guid>
		<description><![CDATA[On Tuesday, Forbes posted a bizarre article, Fear Among Facebook Developers, that seems to suggest if you're not a big brand on the Internet then you should just pack your bags and go home.
The issue is that Facebook is going to start putting more of its own ads throughout the site.  Big surprise.  [...]]]></description>
			<content:encoded><![CDATA[<p>On Tuesday, Forbes posted a bizarre article, <a href="http://www.forbes.com/2007/11/06/facebook-small-developers-tech-internet-cx_rr_1106techfacebook_print.html">Fear Among Facebook Developers</a>, that seems to suggest if you're not a big brand on the Internet then you should just pack your bags and go home.</p>
<p>The issue is that Facebook is going to start putting more of its own ads throughout the site.  Big surprise.  However, Facebook also allows apps to generally put whatever they want in the application canvas, including ads.  If Facebook advertises something else outside the canvas then it's not that big a deal to me.  As a developer, I don't really need them to provide me an "ad widget" as the author suggests; I can use <a href="http://www.google.com/adsense">Google Ads</a>, <a href="http://www.coudal.com/deck/">The Deck</a> or whatever.</p>
<blockquote><p>
If a small application developer is under the illusion that he can win a fight with a big-brand widget, that’s a bad plan, says Gerd Leonhard, chief executive of Sonific, which recently launched a music widget on Facebook.
</p></blockquote>
<p>Strange comment.  "Sonific" doesn't sound like a big brand to me, and yet they just launched a music widget?  Good for them.  However, it seems to me like they're trying to scare off competition.  Also, the net is the quintessential mechanism for some little guy knocking over "big brands".  In fact, that's what Facebook is!</p>
<p><a href="http://apps.facebook.com/netphase-madlibs/"><img src="http://blog.netphase.com/wp-content/uploads/2007/11/madlibs-car-logo.png" alt="madlibs_car_logo.png" border="0" width="75" height="72" align="right" style="margin: 0 1em 2em" /></a></p>
<p>A couple months ago, we launched our first Facebook app for <a href="http://imin.com">I'm&nbsp;In</a>.  Within a week about 1000 people had installed it to check it out.  That's pretty cool, considering all we had to do was get it added to the Facebook directory.  So, over the long run will it generate more transactions for I'm In?  I think so, but time will tell.  For a site like that, it wouldn't take too many added sales to cover the cost of building an app like <a href="http://apps.facebook.com/netphase-madlibs/">Mad&nbsp;Libs™</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/11/08/drudge-afraid-of-forbes-not/feed/</wfw:commentRss>
		</item>
		<item>
		<title>acts_as_amazon_product</title>
		<link>http://blog.netphase.com/2007/09/26/acts_as_amazon_product/</link>
		<comments>http://blog.netphase.com/2007/09/26/acts_as_amazon_product/#comments</comments>
		<pubDate>Wed, 26 Sep 2007 20:31:58 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[Amazon]]></category>

		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/09/26/acts_as_amazon_product/</guid>
		<description><![CDATA[Today we released a new Ruby Gem that makes integrating with Amazon E-Commerce Service (ECS) a snap.  It's called acts_as_amazon_product and you can find it on RubyForge.
All that's necessary to integrate any of your existing models with Amazon is to add a require line to the top of your model file and then an [...]]]></description>
			<content:encoded><![CDATA[<p>Today we released a new Ruby Gem that makes integrating with Amazon E-Commerce Service (ECS) a snap.  It's called acts_as_amazon_product and you can <a href="http://rubyforge.org/projects/aaap/">find it on RubyForge</a>.</p>
<p>All that's necessary to integrate any of your existing models with Amazon is to add a <em>require</em> line to the top of your model file and then an acts_as_amazon_product line just inside your class definition.</p>
<div class="syntax_hilite">
<div id="ruby-20">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> 'acts_as_amazon_product'</p>
<p><span style="color:#9966CC; font-weight:bold;">class</span> Book &lt;ActiveRecord::Base<br />
&nbsp; acts_as_amazon_product<span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; :asin =&gt; 'isbn', :name =&gt; 'title', <br />
&nbsp; &nbsp; &nbsp; :access_key =&gt; '<span style="color:#006666;">0123456</span>', <br />
&nbsp; &nbsp; &nbsp; :associate_tag =&gt; 'assoc-<span style="color:#006666;">20</span>'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<p>After this, you can access Amazon data in your controllers or views like this:</p>
<div class="syntax_hilite">
<div id="ruby-21">
<div class="ruby">@book = Book.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>:title =&gt; 'Getting Things Done'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
@book.<span style="color:#9900CC;">amazon</span>.<span style="color:#9900CC;">isbn</span><br />
@book.<span style="color:#9900CC;">amazon</span>.<span style="color:#9900CC;">title</span><br />
@book.<span style="color:#9900CC;">amazon</span>.<span style="color:#9900CC;">author</span><br />
@book.<span style="color:#9900CC;">amazon</span>.<span style="color:#9900CC;">small_image_url</span></p>
<p>@book.<span style="color:#9900CC;">amazon</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>'itemattributes/foobar'<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p></p>
<p>The code does not require changing any current database tables.  It only requires adding one migration for a single new table used to cache responses from Amazon:</p>
<div class="syntax_hilite">
<div id="ruby-22">
<div class="ruby">ActiveRecord::Base.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">create_table</span> :amazon_products <span style="color:#9966CC; font-weight:bold;">do</span> |t|<br />
&nbsp; t.<span style="color:#9900CC;">column</span> :asin, :<span style="color:#CC0066; font-weight:bold;">string</span><br />
&nbsp; t.<span style="color:#9900CC;">column</span> :xml, :text<br />
&nbsp; t.<span style="color:#9900CC;">column</span> :created_at, :datetime, :null =&gt; <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; t.<span style="color:#9900CC;">column</span> :amazonable_id, :<span style="color:#CC0066; font-weight:bold;">integer</span>, :default =&gt; <span style="color:#006666;">0</span>, :null =&gt; <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; t.<span style="color:#9900CC;">column</span> :amazonable_type, :<span style="color:#CC0066; font-weight:bold;">string</span>, :limit =&gt; <span style="color:#006666;">15</span>, :default =&gt; <span style="color:#996600;">""</span>, :null =&gt; <span style="color:#0000FF; font-weight:bold;">false</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/09/26/acts_as_amazon_product/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Web Session Patent Awarded</title>
		<link>http://blog.netphase.com/2007/06/03/web-session-patent-awarded/</link>
		<comments>http://blog.netphase.com/2007/06/03/web-session-patent-awarded/#comments</comments>
		<pubDate>Sun, 03 Jun 2007 22:48:03 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/06/03/web-session-patent-awarded/</guid>
		<description><![CDATA[I just found out that the U.S. Patent office issued patent number 7,188,176 naming me as primary inventor for an "Apparatus, system, and method for maintaining a persistent data state on a communications network".  I'm pretty stunned.  I did the work for this back in 1998 for Priceline and they filed for the [...]]]></description>
			<content:encoded><![CDATA[<p>I just found out that the U.S. Patent office issued <a href="http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&#038;Sect2=HITOFF&#038;d=PALL&#038;p=1&#038;u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&#038;r=1&#038;f=G&#038;l=50&#038;s1=7188176.PN.&#038;OS=PN/7188176&#038;RS=PN/7188176">patent number 7,188,176</a> naming me as primary inventor for an "Apparatus, system, and method for maintaining a persistent data state on a communications network".  I'm pretty stunned.  I did the work for this back in 1998 for <a href="http://priceline.com">Priceline</a> and they filed for the patent in 2000.  So, I guess I'm now "officially" an Inventor.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/06/03/web-session-patent-awarded/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Apache Log Quick Summary</title>
		<link>http://blog.netphase.com/2007/05/10/apache-log-quick-summary/</link>
		<comments>http://blog.netphase.com/2007/05/10/apache-log-quick-summary/#comments</comments>
		<pubDate>Thu, 10 May 2007 19:46:23 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/05/10/apache-log-quick-summary/</guid>
		<description><![CDATA[Sometimes I set up a quick site for a client and want to summarize hits without setting up awstats.  So, I wrote a quick and dirty script to sum up the hits per day in Apache's access_log file.
Example:
$ cklog access_log
04-15-2007: 21
04-16-2007: 2134
04-17-2007: 304
04-18-2007: 6960
04-19-2007: 951
04-20-2007: 412
Here's the script:


require 'date'
daily = Hash.new
File.open&#40;ARGV&#91;0&#93; &#124;&#124; "access_log", "r"&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I set up a quick site for a client and want to summarize hits without setting up awstats.  So, I wrote a quick and dirty script to sum up the hits per day in Apache's access_log file.</p>
<p>Example:</p>
<p>$ cklog access_log</p>
<p>04-15-2007: 21<br />
04-16-2007: 2134<br />
04-17-2007: 304<br />
04-18-2007: 6960<br />
04-19-2007: 951<br />
04-20-2007: 412</p>
<p>Here's the script:</p>
<div class="syntax_hilite">
<div id="ruby-24">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> 'date'</p>
<p>daily = Hash.<span style="color:#9900CC;">new</span><br />
File.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#996600;">"access_log"</span>, <span style="color:#996600;">"r"</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> |file|<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">while</span> line = file.<span style="color:#CC0066; font-weight:bold;">gets</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> line =~ /<span style="color:#006600; font-weight:bold;">&#40;</span>\d<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#125;</span>\/\w<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#125;</span>\/\d<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006666;">4</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.*GET\s<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span>^\?\s<span style="color:#006600; font-weight:bold;">&#93;</span>+<span style="color:#006600; font-weight:bold;">&#41;</span>/<br />
&nbsp; &nbsp; &nbsp; date = Date.<span style="color:#9900CC;">strptime</span> $<span style="color:#006666;">1</span>, '%d/%b/%Y'<br />
&nbsp; &nbsp; &nbsp; daily<span style="color:#006600; font-weight:bold;">&#91;</span>date<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span> <span style="color:#9966CC; font-weight:bold;">if</span> daily<span style="color:#006600; font-weight:bold;">&#91;</span>date<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?<br />
&nbsp; &nbsp; &nbsp; daily<span style="color:#006600; font-weight:bold;">&#91;</span>date<span style="color:#006600; font-weight:bold;">&#93;</span> + <span style="color:#006666;">1</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>daily.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span>|d, f| <br />
&nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"#{d.strftime '%m-%d-%Y'}: #{f}"</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/05/10/apache-log-quick-summary/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby Web Crawler</title>
		<link>http://blog.netphase.com/2007/04/19/ruby-web-crawler/</link>
		<comments>http://blog.netphase.com/2007/04/19/ruby-web-crawler/#comments</comments>
		<pubDate>Thu, 19 Apr 2007 21:26:43 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/04/19/ruby-web-crawler/</guid>
		<description><![CDATA[Here's a web crawler I wrote awhile back.  It's pretty simple, but does the job.  If you need something more, you might try rdig or Nutch.
You can run this as a stand-alone script and just pass in the URL to crawl as an argument.


require 'net/http'
require 'uri'
class SiteCrawler
&#160; def initialize&#40;url&#41;
&#160; &#160; @site_uri = URI.parse&#40;url&#41;
&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Here's a web crawler I wrote awhile back.  It's pretty simple, but does the job.  If you need something more, you might try <a href="http://rdig.rubyforge.org/">rdig</a> or <a href="http://lucene.apache.org/nutch/">Nutch</a>.</p>
<p>You can run this as a stand-alone script and just pass in the URL to crawl as an argument.</p>
<div class="syntax_hilite">
<div id="ruby-26">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> 'net/http'<br />
<span style="color:#CC0066; font-weight:bold;">require</span> 'uri'</p>
<p><span style="color:#9966CC; font-weight:bold;">class</span> SiteCrawler<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @site_uri = URI.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @site_uri.<span style="color:#9900CC;">path</span> = <span style="color:#996600;">"/"</span> <span style="color:#9966CC; font-weight:bold;">if</span> @site_uri.<span style="color:#9900CC;">path</span> == <span style="color:#996600;">""</span><br />
&nbsp; &nbsp; @visited = Hash.<span style="color:#9900CC;">new</span><br />
&nbsp; &nbsp; @queue = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span><br />
&nbsp; &nbsp; addPath<span style="color:#006600; font-weight:bold;">&#40;</span>@site_uri.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Initialized site crawl for #{@site_uri}"</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> addPath<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; @queue.<span style="color:#9900CC;">push</span> path<br />
&nbsp; &nbsp; @visited<span style="color:#006600; font-weight:bold;">&#91;</span>path<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> getPage<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">begin</span><br />
&nbsp; &nbsp; &nbsp; uri = @site_uri.<span style="color:#9900CC;">clone</span><br />
&nbsp; &nbsp; &nbsp; uri.<span style="color:#9900CC;">path</span> = uri.<span style="color:#9900CC;">path</span> + path <span style="color:#9966CC; font-weight:bold;">if</span> path != <span style="color:#996600;">"/"</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"getting #{uri}"</span><br />
&nbsp; &nbsp; &nbsp; response = Net::HTTP.<span style="color:#9900CC;">get_response</span><span style="color:#006600; font-weight:bold;">&#40;</span>uri<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">rescue</span> Exception<br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Error: #{$!}"</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">""</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">return</span> response.<span style="color:#9900CC;">body</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> queueLocalLinks<span style="color:#006600; font-weight:bold;">&#40;</span>html<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; html.<span style="color:#9900CC;">scan</span><span style="color:#006600; font-weight:bold;">&#40;</span>/&lt;a href\s*=\s*<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"']([^"</span><span style="color:#006600; font-weight:bold;">&#93;</span>+<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#996600;">"/i) {|w|<br />
&nbsp; &nbsp; &nbsp; uri = URI.parse("</span><span style="color:#008000; font-style:italic;">#{w}&quot;)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> !@visited.<span style="color:#9900CC;">has_key</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>uri.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">and</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">&#40;</span>uri.<span style="color:#9900CC;">relative</span>? <span style="color:#9966CC; font-weight:bold;">or</span> uri.<span style="color:#9900CC;">host</span> == @site_uri.<span style="color:#9900CC;">host</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; addPath<span style="color:#006600; font-weight:bold;">&#40;</span>uri.<span style="color:#9900CC;">path</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> crawlSite<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!@queue.<span style="color:#9900CC;">empty</span>?<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; uri = @queue.<span style="color:#9900CC;">shift</span><br />
&nbsp; &nbsp; &nbsp; page = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>uri<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">yield</span> uri, page<br />
&nbsp; &nbsp; &nbsp; queueLocalLinks<span style="color:#006600; font-weight:bold;">&#40;</span>page<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; @visited<span style="color:#006600; font-weight:bold;">&#91;</span>uri<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>sc = SiteCrawler.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
@pages = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span><br />
sc.<span style="color:#9900CC;">crawlSite</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |url, page_text|<br />
&nbsp; @pages &lt;&lt;url<br />
&nbsp; <span style="color:#008000; font-style:italic;"># SITE_INDEX &lt;&lt;{ :url =&gt; url, :context =&gt; page_text }</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/04/19/ruby-web-crawler/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The Google Bus</title>
		<link>http://blog.netphase.com/2007/03/13/the-google-bus/</link>
		<comments>http://blog.netphase.com/2007/03/13/the-google-bus/#comments</comments>
		<pubDate>Tue, 13 Mar 2007 21:55:40 +0000</pubDate>
		<dc:creator>scott</dc:creator>
		
		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://blog.netphase.com/2007/03/13/the-google-bus/</guid>
		<description><![CDATA[Unbelievable...  Working at the Googleplex gets sweeter all the time.

[Google] now ferries about 1,200 employees to and from Google daily--nearly one-fourth of its local work force--aboard 32 shuttle buses equipped with comfortable leather seats and wireless Internet access. Bicycles are allowed on exterior racks, and dogs on forward seats, or on their owners' laps [...]]]></description>
			<content:encoded><![CDATA[<p>Unbelievable...  <a href="http://news.com.com/2100-1030_3-6166216.html">Working at the Googleplex</a> gets sweeter all the time.</p>
<blockquote><p>
[Google] now ferries about 1,200 employees to and from Google daily--nearly one-fourth of its local work force--aboard 32 shuttle buses equipped with comfortable leather seats and wireless Internet access. Bicycles are allowed on exterior racks, and dogs on forward seats, or on their owners' laps if the buses run full.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.netphase.com/2007/03/13/the-google-bus/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
