<?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>We Heart Code &#187; ruby</title>
	<atom:link href="http://www.weheartcode.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.weheartcode.com</link>
	<description>A discourse on programming</description>
	<lastBuildDate>Sun, 17 Jan 2010 02:16:44 +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>Reading An Excel File With Ruby</title>
		<link>http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/</link>
		<comments>http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/#comments</comments>
		<pubDate>Fri, 05 Oct 2007 13:31:35 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/</guid>
		<description><![CDATA[This tutorial will cover how to read (or parse) an excel file with ruby. I had to write a script to unpivot some data for a co-worker that saved him hours of time, and I got to write a ruby script, so it was a win-win. Here's how you can do the same thing.

Installing Parseexcel
Parseexcel [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will cover how to read (or parse) an excel file with ruby. I had to write a script to unpivot some data for a co-worker that saved him hours of time, and I got to write a ruby script, so it was a win-win. Here's how you can do the same thing.</p>
<p><span id="more-35"></span></p>
<h2>Installing Parseexcel</h2>
<p><a href="http://raa.ruby-lang.org/project/parseexcel/">Parseexcel</a> is a ruby port of the perl parseexcel module.</p>
<p>It's installable via a nice gem like so:</p>
<div class="syntax_hilite">
<div id="code-8">
<div class="code">gem install parseexcel</div>
</div>
</div>
<p></p>
<p>That's that, now remember since it's a gem library we have to tell our script to use the gem libs when we run the script from the console using the -rubygems switch.</p>
<h2>Using Parseexcel</h2>
<p>Parseexcel is a very straight forward library, you can't do too much with it, but it gets the job done.</p>
<h3>Getting a Workbook</h3>
<div class="syntax_hilite">
<div id="code-9">
<div class="code">Spreadsheet::<span style="">ParseExcel</span>.<span style="">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span>filenameandpath<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p>
This returns the actual excel file's workbook, from there we need to determine what worksheet we're on.</p>
<h3>Getting a Worksheet</h3>
<div class="syntax_hilite">
<div id="code-10">
<div class="code">worksheet = workbook.<span style="">worksheet</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p>
Will return the first worksheet, you could also use the each method on the workbook to iterate over all the worksheets.</p>
<h3>Iterating over rows and columns</h3>
<p>The worksheet object has a very nice each method that will allow us to iterate over the rows like so</p>
<div class="syntax_hilite">
<div id="ruby-11">
<div class="ruby">worksheet.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |row|<br />
&nbsp; j=<span style="color:#006666;">0</span><br />
&nbsp; i=<span style="color:#006666;">0</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> row != <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; row.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |cell|<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> cell != <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; &nbsp; &nbsp; contents = cell.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#40;</span>'latin1'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Row: #{j} Cell: #{i} #{contents}"</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; i = i+<span style="color:#006666;">1</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; j = j +<span style="color:#006666;">1</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<h3>Getting Cell Data</h3>
<ul>
<li><b>Getting a String</b>: cell.to_s('latin1')</li>
<li><b>Getting a Float</b>: cell.to_s('latin1')</li>
<li><b>Getting a Int</b>: cell.to_i</li>
<li><b>Getting a Date</b>: cell.date</li>
</ul>
<h3>Getting A Specific Cell</h3>
<div class="syntax_hilite">
<div id="ruby-12">
<div class="ruby">cell = row.<span style="color:#9900CC;">at</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#returns cell at column 3 </span></div>
</div>
</div>
<p></p>
<h3>A basic script for dumping an excel file</h3>
<div class="syntax_hilite">
<div id="ruby-13">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> 'parseexcel'</p>
<p><span style="color:#008000; font-style:italic;">#Open the excel file passed in from the commandline</span><br />
workbook = Spreadsheet::ParseExcel.<span style="color:#9900CC;">parse</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></p>
<p><span style="color:#008000; font-style:italic;">#Get the first worksheet</span><br />
worksheet = workbook.<span style="color:#9900CC;">worksheet</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p><span style="color:#008000; font-style:italic;">#cycle over every row</span><br />
worksheet.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |row|<br />
&nbsp; j=<span style="color:#006666;">0</span><br />
&nbsp; i=<span style="color:#006666;">0</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> row != <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; <span style="color:#008000; font-style:italic;">#cycle over each cell in this row if it's not an empty row</span><br />
&nbsp; row.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |cell|<br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> cell != <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#Get the contents of the cell as a string</span><br />
&nbsp; &nbsp; &nbsp; contents = cell.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#40;</span>'latin1'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Row: #{j} Cell: #{i}&gt; #{contents}"</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; i = i+<span style="color:#006666;">1</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<p>To run the script, remember to use the -rubygems switch so that you can find the parsexcel library.</p>
<div class="syntax_hilite">
<div id="code-14">
<div class="code">ruby -rubygems excelparse.<span style="">rb</span> myfile.<span style="">xls</span></div>
</div>
</div>
<p></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/&amp;title=Reading+An+Excel+File+With+Ruby" title="Add 'Reading An Excel File With Ruby' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Reading An Excel File With Ruby' to Del.icio.us" alt="Add 'Reading An Excel File With Ruby' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/&amp;title=Reading+An+Excel+File+With+Ruby" title="Add 'Reading An Excel File With Ruby' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Reading An Excel File With Ruby' to digg" alt="Add 'Reading An Excel File With Ruby' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Reading+An+Excel+File+With+Ruby&amp;u=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/" title="Add 'Reading An Excel File With Ruby' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Reading An Excel File With Ruby' to FURL" alt="Add 'Reading An Excel File With Ruby' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/&amp;title=Reading+An+Excel+File+With+Ruby" title="Add 'Reading An Excel File With Ruby' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Reading An Excel File With Ruby' to reddit" alt="Add 'Reading An Excel File With Ruby' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/" title="Add 'Reading An Excel File With Ruby' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Reading An Excel File With Ruby' to Technorati" alt="Add 'Reading An Excel File With Ruby' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/&amp;title=Reading+An+Excel+File+With+Ruby" title="Add 'Reading An Excel File With Ruby' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Reading An Excel File With Ruby' to Google Bookmarks" alt="Add 'Reading An Excel File With Ruby' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2007/10/05/reading-an-excel-file-with-ruby/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>Easy XML Generation with Ruby and ERB</title>
		<link>http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/</link>
		<comments>http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 15:42:25 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[code generation]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/</guid>
		<description><![CDATA[Ah, the bracket tax. XML-Situps, whatever you want to call them, if you write any code (especially if you use java) it should be your sworn enemy. The other day I had to create about 40 XML files for some Java Webstart configs. Instead of doing them by hand, I decided to check out the [...]]]></description>
			<content:encoded><![CDATA[<p>Ah, the bracket tax. XML-Situps, whatever you want to call them, if you write any code (especially if you use java) it should be your sworn enemy. The other day I had to create about 40 XML files for some Java Webstart configs. Instead of doing them by hand, I decided to check out the ERB class for easy "templating" that's built into Ruby. It makes doing code generation very easy!</p>
<h3>Our Task</h3>
<p>Create a custom XML file for each .jar file in a directory.</p>
<p>...more after the jump!<br />
<span id="more-31"></span></p>
<h3>Strategy</h3>
<p>With any code generation project we need to identify a few things.</p>
<ol>
<li>Static template: The code/text that will stay the same.</li>
<li>Dynamic variables: These are the pieces that will change in our template.</li>
<li>Input source: The input for our dynamic variables.</li>
</ol>
<p>For me, the static template is a JNLP XML file that looks like this:</p>
<div class="syntax_hilite">
<div id="xml-22">
<div class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>?xml <span style="color: #000066;">version</span>=<span style="color: #ff0000;">"1.0"</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">"UTF-8"</span>?<span style="font-weight: bold; color: black;">&gt;</span></span><br />
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;jnlp</span><br />
&nbsp; <span style="color: #000066;">spec</span>=<span style="color: #ff0000;">"1.0+"</span><br />
&nbsp; <span style="color: #000066;">codebase</span>=<span style="color: #ff0000;">"http://redacted.com/libs/com.redacted.dao_1.3"</span><br />
&nbsp; <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"RcpWebStart.jnlp"</span><span style="font-weight: bold; color: black;">&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;information<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;title<span style="font-weight: bold; color: black;">&gt;</span></span></span>RedactedLibs<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/title<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;vendor<span style="font-weight: bold; color: black;">&gt;</span></span></span>Redacted<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/vendor<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;description<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;strong<span style="font-weight: bold; color: black;">&gt;</span></span></span>com.redacted.dao_1.3.1.jar<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/strong<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/description<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/information<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;security<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;all</span>-permissions<span style="font-weight: bold; color: black;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/security<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;resources<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;j2se</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">"1.4+"</span><span style="font-weight: bold; color: black;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;jar</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"com.redacted.dao_1.3.1.jar"</span><span style="font-weight: bold; color: black;">/&gt;</span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/resources<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;component</span>-desc<span style="font-weight: bold; color: black;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/jnlp<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</div>
</div>
<p></p>
<p>The dynamic bits will be anywhere a jar is referenced as well as the directory for the jar.</p>
<h3>The Template</h3>
<p>The template defines our static text, and the variables and/or ruby code that will be substituted into the text by ERB.</p>
<p>We use
<div class="syntax_hilite">
<div id="code-23">
<div class="code">&lt;%= %&gt;</div>
</div>
</div>
<p> blocks to substitute in variables from our ruby script.</p>
<p>Here's what my template looks like, I have four variables that I want to substitute in.</p>
<ul>
<li><strong>basedir</strong>: the base directory of where I'm storing my jar.</li>
<li><strong>shortname</strong>: the name of the jar sans the version.</li>
<li><strong>jarname</strong>: the full name of the jar file.</li>
</ul>
<div class="syntax_hilite">
<div id="xml-24">
<div class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>?xml <span style="color: #000066;">version</span>=<span style="color: #ff0000;">"1.0"</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">"UTF-8"</span>?<span style="font-weight: bold; color: black;">&gt;</span></span><br />
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;jnlp</span><br />
&nbsp; <span style="color: #000066;">spec</span>=<span style="color: #ff0000;">"1.0+"</span><br />
&nbsp; <span style="color: #000066;">codebase</span>=<span style="color: #ff0000;">"http://redacted.net/libs/&lt;%=basedir%&gt;</span>/<span style="color: #009900;">&lt;%=shortname%&gt;</span>_<span style="color: #009900;">&lt;%=version%&gt;</span>&quot;<br />
&nbsp; href=&quot;RcpWebStart.jnlp&quot;&gt;<br />
&nbsp; <span style="color: #009900;">&lt;information&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;title&gt;</span><span style="color: #009900;">&lt;%=basedir%&gt;</span><span style="color: #009900;">&lt;/title&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;vendor&gt;</span>Redacted<span style="color: #009900;">&lt;/vendor&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;description&gt;</span><span style="color: #009900;">&lt;%=jarname%&gt;</span><span style="color: #009900;">&lt;/description&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;/information&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;security&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;all-permissions/&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;/security&gt;</span><br />
&nbsp; <span style="color: #009900;">&lt;resources&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;j2se version="</span><span style="color: #cc66cc;">1</span>.<span style="color: #cc66cc;">4</span>+<span style="color: #ff0000;">"/&gt;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&lt;jar href="</span><span style="font-weight: bold; color: black;">&lt;</span>%=jarname%<span style="font-weight: bold; color: black;">&gt;</span></span>&quot;/&gt;<br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/resources<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;component</span>-desc<span style="font-weight: bold; color: black;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/jnlp<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</div>
</div>
<p></p>
<h3>The Code</h3>
<p>Let's examine some code. The first thing I do is create the template string, i Use the %q{ shortcut to avoid having to worry about quotes.</p>
<p>Next, I need to define my template, that's what this line does.</p>
<div class="syntax_hilite">
<div id="ruby-25">
<div class="ruby">jnlp = ERB.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>template, <span style="color:#006666;">0</span>, <span style="color:#996600;">"%&lt;&gt;"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>It says, create a new ERB object using the string 'template' as the template and the "%&lt;&gt;" as my template escape operators.</p>
<p>Our next step is to loop through all the jar's in a directory and create a new file for each one, here's the juicy bits to accomplish that.</p>
<div class="syntax_hilite">
<div id="ruby-26">
<div class="ruby">b = <span style="color:#CC0066; font-weight:bold;">binding</span><br />
&nbsp; &nbsp; &nbsp;jarname = File.<span style="color:#9900CC;">basename</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;basedir = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; &nbsp;shortname = jarname.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/<span style="color:#006600; font-weight:bold;">&#40;</span>.+?<span style="color:#006600; font-weight:bold;">&#41;</span>_<span style="color:#006600; font-weight:bold;">&#40;</span>\d.+<span style="color:#006600; font-weight:bold;">&#41;</span>$/,'\<span style="color:#006666;">1</span>'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;version = jarname.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/<span style="color:#006600; font-weight:bold;">&#40;</span>.+?<span style="color:#006600; font-weight:bold;">&#41;</span>_<span style="color:#006600; font-weight:bold;">&#40;</span>\d\.\d<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#40;</span>.+<span style="color:#006600; font-weight:bold;">&#41;</span>$/,'\<span style="color:#006666;">2</span>'<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp;dirname = shortname + <span style="color:#996600;">"_"</span> + version<br />
&nbsp; &nbsp; &nbsp;ourfile = jnlp.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span></div>
</div>
</div>
<p></p>
<p>Notice that we create a binding variable called b and then pass that to our ERB object (jnlp), that binding variable tells ERB to use template variables in the same scope as it. It's some ruby black magic that makes our lives easier.<br />
The rest of the script actually creates some directory and writes the created file to a directory based on the name of the jar.</p>
<div class="syntax_hilite">
<div id="ruby-27">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">"erb"</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">"find"</span></p>
<p>template = %q<span style="color:#006600; font-weight:bold;">&#123;</span><br />
&lt;?xml version=<span style="color:#996600;">"1.0"</span> encoding=<span style="color:#996600;">"UTF-8"</span>?&gt;<br />
&lt;jnlp<br />
&nbsp; spec=<span style="color:#996600;">"1.0+"</span><br />
&nbsp; codebase=<span style="color:#996600;">"http://redacted.net/libs/&lt;%=basedir%&gt;/&lt;%=shortname%&gt;_&lt;%=version%&gt;"</span><br />
&nbsp; href=<span style="color:#996600;">"RcpWebStart.jnlp"</span>&gt;<br />
&nbsp; &lt;information&gt;<br />
&nbsp; &nbsp; &lt;title&gt;&lt;%=basedir%&gt;&lt;/title&gt;<br />
&nbsp; &nbsp; &lt;vendor&gt;Redactedl&lt;/vendor&gt;<br />
&nbsp; &nbsp; &lt;description&gt;&lt;%=jarname%&gt;&lt;/description&gt;<br />
&nbsp; &lt;/information&gt;<br />
&nbsp; &lt;security&gt;<br />
&nbsp; &nbsp; &lt;all-permissions/&gt;<br />
&nbsp; &lt;/security&gt;<br />
&nbsp; &lt;resources&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;j2se version=<span style="color:#996600;">"1.4+"</span>/&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;jar href=<span style="color:#996600;">"&lt;%=jarname%&gt;"</span>/&gt;<br />
&nbsp; &lt;/resources&gt;<br />
&nbsp; &lt;component-desc/&gt;<br />
&lt;/jnlp&gt;<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p>&nbsp; jnlp = ERB.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>template, <span style="color:#006666;">0</span>, <span style="color:#996600;">"%&lt;&gt;"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</p>
<p>&nbsp; <span style="color:#008000; font-style:italic;">#Search for jar files here</span><br />
&nbsp; Find.<span style="color:#9900CC;">find</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> <span style="color:#9966CC; font-weight:bold;">do</span> |path|</p>
<p>&nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">if</span> !FileTest.<span style="color:#9900CC;">directory</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;b = <span style="color:#CC0066; font-weight:bold;">binding</span><br />
&nbsp; &nbsp; &nbsp;jarname = File.<span style="color:#9900CC;">basename</span><span style="color:#006600; font-weight:bold;">&#40;</span>path<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;basedir = ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; &nbsp;shortname = jarname.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/<span style="color:#006600; font-weight:bold;">&#40;</span>.+?<span style="color:#006600; font-weight:bold;">&#41;</span>_<span style="color:#006600; font-weight:bold;">&#40;</span>\d.+<span style="color:#006600; font-weight:bold;">&#41;</span>$/,'\<span style="color:#006666;">1</span>'<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;version = jarname.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/<span style="color:#006600; font-weight:bold;">&#40;</span>.+?<span style="color:#006600; font-weight:bold;">&#41;</span>_<span style="color:#006600; font-weight:bold;">&#40;</span>\d\.\d<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#40;</span>.+<span style="color:#006600; font-weight:bold;">&#41;</span>$/,'\<span style="color:#006666;">2</span>'<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp;dirname = shortname + <span style="color:#996600;">"_"</span> + version</p>
<p>&nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;">#pass in the binding variable and create a string from the template</span><br />
&nbsp; &nbsp; &nbsp;ourfile = jnlp.<span style="color:#9900CC;">result</span><span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p>&nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;">#create a new directory and file, and output the template string to it.</span><br />
&nbsp; &nbsp; &nbsp;Dir.<span style="color:#9900CC;">mkdir</span><span style="color:#006600; font-weight:bold;">&#40;</span>basedir + <span style="color:#996600;">"/"</span> + dirname<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;outfile = File.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>basedir + <span style="color:#996600;">"/"</span> + dirname +&nbsp; <span style="color:#996600;">"/RcpWebStart.jnlp"</span>,<span style="color:#996600;">"w+"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp;outfile &lt;&lt;ourfile<br />
&nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<h3>The fun doesn't stop there</h3>
<p>This is an elementary example, but ERB also allows you to embed real ruby code in the template, this allows you to accomplish looping. </p>
<p>So we could pass in an array of person objects and loop through them with a template like this:</p>
<div class="syntax_hilite">
<div id="xml-28">
<div class="xml"><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;people<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; &nbsp;<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>%@people.each do |person| %<span style="font-weight: bold; color: black;">&gt;</span></span><br />
&nbsp; &nbsp;<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;name<span style="font-weight: bold; color: black;">&gt;</span></span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>%=person.name%<span style="font-weight: bold; color: black;">&gt;</span></span><span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/name<span style="font-weight: bold; color: black;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;</span>%end%<span style="font-weight: bold; color: black;">&gt;</span></span><br />
&nbsp;<span style="color: #009900;"><span style="font-weight: bold; color: black;">&lt;/people<span style="font-weight: bold; color: black;">&gt;</span></span></span></div>
</div>
</div>
<p></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/&amp;title=Easy+XML+Generation+with+Ruby+and+ERB" title="Add 'Easy XML Generation with Ruby and ERB' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Easy XML Generation with Ruby and ERB' to Del.icio.us" alt="Add 'Easy XML Generation with Ruby and ERB' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/&amp;title=Easy+XML+Generation+with+Ruby+and+ERB" title="Add 'Easy XML Generation with Ruby and ERB' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Easy XML Generation with Ruby and ERB' to digg" alt="Add 'Easy XML Generation with Ruby and ERB' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Easy+XML+Generation+with+Ruby+and+ERB&amp;u=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/" title="Add 'Easy XML Generation with Ruby and ERB' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Easy XML Generation with Ruby and ERB' to FURL" alt="Add 'Easy XML Generation with Ruby and ERB' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/&amp;title=Easy+XML+Generation+with+Ruby+and+ERB" title="Add 'Easy XML Generation with Ruby and ERB' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Easy XML Generation with Ruby and ERB' to reddit" alt="Add 'Easy XML Generation with Ruby and ERB' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/" title="Add 'Easy XML Generation with Ruby and ERB' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Easy XML Generation with Ruby and ERB' to Technorati" alt="Add 'Easy XML Generation with Ruby and ERB' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/&amp;title=Easy+XML+Generation+with+Ruby+and+ERB" title="Add 'Easy XML Generation with Ruby and ERB' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Easy XML Generation with Ruby and ERB' to Google Bookmarks" alt="Add 'Easy XML Generation with Ruby and ERB' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2007/09/18/easy-xml-generation-with-ruby-and-erb/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Capturing STDERR with ruby backticks</title>
		<link>http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/</link>
		<comments>http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/#comments</comments>
		<pubDate>Fri, 14 Sep 2007 14:13:25 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/</guid>
		<description><![CDATA[I was writing a ruby script today that ran a linux command for every line in a file. The problem was the backtick operator in ruby only captures stdout, here's a little trick to get stderr as well. (*nix only)


out = `ourlinuxcmd 2&#62;&#38;1`



the 2>&#038;1 bit tells the shell to redirect stderr to stdout
Bookmark to:
]]></description>
			<content:encoded><![CDATA[<p>I was writing a ruby script today that ran a linux command for every line in a file. The problem was the backtick operator in ruby only captures stdout, here's a little trick to get <strong>stderr</strong> as well. (<em>*nix only</em>)</p>
<div class="syntax_hilite">
<div id="ruby-30">
<div class="ruby">out = <span style="color:#996600;">`ourlinuxcmd 2&gt;&amp;1`</span></div>
</div>
</div>
<p></p>
<p>the 2>&#038;1 bit tells the shell to redirect <strong>stderr</strong> to <strong>stdout</strong></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/&amp;title=Capturing+STDERR+with+ruby+backticks" title="Add 'Capturing STDERR with ruby backticks' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Capturing STDERR with ruby backticks' to Del.icio.us" alt="Add 'Capturing STDERR with ruby backticks' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/&amp;title=Capturing+STDERR+with+ruby+backticks" title="Add 'Capturing STDERR with ruby backticks' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Capturing STDERR with ruby backticks' to digg" alt="Add 'Capturing STDERR with ruby backticks' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Capturing+STDERR+with+ruby+backticks&amp;u=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/" title="Add 'Capturing STDERR with ruby backticks' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Capturing STDERR with ruby backticks' to FURL" alt="Add 'Capturing STDERR with ruby backticks' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/&amp;title=Capturing+STDERR+with+ruby+backticks" title="Add 'Capturing STDERR with ruby backticks' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Capturing STDERR with ruby backticks' to reddit" alt="Add 'Capturing STDERR with ruby backticks' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/" title="Add 'Capturing STDERR with ruby backticks' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Capturing STDERR with ruby backticks' to Technorati" alt="Add 'Capturing STDERR with ruby backticks' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/&amp;title=Capturing+STDERR+with+ruby+backticks" title="Add 'Capturing STDERR with ruby backticks' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Capturing STDERR with ruby backticks' to Google Bookmarks" alt="Add 'Capturing STDERR with ruby backticks' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2007/09/14/capturing-stderr-with-ruby-backticks/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Running rails with mongrel for a specific sub directory</title>
		<link>http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/</link>
		<comments>http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 13:20:54 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tip]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/</guid>
		<description><![CDATA[I've started using mongrel for running rails apps with apache2 and mod_proxy , it works like a charm and allows you to run multiple rails apps and mongrel instances on one server.
Your proxy setup looks like this in your httpd.conf or vhost.conf


&#60;VirtualHost *:80&#62;
&#160; &#160; ServerName myapp.com
&#160; &#160; ServerAlias www.myapp.com
&#160; &#160; ProxyPass /myapp http://www.myapp.com:8000/
&#160; &#160; ProxyPassReverse [...]]]></description>
			<content:encoded><![CDATA[<p>I've started using <a href="http://mongrel.rubyforge.org/index.html">mongrel</a> for running rails apps with apache2 and mod_proxy , it works like a charm and allows you to run multiple rails apps and mongrel instances on one server.</p>
<p>Your proxy setup looks like this in your httpd.conf or vhost.conf</p>
<div class="syntax_hilite">
<div id="code-33">
<div class="code">&lt;VirtualHost *:<span style="color:#800000;">80</span>&gt;<br />
&nbsp; &nbsp; ServerName myapp.<span style="">com</span><br />
&nbsp; &nbsp; ServerAlias www.<span style="">myapp</span>.<span style="">com</span></p>
<p>&nbsp; &nbsp; ProxyPass /myapp http:<span style="color:#FF9933; font-style:italic;">//www.myapp.com:8000/</span><br />
&nbsp; &nbsp; ProxyPassReverse /myapp http:<span style="color:#FF9933; font-style:italic;">//www.myapp.com:8000</span><br />
&nbsp; &nbsp; ProxyPreserveHost on<br />
&nbsp; &lt;/VirtualHost&gt;</div>
</div>
</div>
<p></p>
<p>Then in your environment.rb add:</p>
<div class="syntax_hilite">
<div id="ruby-34">
<div class="ruby">ActionController::AbstractRequest.<span style="color:#9900CC;">relative_url_root</span> = '/myapp'</div>
</div>
</div>
<p></p>
<p>This will make ActionController rewrite the proper URL for your rails application.</p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/&amp;title=Running+rails+with+mongrel+for+a+specific+sub+directory" title="Add 'Running rails with mongrel for a specific sub directory' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Running rails with mongrel for a specific sub directory' to Del.icio.us" alt="Add 'Running rails with mongrel for a specific sub directory' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/&amp;title=Running+rails+with+mongrel+for+a+specific+sub+directory" title="Add 'Running rails with mongrel for a specific sub directory' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Running rails with mongrel for a specific sub directory' to digg" alt="Add 'Running rails with mongrel for a specific sub directory' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Running+rails+with+mongrel+for+a+specific+sub+directory&amp;u=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/" title="Add 'Running rails with mongrel for a specific sub directory' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Running rails with mongrel for a specific sub directory' to FURL" alt="Add 'Running rails with mongrel for a specific sub directory' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/&amp;title=Running+rails+with+mongrel+for+a+specific+sub+directory" title="Add 'Running rails with mongrel for a specific sub directory' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Running rails with mongrel for a specific sub directory' to reddit" alt="Add 'Running rails with mongrel for a specific sub directory' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/" title="Add 'Running rails with mongrel for a specific sub directory' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Running rails with mongrel for a specific sub directory' to Technorati" alt="Add 'Running rails with mongrel for a specific sub directory' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/&amp;title=Running+rails+with+mongrel+for+a+specific+sub+directory" title="Add 'Running rails with mongrel for a specific sub directory' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Running rails with mongrel for a specific sub directory' to Google Bookmarks" alt="Add 'Running rails with mongrel for a specific sub directory' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2007/09/10/running-rails-with-mongrel-for-a-specific-sub-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scraping IMDB with Ruby and Hpricot</title>
		<link>http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/</link>
		<comments>http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/#comments</comments>
		<pubDate>Tue, 03 Apr 2007 17:11:24 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/</guid>
		<description><![CDATA[One service that cries for a nice web service interface is IMDB, however they like want $$ or something for it...the nerve!
With just a few lines of ruby we can query to our heart's content. In this post I'll go over how to create a very simple class for extracting information about movies from IMDB [...]]]></description>
			<content:encoded><![CDATA[<p>One service that cries for a nice web service interface is IMDB, however they like want $$ or something for it...the nerve!</p>
<p>With just a few lines of ruby we can query to our heart's content. In this post I'll go over how to create a very simple class for extracting information about movies from IMDB using the lovely <a href="http://code.whytheluckystiff.net/hpricot/">Hpricot</a> library.<br />
<span id="more-15"></span></p>
<h3>Prerequisites</h3>
<p>Downoad and Install Hpricot<br />
That's it!</p>
<h3>The Class</h3>
<p>So let's think of what information we want to grab.</p>
<p>I think we need the title of the movie, the rating, and all the other junk - genre,plot outline, etc.</p>
<p>So we'll create an IMDB class that takes a IMDB url as input and can then give us all that other information.</p>
<p>So the beginning of our class looks like this</p>
<div class="syntax_hilite">
<div id="ruby-45">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> IMDB<br />
<span style="color:#CC0066; font-weight:bold;">require</span> 'hpricot'<br />
<span style="color:#CC0066; font-weight:bold;">require</span> 'open-uri'</p>
<p><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; @url = url;<br />
&nbsp; @hp = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@url<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<h3>The Title</h3>
<p>Now let's build our first method to grab the title. So I'll pull up my favorite movie, Lost In Translation, and take a look at the source code.</p>
<p>Here's the bit I'm looking for</p>
<div class="syntax_hilite">
<div id="html-46">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/meta.html"><span style="color: #000000; font-weight: bold;">&lt;meta</span></a> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">"title"</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">"Lost in Translation (2003)"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span></div>
</div>
</div>
<p></p>
<p>So we need to search for a meta tag that has a name attribute of title and extract the contents of the 'content' attribute. Hpricot <a href="http://code.whytheluckystiff.net/hpricot/wiki/HpricotXpathSearch">uses the XPath query language</a> or a <a href="http://code.whytheluckystiff.net/hpricot/wiki/HpricotCssSearch">CSS selector based</a> query language to allow us to quickly get to the data we want. Since this has a condition in it, we'll use XPath ,the first step in getting this data is determining what sort of XPath query we need to write.</p>
<p>Here's what we have for our title method</p>
<div class="syntax_hilite">
<div id="ruby-47">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span>&nbsp; title<br />
&nbsp; &nbsp;@title = @hp.<span style="color:#9900CC;">at</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">"meta[@name='title']"</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>'content'<span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p>
We use our @hp instance variable which is a Hpricot object, and tell it to return the first element with a tag of meta and an attribute that matches title, then give us the value of the content attribute.</p>
<h3>The Ranking</h3>
<p>Looking at the source for the rating, I see it's in a div named rating. So we'll simply search for that div, then use a regular expression to extract the number value out of it!</p>
<p>Here's the html</p>
<div class="syntax_hilite">
<div id="html-48">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"general rating"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"starbar static"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"outer"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"inner"</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">"width: 158px"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/b.html"><span style="color: #000000; font-weight: bold;">&lt;b&gt;</span></a></span>User Rating:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/b&gt;</span></span> <br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/b.html"><span style="color: #000000; font-weight: bold;">&lt;b&gt;</span></a></span>7.9/10<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/b&gt;</span></span> <br />
&nbsp; <span style="color: #009900;"><a href="http://december.com/html/4/element/small.html"><span style="color: #000000; font-weight: bold;">&lt;small&gt;</span></a></span>(<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"ratings"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>74,513 votes<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span>)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/small&gt;</span></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"bottom"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"ratings"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
</div>
<p></p>
<div class="syntax_hilite">
<div id="ruby-49">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> rating<br />
&nbsp; &nbsp; rating_text = <span style="color:#006600; font-weight:bold;">&#40;</span>@hp/<span style="color:#996600;">"div.rating/b"</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">inner_text</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> rating_text =~ /<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;">&#41;</span>\/<span style="color:#006666;">10</span>/<br />
&nbsp; &nbsp; &nbsp; @rating = $<span style="color:#006666;">1</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; @rating<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p>
Looking closer we have the CSS query of "div.rating/b", in english that says find a bold tag in a d iv tag with the class name rating. The "/" operator we're  using on @hp is a shortcut for the search method, it returns an Hprcot::Element, on the element it returns we call inner_text which returns the text of that element stripped of all html tags.</p>
<p>I then run the text through a regular expression to extract the rating out of 10 points.</p>
<h3>The Rest</h3>
<p>The rest of the main information about the movie is contained in these div's with class name info, as seen in the html here</p>
<div class="syntax_hilite">
<div id="html-50">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Release Date:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span> <br />
3 October 2003 (USA)<br />
&nbsp;<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/releasedates/title/tt0335266/releaseinfo"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p>&nbsp;<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">"margin-left: 1em"</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/trailers/title/tt0335266/trailers-screenplay-E19136-10-2"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>view trailer<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Genre:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/Sections/Genres/Comedy/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Comedy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span> / <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/Sections/Genres/Drama/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Drama<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span> / <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/Sections/Genres/Romance/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Romance<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span> <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/keywords/title/tt0335266/keywords"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Tagline:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span><br />
Everyone wants to be found. <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/taglines/title/tt0335266/taglines"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Plot Outline:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span> <br />
A movie star with a sense of emptiness, and a neglected newlywed meet up as strangers in Tokyo, Japan and form an unlikely bond. <span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/plotsummary/title/tt0335266/plotsummary"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Plot Keywords:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/keyword/lyrical/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Lyrical<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
&nbsp;/ <br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/keyword/reflection/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Reflection<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
&nbsp;/ <br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/keyword/psychological-drama/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Psychological<span style="color: #ddbb00;">&amp;#160;</span>Drama<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
&nbsp;/ </p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/keyword/loneliness/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Loneliness<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
&nbsp;/ <br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/keyword/advertising/"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>Advertising<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/keywords/title/tt0335266/keywords"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span></p>
<p><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></p>
<p><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"info"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/h5.html"><span style="color: #000000; font-weight: bold;">&lt;h5&gt;</span></a></span>Awards:<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h5&gt;</span></span> <br />
Won Oscar.<br />
&nbsp;Another 67 wins<br />
<span style="color: #ddbb00;">&amp;amp;</span></p>
<p>50 nominations<br />
<span style="color: #009900;"><a href="http://december.com/html/4/element/a.html"><span style="color: #000000; font-weight: bold;">&lt;a</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"tn15more inline"</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">"/rg/title-tease/awards/title/tt0335266/awards"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span>more<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/a&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
</div>
<p></p>
<p>We could extract each piece in it's own separate method, but I'm lazy so I think I'll just create one method called extrainfo that returns a hash of all the extra information back.</p>
<div class="syntax_hilite">
<div id="ruby-51">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> extrainfo<br />
&nbsp;<span style="color:#9966CC; font-weight:bold;">if</span> @extrainfo == <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#008000; font-style:italic;">#don't do it twice</span><br />
&nbsp; &nbsp; @extrainfo = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#008000; font-style:italic;">#init our hash</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span>@hp/<span style="color:#996600;">"div.info"</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |inf| <span style="color:#008000; font-style:italic;">#go through each info div</span><br />
&nbsp; &nbsp; &nbsp; title = inf/<span style="color:#996600;">"h5"</span> <span style="color:#008000; font-style:italic;">#the type of infobox is stored in h5</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> title.<span style="color:#9900CC;">any</span>? <span style="color:#008000; font-style:italic;">#if we found one , we got data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body = inf.<span style="color:#9900CC;">inner_text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body = body.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/\n/,''<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#remove newlines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> body =~ /\:<span style="color:#006600; font-weight:bold;">&#40;</span>.+<span style="color:#006600; font-weight:bold;">&#41;</span>/ <span style="color:#008000; font-style:italic;">#extract body from our text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body = $<span style="color:#006666;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @extrainfo<span style="color:#006600; font-weight:bold;">&#91;</span>title.<span style="color:#9900CC;">inner_text</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><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>.<span style="color:#9900CC;">downcase</span><span style="color:#006600; font-weight:bold;">&#93;</span> = body <span style="color:#008000; font-style:italic;">#store the body</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</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 />
&nbsp; &nbsp; @extrainfo<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<p>So our first query "div.info" is a CSS based query, it searches for all div boxes with a class of info. Now, we've got to find a way to extract the title to use as a key in the hash, and the rest of the body will be the value of the hash.</p>
<p>Examining the info div's closer I see the title is always stored in an h5 tag, so what we'll do is for each info div we'll grab the first h5 tag from that div. Hpricot allows you to nest queries, so the results of our first search is also searchable, and so on. So we can search each of our inf variables for all h5 tags, once we find one we simply do a little bit of regular expression magic to separate the body from the title, then store that information in the @extrainformation hash.</p>
<h3>All Done</h3>
<p>So our finished class now looks like this:</p>
<div class="syntax_hilite">
<div id="ruby-52">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> IMDB<br />
<span style="color:#008000; font-style:italic;">#uncomment the next line if you installed hpricot from the gem</span><br />
<span style="color:#008000; font-style:italic;">#require 'rubygems'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> 'hpricot'<br />
<span style="color:#CC0066; font-weight:bold;">require</span> 'open-uri'</p>
<p><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; @url = url;<br />
&nbsp; @hp = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@url<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span>&nbsp; title<br />
&nbsp; &nbsp;@title = @hp.<span style="color:#9900CC;">at</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">"meta[@name='title']"</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>'content'<span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span> rating<br />
&nbsp; &nbsp; rating_text = <span style="color:#006600; font-weight:bold;">&#40;</span>@hp/<span style="color:#996600;">"div.rating/b"</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">inner_text</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> rating_text =~ /<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;">&#41;</span>\/<span style="color:#006666;">10</span>/<br />
&nbsp; &nbsp; &nbsp; @rating = $<span style="color:#006666;">1</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; @rating<br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">def</span> extrainfo<br />
&nbsp;<span style="color:#9966CC; font-weight:bold;">if</span> @extrainfo == <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#008000; font-style:italic;">#don't do it twice</span><br />
&nbsp; &nbsp; @extrainfo = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#008000; font-style:italic;">#init our hash</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#40;</span>@hp/<span style="color:#996600;">"div.info"</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |inf| <span style="color:#008000; font-style:italic;">#go through each info div</span><br />
&nbsp; &nbsp; &nbsp; title = inf/<span style="color:#996600;">"h5"</span> <span style="color:#008000; font-style:italic;">#the type of infobox is stored in h5</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> title.<span style="color:#9900CC;">any</span>? <span style="color:#008000; font-style:italic;">#if we found one , we got data</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body = inf.<span style="color:#9900CC;">inner_text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; body = body.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span>/\n/,''<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#remove newlines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> body =~ /\:<span style="color:#006600; font-weight:bold;">&#40;</span>.+<span style="color:#006600; font-weight:bold;">&#41;</span>/ <span style="color:#008000; font-style:italic;">#extract body from our text</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; body = $<span style="color:#006666;">1</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @extrainfo<span style="color:#006600; font-weight:bold;">&#91;</span>title.<span style="color:#9900CC;">inner_text</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><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>.<span style="color:#9900CC;">downcase</span><span style="color:#006600; font-weight:bold;">&#93;</span> = body <span style="color:#008000; font-style:italic;">#store the body</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</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 />
&nbsp; &nbsp; @extrainfo<br />
<span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">def</span> reset<br />
&nbsp; @rating = <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; @extrainfo = <span style="color:#0000FF; font-weight:bold;">nil</span><br />
<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>You could certainly get much more advanced in your IMDB scraper class, but the above should get you started. Here's a quick test script to see how our class worked.</p>
<div class="syntax_hilite">
<div id="ruby-53">
<div class="ruby"><span style="color:#CC0066; font-weight:bold;">require</span> 'IMDB'</p>
<p>imdb = IMDB.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>'http://imdb.<span style="color:#9900CC;">com</span>/title/tt0335266/'<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p><span style="color:#CC0066; font-weight:bold;">p</span> imdb.<span style="color:#9900CC;">rating</span><br />
<span style="color:#CC0066; font-weight:bold;">p</span> imdb.<span style="color:#9900CC;">title</span><br />
<span style="color:#CC0066; font-weight:bold;">p</span> imdb.<span style="color:#9900CC;">extrainfo</span></div>
</div>
</div>
<p></p>
<p>So running this script gives us the output</p>
<div class="syntax_hilite">
<div id="code-54">
<div class="code"><span style="color:#800000;">7</span>.9<span style="color:#CC0000;">"<br />
"</span>Lost in Translation <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">2003</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#CC0000;">"<br />
{"</span>company<span style="color:#CC0000;">"=&gt;"</span>American Zoetropemore<span style="color:#CC0000;">", "</span>quotes<span style="color:#CC0000;">"=&gt;"</span>Bob:I don<span style="color:#CC0000;">'t get that close to the glass until I'</span>m on the floor.<span style="">more</span><span style="color:#CC0000;">", "</span>director<span style="color:#CC0000;">"=&gt;"</span>Sofia Coppola<span style="color:#CC0000;">", "</span>goofs<span style="color:#CC0000;">"=&gt;"</span>Continuity: The pink flowers in Charlotte<span style="color:#CC0000;">'s room disappear when she is listening to the &amp;#34;soul searching&amp;#34; tape, but reappear later in the movie.more&quot;, &quot;language&quot;=&gt;&quot;English / Japanese / German / French&quot;, &quot;usercomments&quot;=&gt;&quot;breath takingmore&quot;, &quot;moviemeter&quot;=&gt;&quot;&nbsp; 35% since last weekwhy?&quot;, &quot;mpaa&quot;=&gt;&quot; Rated R for some sexual content.&quot;, &quot;filminglocations&quot;=&gt;&quot; Japanmore&quot;, &quot;certification&quot;=&gt;&quot;Indonesia:Dewasa&nbsp; / Malaysia:18PL (re-rating) / Malaysia:(Banned) (uncut version) / Iceland:L&nbsp; / Canada:PG (British Columbia/Manitoba/Nova Scotia/Ontario) / Hungary:14&nbsp; / Argentina:13&nbsp; / Australia:PG&nbsp; / Brazil:14&nbsp; / Canada:14A (Alberta) / Canada:G (Qu&amp;#233;bec) / Chile:TE&nbsp; / Finland:K-11&nbsp; / Germany:6 (bw) / Hong Kong:IIB&nbsp; / Italy:T&nbsp; / Netherlands:AL&nbsp; / New Zealand:PG&nbsp; / Norway:A&nbsp; / Peru:PT&nbsp; / Philippines:PG-13&nbsp; / Portugal:M/12&nbsp; / Singapore:PG (edited for re-rating) / Singapore:R(A) (original rating) / South Korea:15&nbsp; / Spain:13&nbsp; / Sweden:Btl&nbsp; / Switzerland:12 (canton of the Grisons) / UK:15&nbsp; / USA:R&nbsp; / Singapore:M18 (DVD rating)&quot;, &quot;country&quot;=&gt;&quot;USA / Japan&quot;, &quot;awards&quot;=&gt;&quot; Won Oscar. Another 67 wins&amp;amp;50 nominationsmore&quot;, &quot;plotkeywords&quot;=&gt;&quot;Lyrical / Reflection / Psychological&amp;#160;Drama / Loneliness / Advertisingmore&quot;, &quot;plotoutline&quot;=&gt;&quot; A movie star with a sense of emptiness, and a neglected newlywed meet up as strangers in Tokyo, Japan and form an unlikely bond. more&quot;, &quot;soundtrack&quot;=&gt;&quot; She Gets Aroundmore&quot;, &quot;soundmix&quot;=&gt;&quot;Dolby Digital &quot;, &quot;runtime&quot;=&gt;&quot;102 min &quot;, &quot;writer(wga)&quot;=&gt;&quot;Sofia Coppola (written by)&quot;, &quot;trivia&quot;=&gt;&quot;In 1999, Bill Murray replaced his talent agency with an automated voice mailbox that can be reached with an 800 number he gives out sparingly. Sofia Coppola reportedly left hundreds of messages on Murray'</span>s mailbox before he finally called back to discuss her offer to cast him as the star.<span style="">more</span><span style="color:#CC0000;">", "</span>color<span style="color:#CC0000;">"=&gt;"</span>Color <span style="color:#CC0000;">", "</span>tagline<span style="color:#CC0000;">"=&gt;"</span>Everyone wants to be found. <span style="">more</span><span style="color:#CC0000;">", "</span>genre<span style="color:#CC0000;">"=&gt;"</span>Comedy / Drama / Romance more<span style="color:#CC0000;">", "</span>aspectratio<span style="color:#CC0000;">"=&gt;"</span><span style="color:#800000;">1</span>.<span style="color:#800000;">85</span> : <span style="color:#800000;">1</span> more<span style="color:#CC0000;">", "</span>movieconnections<span style="color:#CC0000;">"=&gt;"</span> Featured in The <span style="color:#800000;">2004</span> IFP/West Independent Spirit Awards <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">2004</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#40;</span>TV<span style="color:#006600; font-weight:bold;">&#41;</span>more<span style="color:#CC0000;">", "</span>releasedate<span style="color:#CC0000;">"=&gt;"</span> <span style="color:#800000;">3</span> October <span style="color:#800000;">2003</span> <span style="color:#006600; font-weight:bold;">&#40;</span>USA<span style="color:#006600; font-weight:bold;">&#41;</span> more view trailer<span style="color:#CC0000;">"} </span></div>
</div>
</div>
<p></p>
<h3>More Information</h3>
<p><a href="http://code.whytheluckystiff.net/hpricot/wiki/AnHpricotShowcase">Hpricot Showcase</a><br/><br />
<a href="http://code.whytheluckystiff.net/doc/hpricot/">Hpricot API Documentation</a></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/&amp;title=Scraping+IMDB+with+Ruby+and+Hpricot" title="Add 'Scraping IMDB with Ruby and Hpricot' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to Del.icio.us" alt="Add 'Scraping IMDB with Ruby and Hpricot' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/&amp;title=Scraping+IMDB+with+Ruby+and+Hpricot" title="Add 'Scraping IMDB with Ruby and Hpricot' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to digg" alt="Add 'Scraping IMDB with Ruby and Hpricot' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Scraping+IMDB+with+Ruby+and+Hpricot&amp;u=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/" title="Add 'Scraping IMDB with Ruby and Hpricot' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to FURL" alt="Add 'Scraping IMDB with Ruby and Hpricot' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/&amp;title=Scraping+IMDB+with+Ruby+and+Hpricot" title="Add 'Scraping IMDB with Ruby and Hpricot' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to reddit" alt="Add 'Scraping IMDB with Ruby and Hpricot' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/" title="Add 'Scraping IMDB with Ruby and Hpricot' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to Technorati" alt="Add 'Scraping IMDB with Ruby and Hpricot' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/&amp;title=Scraping+IMDB+with+Ruby+and+Hpricot" title="Add 'Scraping IMDB with Ruby and Hpricot' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Scraping IMDB with Ruby and Hpricot' to Google Bookmarks" alt="Add 'Scraping IMDB with Ruby and Hpricot' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2007/04/03/scraping-imdb-with-ruby-and-hpricot/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Importing an MS Project Plan into Basecamp using Ruby</title>
		<link>http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/</link>
		<comments>http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/#comments</comments>
		<pubDate>Wed, 20 Dec 2006 15:18:23 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[ruby]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/</guid>
		<description><![CDATA[Basecamp is a web based project management tool. It's just fun to use. Microsoft Project....not so much.
That being said MS Project does a whole lot of stuff that Basecamp doesn't. Being leet web 2.0 doods we want to use Basecamp! Of course MS Project is the standard that most clients like to see, so we're [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.basecamphq.com">Basecamp</a> is a web based project management tool. It's just fun to use. Microsoft Project....not so much.<br />
That being said MS Project does a whole lot of stuff that Basecamp doesn't. Being leet web 2.0 doods we want to use Basecamp! Of course MS Project is the standard that most clients like to see, so we're kind of stuck.</p>
<p>So why not the best of both worlds, MS Project and Basecamp without having to retype everything into Basecamp!</p>
<p>With a bit of ruby and the help of the Basecamp API we can save a lot of time.<br />
<span id="more-13"></span></p>
<h3>Introduction</h3>
<p>MS Project gives us tons of different ways to organize our project, Basecamp has only a few simple ways so our mapping can't really be one to one. Basecamp offers the following concepts: Milestones, To-Do Lists (made up of items, may be linked to a milestone). </p>
<p>Here is the basic strategy I used for <strong>my</strong> project plan.</p>
<p>MS Project Milestone = Basecamp Milestone<br />
MS Project Tasks under Milestone = Basecamp to-do list  linked to milestone.</p>
<p>So our script simply loops through the project, when it hits a milestone we create a milestone, we collect all the tasks into a list until we hit the next milestone and the cycle begins again. So we end up with one whole to-do list per milestone.</p>
<p>Prerequisites:</p>
<ul>
<li><strong>Activate the Basecamp API for your project</strong> in your Account Settings (the same page where you would go to upgrade your account to pro). If you don't do this you'll see the script complain with 404 errors</li>
<li><a href="http://www.basecamphq.com/api/basecamp.rb">Download the ruby Basecamp API Wrapper</a>. Put this in the same directory as your script.
</li>
<li>Install the xml-simple gem.</li>
</ul>
<h3>Exporting from MS Project</h3>
<p>MS Project has a very nice export wizard. It allows you to export to a CSV file and specify filters and fields.</p>
<p>To access the export wizard, open up your project plan and choose File->Save As, for the 'Save as type' choose CSV (Comma delimited) (*.csv).</p>
<p>When prompted by the wizard to create or choose an export map, choose New map and click next, in the next dialog box choose Tasks as the type of data to export, uncheck 'Export includes headers', make sure our text delimiter is comma and click Next.</p>
<p>Now it's time to create our map, this is where we tell Project what columns to put in our CSV file.</p>
<p>For this script I just want the following data: [task name],[baseline finish date],[milestone].</p>
<p>So choose those three options, here's how mine looks:<br />
<img src="/export_wiz_ss.jpg"></p>
<p>Click Next, you can save the map for later if you want to do this again.</p>
<p>Another wrinkle, I like the following date format in MS Project: Tues 11/06/06 (Day MM/YY/DD). If you don't like it, no biggie you just have to figure out how to turn your preferred date format into YYYY-MM-DD later on in the script. I hope you like regex's!</p>
<h3>The Script</h3>
<p>Now it's time to write our script, so let's review what it should do:</p>
<p>Login to Basecamp<br />
Select our project<br />
Loop through our CSV<br />
Create a collection that looks like this: Milestone->Task List<br />
Insert milestones and task lists into basecamp!</p>
<p><strong>Disclaimer</strong>: I have the ruby programming skills of a 4 year old girl, I know this. I do not claim to be an expert ruby ninja, feel free to improve the script.</p>
<p>Here is the <a href="http://www.weheartcode.com/import_msproject.rb">script</a>, so place this in the same directory as your csv file and the <a href="http://www.basecamphq.com/api/basecamp.rb"> basecamp.rb</a> file from 37 Signals.</p>
<div class="syntax_hilite">
<div id="ruby-58">
<div class="ruby"><span style="color:#008000; font-style:italic;">#!/usr/bin/ruby</span></p>
<p><span style="color:#008000; font-style:italic;">#Script by weheartcode.com, modify however you like.</span><br />
<span style="color:#008000; font-style:italic;">#WARNING THIS SCRIPT CAN HOSE YOUR BASECAMP ACCOUNT</span><br />
<span style="color:#008000; font-style:italic;">#Don't be stupid, try it on a test account first</span></p>
<p><span style="color:#CC0066; font-weight:bold;">require</span> 'basecamp'</p>
<p>
<span style="color:#008000; font-style:italic;">#Fill in these variables, PLEASE TRY ON TEST ACCOUNT FIRST</span><br />
basecampurl = 'YOURBASECAMPURL' <span style="color:#008000; font-style:italic;">#Ex. weheartcode.grouphub.com</span></p>
<p>basecampuser = 'CHANGEME'<br />
basecamppass = 'CHANGEME'</p>
<p>msprojcsvfile = 'CHANGEME' <span style="color:#008000; font-style:italic;">#Ex. export.csv</span></p>
<p><span style="color:#008000; font-style:italic;">#Connect to basecamp using the Basecamp API Ruby Wrapper</span><br />
session = Basecamp.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>basecampurl,basecampuser,basecamppass<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p>
<span style="color:#008000; font-style:italic;">#Assume we're working on the first project</span><br />
project = session.<span style="color:#9900CC;">projects</span>.<span style="color:#9900CC;">first</span></p>
<p>milestones = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span></p>
<p><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Creating data structure..."</span></p>
<p><span style="color:#008000; font-style:italic;">#Read our file line by line</span><br />
<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>msprojcsvfile<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#123;</span>|f|<br />
&nbsp; f.<span style="color:#9900CC;">each_line</span> <span style="color:#006600; font-weight:bold;">&#123;</span>|line|<br />
&nbsp; data = line.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span>','<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; milestone = Hash.<span style="color:#9900CC;">new</span></p>
<p>&nbsp; ismile = data<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span></p>
<p>&nbsp; <span style="color:#008000; font-style:italic;">#if we just hit a milestone, create one and add it to our Array</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> 'Yes' == ismile.<span style="color:#9900CC;">strip</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#reconbobulate date for deadline</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;">#Expecting Day dd/mm/yyyy format (ex. Tues 12/25/2006)</span><br />
&nbsp; &nbsp; &nbsp;m1 = /.+\s<span style="color:#006600; font-weight:bold;">&#40;</span>\d+?<span style="color:#006600; font-weight:bold;">&#41;</span>\/<span style="color:#006600; font-weight:bold;">&#40;</span>\d+?<span style="color:#006600; font-weight:bold;">&#41;</span>\/<span style="color:#006600; font-weight:bold;">&#40;</span>\d+<span style="color:#006600; font-weight:bold;">&#41;</span>/.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">strip</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp;deadline = <span style="color:#996600;">"20"</span> + m1<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#93;</span> + <span style="color:#996600;">"-"</span> + m1<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> + <span style="color:#996600;">"-"</span> + m1<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span></p>
<p>&nbsp; &nbsp; &nbsp; milestone<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"title"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = data<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; milestone<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"deadline"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = deadline<br />
&nbsp; &nbsp; &nbsp; milestone<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"thelist"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#CC0066; font-weight:bold;">Array</span>.<span style="color:#9900CC;">new</span><br />
&nbsp; &nbsp; &nbsp; milestones &lt;&lt;milestone<br />
&nbsp; <span style="color:#008000; font-style:italic;">#otherwise, we just have a normal task</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;">#Add task to current milestone list array</span><br />
&nbsp; &nbsp; &nbsp;milestones.<span style="color:#9900CC;">last</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"thelist"</span><span style="color:#006600; font-weight:bold;">&#93;</span> &lt;&lt;data<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp;<span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#008000; font-style:italic;">#Reverse our milestone list, so that the to-do's show up oldest first</span><br />
milestones.<span style="color:#9900CC;">reverse</span></p>
<p><span style="color:#008000; font-style:italic;">#Let's go through each milestone and add to basecamp</span><br />
milestones.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span> |m|</p>
<p><span style="color:#008000; font-style:italic;">#Get a copy of our todo list</span><br />
tasklist = m<span style="color:#006600; font-weight:bold;">&#91;</span>'thelist'<span style="color:#006600; font-weight:bold;">&#93;</span></p>
<p><span style="color:#008000; font-style:italic;">#Nil out key so we dont send to basecamp API</span><br />
m<span style="color:#006600; font-weight:bold;">&#91;</span>'thelist'<span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">nil</span></p>
<p><span style="color:#008000; font-style:italic;">#Create a milestone with our project id</span><br />
<span style="color:#008000; font-style:italic;">#Uaing the data from our milestone hash</span><br />
session.<span style="color:#9900CC;">create_milestone</span><span style="color:#006600; font-weight:bold;">&#40;</span>project.<span style="color:#9900CC;">id</span>,m<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Milestone created."</span></p>
<p><span style="color:#008000; font-style:italic;">#Grab an instance of the milestone we just created</span><br />
themile = session.<span style="color:#9900CC;">milestones</span><span style="color:#006600; font-weight:bold;">&#40;</span>project.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">last</span></p>
<p><span style="color:#008000; font-style:italic;">#create a to-do list for milestone</span><br />
tmplist = Hash.<span style="color:#9900CC;">new</span><br />
tmplist<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"tracked"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">false</span>;</p>
<p><span style="color:#008000; font-style:italic;">#Use milestone title prefixed with M-LISt for list title</span><br />
tmplist<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"name"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">"M-LIST: "</span> + m<span style="color:#006600; font-weight:bold;">&#91;</span>'title'<span style="color:#006600; font-weight:bold;">&#93;</span><br />
tmplist<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"description"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">"Task list for milestone."</span><br />
tmplist<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">"milestone-id"</span><span style="color:#006600; font-weight:bold;">&#93;</span> = themile.<span style="color:#9900CC;">id</span></p>
<p>
<span style="color:#008000; font-style:italic;">#Create the list with Basecamp API</span><br />
session.<span style="color:#9900CC;">create_list</span><span style="color:#006600; font-weight:bold;">&#40;</span>project.<span style="color:#9900CC;">id</span>,tmplist<span style="color:#006600; font-weight:bold;">&#41;</span></p>
<p><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"Milestone list created."</span></p>
<p>thelist = session.<span style="color:#9900CC;">lists</span><span style="color:#006600; font-weight:bold;">&#40;</span>project.<span style="color:#9900CC;">id</span>,<span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">last</span></p>
<p><span style="color:#008000; font-style:italic;">#Create items underneath our list</span><br />
tasklist.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span>|task| session.<span style="color:#9900CC;">create_item</span><span style="color:#006600; font-weight:bold;">&#40;</span>thelist.<span style="color:#9900CC;">id</span>,task<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></p>
<p><span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">"All done!"</span></div>
</div>
</div>
<p></p>
<p>Upload the ruby script to your hosting provider (I use <a href="http://www.dreamhost.com/r.cgi?106427">dreamhost</a>) or place in the directory on your local box.</p>
<p>Make sure you have your csv file from MS project and the basecamp library from 37 signals in the same directory and the xml-simple gem installed.</p>
<p>So, we simple change the variables for the basecamp URL, username, pass, filename and run the ruby script using our favorite editor and prepare to run the script.</p>
<p><strong>For the love of god, please make sure you try this on a test account before you do it for the first time on your actual account, the results could be unexpected.</strong></p>
<div class="syntax_hilite">
<div id="code-59">
<div class="code">ruby import_basecamp.<span style="">rb</span></div>
</div>
</div>
<p></p>
<p>If all goes well you will see the script do it's thing like this.</p>
<div class="syntax_hilite">
<div id="code-60">
<div class="code">Milestone list created.<br />
<span style="">Creating</span> Item for list_id: <span style="color:#800000;">1483337</span><br />
Creating Item for list_id: <span style="color:#800000;">1483337</span><br />
Creating Item for list_id: <span style="color:#800000;">1483337</span><br />
Creating Item for list_id: <span style="color:#800000;">1483337</span><br />
.<br />
.<br />
.<br />
<span style="">All</span> done!</div>
</div>
</div>
<p></p>
<p>If you get 404 errors, please check to make sure you have the correct URL, that you have a project created in your account, and that you have <strong>activated the basecamp API</strong> in the Account tab of your basecamp account.</p>
<p>This is a very simple example, depending on how complex your MS Project Plan you may want to omit the task part all together, or modify how you name tasks/milestones. Either way it sure beats entering it all by hand.</p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/&amp;title=Importing+an+MS+Project+Plan+into+Basecamp+using+Ruby" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Del.icio.us" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/&amp;title=Importing+an+MS+Project+Plan+into+Basecamp+using+Ruby" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to digg" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Importing+an+MS+Project+Plan+into+Basecamp+using+Ruby&amp;u=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to FURL" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/&amp;title=Importing+an+MS+Project+Plan+into+Basecamp+using+Ruby" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to reddit" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Technorati" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/&amp;title=Importing+an+MS+Project+Plan+into+Basecamp+using+Ruby" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Google Bookmarks" alt="Add 'Importing an MS Project Plan into Basecamp using Ruby' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2006/12/20/importing-an-ms-project-plan-into-basecamp-using-ruby/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Derived Columns in ActiveRecord</title>
		<link>http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/</link>
		<comments>http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/#comments</comments>
		<pubDate>Mon, 16 Oct 2006 23:41:10 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/</guid>
		<description><![CDATA[Sometimes it's useful to have a field in your ActiveRecord implentation that isn't actually selected in your query or present in your table. One way to acheive this is by simply adding a new accessor to your Model class.
Let's say we have a table named Customers that has a firstname and lastname column but we [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it's useful to have a field in your <a href="http://wiki.rubyonrails.com/rails/pages/ActiveRecord">ActiveRecord</a> implentation that isn't actually selected in your query or present in your table. One way to acheive this is by simply adding a new accessor to your Model class.</p>
<p>Let's say we have a table named Customers that has a firstname and lastname column but we would like to also have a fullname column available to us when doing things like iterating through Customer objects in our view. One way is to add it directly to our Customers class ( app/model/customer.rb in your rails app).</p>
<div class="syntax_hilite">
<div id="ruby-62">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> Customer &lt;ActiveRecord::Base<br />
<span style="color:#9966CC; font-weight:bold;">def</span> fullname<br />
&nbsp; &nbsp; @fullname = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">firstname</span> + ' ' + <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">lastname</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/&amp;title=Derived+Columns+in+ActiveRecord" title="Add 'Derived Columns in ActiveRecord' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Derived Columns in ActiveRecord' to Del.icio.us" alt="Add 'Derived Columns in ActiveRecord' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/&amp;title=Derived+Columns+in+ActiveRecord" title="Add 'Derived Columns in ActiveRecord' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Derived Columns in ActiveRecord' to digg" alt="Add 'Derived Columns in ActiveRecord' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Derived+Columns+in+ActiveRecord&amp;u=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/" title="Add 'Derived Columns in ActiveRecord' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Derived Columns in ActiveRecord' to FURL" alt="Add 'Derived Columns in ActiveRecord' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/&amp;title=Derived+Columns+in+ActiveRecord" title="Add 'Derived Columns in ActiveRecord' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Derived Columns in ActiveRecord' to reddit" alt="Add 'Derived Columns in ActiveRecord' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/" title="Add 'Derived Columns in ActiveRecord' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Derived Columns in ActiveRecord' to Technorati" alt="Add 'Derived Columns in ActiveRecord' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/&amp;title=Derived+Columns+in+ActiveRecord" title="Add 'Derived Columns in ActiveRecord' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Derived Columns in ActiveRecord' to Google Bookmarks" alt="Add 'Derived Columns in ActiveRecord' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2006/10/16/derived-columns-in-activerecord/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Randomizing an array in Ruby</title>
		<link>http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/</link>
		<comments>http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/#comments</comments>
		<pubDate>Sat, 07 Oct 2006 03:49:34 +0000</pubDate>
		<dc:creator>Paul</dc:creator>
				<category><![CDATA[arrays]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/</guid>
		<description><![CDATA[Ruby's Array class has no method to randomize the contents of an array.  Of course, Array can easily be extended to include this functionality.  And like anything else in Ruby, there's more than one way to do it.  Here's one way:


class Array
&#160; def randomize
&#160; &#160; arr=self.dup
&#160; &#160; self.collect &#123; arr.slice!&#40;rand&#40;arr.length&#41;&#41; &#125;
&#160; end
&#160; [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby's Array class has no method to randomize the contents of an array.  Of course, Array can easily be extended to include this functionality.  And like anything else in Ruby, there's more than one way to do it.  Here's one way:</p>
<div class="syntax_hilite">
<div id="ruby-64">
<div class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#CC0066; font-weight:bold;">Array</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> randomize<br />
&nbsp; &nbsp; arr=<span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">dup</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> arr.<span style="color:#9900CC;">slice</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>arr.<span style="color:#9900CC;">length</span><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; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> randomize!<br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">replace</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">randomize</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p>&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> random<br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">randomize</span>.<span style="color:#9900CC;">first</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span></p>
<p><span style="color:#9966CC; font-weight:bold;">end</span></div>
</div>
</div>
<p></p>
<!-- Social Bookmarks BEGIN --><div class="social_bookmark"><em>Bookmark to:</em><br /><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://del.icio.us/post?url=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/&amp;title=Randomizing+an+array+in+Ruby" title="Add 'Randomizing an array in Ruby' to Del.icio.us"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/delicious.png" title="Add 'Randomizing an array in Ruby' to Del.icio.us" alt="Add 'Randomizing an array in Ruby' to Del.icio.us" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://digg.com/submit?phase=2&amp;url=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/&amp;title=Randomizing+an+array+in+Ruby" title="Add 'Randomizing an array in Ruby' to digg"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/digg.png" title="Add 'Randomizing an array in Ruby' to digg" alt="Add 'Randomizing an array in Ruby' to digg" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://furl.net/storeIt.jsp?t=Randomizing+an+array+in+Ruby&amp;u=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/" title="Add 'Randomizing an array in Ruby' to FURL"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/furl.png" title="Add 'Randomizing an array in Ruby' to FURL" alt="Add 'Randomizing an array in Ruby' to FURL" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://reddit.com/submit?url=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/&amp;title=Randomizing+an+array+in+Ruby" title="Add 'Randomizing an array in Ruby' to reddit"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/reddit.png" title="Add 'Randomizing an array in Ruby' to reddit" alt="Add 'Randomizing an array in Ruby' to reddit" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.technorati.com/faves?add=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/" title="Add 'Randomizing an array in Ruby' to Technorati"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/technorati.png" title="Add 'Randomizing an array in Ruby' to Technorati" alt="Add 'Randomizing an array in Ruby' to Technorati" /></a><a class="social_img" onclick="window.open(this.href, '_blank', 'scrollbars=yes,menubar=no,height=600,width=750,resizable=yes,toolbar=no,location=no,status=no'); return false;" href="http://www.google.com/bookmarks/mark?op=edit&amp;output=popup&amp;bkmk=http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/&amp;title=Randomizing+an+array+in+Ruby" title="Add 'Randomizing an array in Ruby' to Google Bookmarks"><img src="http://www.weheartcode.com/wp-content/plugins/social_bookmarks/google.png" title="Add 'Randomizing an array in Ruby' to Google Bookmarks" alt="Add 'Randomizing an array in Ruby' to Google Bookmarks" /></a></div>
<!-- Social Bookmarks END -->]]></content:encoded>
			<wfw:commentRss>http://www.weheartcode.com/2006/10/06/randomizing-an-array-in-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
