<?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>Biodegradable Geek &#187; Ruby</title>
	<atom:link href="http://biodegradablegeek.com/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://biodegradablegeek.com</link>
	<description></description>
	<lastBuildDate>Tue, 22 Jun 2010 21:52:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to Maintain Static Sites with Git &amp; Jekyll</title>
		<link>http://biodegradablegeek.com/2009/03/how-to-maintain-static-sites-with-git-jekyll/</link>
		<comments>http://biodegradablegeek.com/2009/03/how-to-maintain-static-sites-with-git-jekyll/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 04:10:00 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=371</guid>
		<description><![CDATA[Static sites in this context just means non-database driven sites. Your static site can be an elaborate PHP script or just a few markup and image files. For this I am using Jekyll &#8211; A neat Ruby gem that makes your static sites dynamic. It lets you create layouts and embed custom variables in your [...]]]></description>
			<content:encoded><![CDATA[<p>Static sites in this context just means non-database driven sites. Your static site can be an elaborate PHP script or just a few markup and image files. For this I am using <strong><a href="http://github.com/mojombo/jekyll/tree/master">Jekyll</a> &#8211; A neat Ruby gem that makes your static sites dynamic.</strong> It lets you create layouts and embed custom variables in your HTML (this is a &#8220;prototype&#8221; of the site). </p>
<p>Jekyll tackles all the nuisances involved in creating static pages (I used to add just enough PHP to make a layout). It works by running your prototype through some parsers and outputs plain static HTML/XML (RSS feeds) etc. It&#8217;s perfect for lightweight sites that would be impractical on Wordpress, like a few static pages of information, landing pages, portfolio/resume pages, and parked domains. </p>
<p>Git takes care of keeping your development (local) and production (remote) environments synced. Git might be a little confusing if you&#8217;re learning it with the mindset that it works like Subversion. </p>
<p><strong>I&#8217;ll update this post when the guide is done. For now, the following will assume you&#8217;re familiar with Jekyll (or at least have an empty file in the prototype directory) and git. This Bash script simplifies creating the remote git repository:</strong></p>
<p>** please read through the code and make sure you know what this does, and what you&#8217;re doing. As of now, this is bias towards my own Apache/vhost setup. It&#8217;s trivial to edit for your specific needs. <strong>You&#8217;re using this at your own risk</strong>.</p>
<p>(<a href="http://code.biodegradablegeek.com/repogen.sh" target="_blank">direct link &#8211; repogen.sh</a>)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># </span>
<span style="color: #666666; font-style: italic;"># 04/01/2009 | http://biodegradablegeek.com | GPL </span>
<span style="color: #666666; font-style: italic;"># </span>
<span style="color: #666666; font-style: italic;"># You should be in site (NOT public) root (be in same dir as public/ log/ etc)</span>
<span style="color: #666666; font-style: italic;"># proto/ is created and will house the jekyll prototype</span>
<span style="color: #666666; font-style: italic;"># public/ will be the generated static site</span>
<span style="color: #666666; font-style: italic;"># the public/ folder will be REMOVED and regenerated on every push</span>
<span style="color: #666666; font-style: italic;"># </span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
  <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Usage: ./repogen.sh domain.comn&quot;</span>
  <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># optional. will make it easier to copy/paste cmd to clone repo </span>
<span style="color: #007800;">SSHURL</span>=<span style="color: #ff0000;">&quot;ssh.domain.com&quot;</span>
<span style="color: #007800;">URL</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** creating tmp repo&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> proto
<span style="color: #7a0874; font-weight: bold;">cd</span> proto
git init 
<span style="color: #c20cb9; font-weight: bold;">touch</span> INITIAL
git add INITIAL
git commit <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Initial Commit&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** creating bare repo&quot;</span>
<span style="color: #7a0874; font-weight: bold;">cd</span> ..
git clone <span style="color: #660033;">--bare</span> proto proto.git
<span style="color: #c20cb9; font-weight: bold;">mv</span> proto proto.old
git clone proto.git
<span style="color: #c20cb9; font-weight: bold;">rm</span> <span style="color: #660033;">-rf</span> proto.old
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** generating hook&quot;</span>
<span style="color: #007800;">HOOK</span>=proto.git<span style="color: #000000; font-weight: bold;">/</span>hooks<span style="color: #000000; font-weight: bold;">/</span>post-update
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #007800;">$HOOK</span> <span style="color: #000000; font-weight: bold;">/</span>tmp
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'#!/bin/sh'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'# To enable this hook, make this file executable by &quot;chmod +x post-update&quot;.'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'#exec git-update-server-info'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'URL='</span><span style="color: #ff0000;">&quot;<span style="color: #007800;">$URL</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'PROTO=&quot;/home/$USER/www/$URL/proto&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'PUBLIC=&quot;/home/$USER/www/$URL/public&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span>  <span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'export GIT_DIR=&quot;$PROTO/.git&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'pushd $PROTO &gt; /dev/null'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'git pull'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'popd &gt; /dev/null'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">''</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;echo -----------------------------&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;echo '** Pushing changes to '<span style="color: #007800;">$URL</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;echo '** Moving current public to /tmp'&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'mv &quot;$PUBLIC&quot; &quot;/tmp/'</span><span style="color: #007800;">$URL</span><span style="color: #ff0000;">'public-`date '</span>+<span style="color: #000000; font-weight: bold;">%</span>m<span style="color: #000000; font-weight: bold;">%</span>d<span style="color: #000000; font-weight: bold;">%</span>Y<span style="color: #ff0000;">'`&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'echo &quot;** Generating new public&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'jekyll &quot;$PROTO&quot; &quot;$PUBLIC&quot;'</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> <span style="color: #007800;">$HOOK</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** enabling hook&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">chmod</span> a+x <span style="color: #007800;">$HOOK</span> 
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;** clone repo on local machina. example:&quot;</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;git clone ssh://<span style="color: #007800;">$USER</span>@<span style="color: #007800;">$SSHURL</span>/~<span style="color: #007800;">$USER</span>/www/<span style="color: #007800;">$SSHURL</span>/proto.git&quot;</span></pre></div></div>

<p><strong>Usage</strong></p>
<p>Your site structure might be different. <strong>repogen.sh</strong> is made by pasting the above code in a new file, and then chmod a+x to make it executable. This should be done on the remote server.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> www<span style="color: #000000; font-weight: bold;">/</span>domain.com<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">ls</span>
public<span style="color: #000000; font-weight: bold;">/</span> private<span style="color: #000000; font-weight: bold;">/</span> log<span style="color: #000000; font-weight: bold;">/</span> cgi-bin<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
.<span style="color: #000000; font-weight: bold;">/</span>repogen.sh domain.com</pre></div></div>

<p>Now on your local machine, clone the new repo, move your files in, and push:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">git clone <span style="color: #c20cb9; font-weight: bold;">ssh</span>:<span style="color: #000000; font-weight: bold;">//</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>username<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">@</span>ssh.domain.com<span style="color: #000000; font-weight: bold;">/</span>~<span style="color: #7a0874; font-weight: bold;">&#91;</span>username<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>domain.com<span style="color: #000000; font-weight: bold;">/</span>proto.git
<span style="color: #7a0874; font-weight: bold;">cd</span> proto<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #ff0000;">&quot;hello, world&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> index.htm
git add index.htm
git commit <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'first local commit'</span>
git push</pre></div></div>

<p>After you push your changes, the post-update hook will delete the public/ directory (the root of the site). This dir and its contents are automatically generated and will get wiped out on EVERY push. Keep this in mind. All your changes and content should reside in proto/. </p>
<p>The proto/ repo will pull in the new changes, and then Jekyll will be invoked to generate the updated site in public/ from the prototype.</p>
<p>Should you need to edit it, the <strong>post-update hook</strong> is in the bare git repo (proto.git/hooks/)</p>
<p>Thanks to the authors in the posts below for sharing ideas. I first read this git method on dmiessler&#8217;s site. </p>
<p><strong>Resources:</strong><br />
<a href="http://dmiessler.com/blog/using-git-to-maintain-your-website">dmiessler.com &#8211; using git to maintain static pages</a><br />
<a href="http://toroid.org/ams/git-website-howto">toroid.org &#8211; using git to manage a web site</a><br />
<a href="http://github.com/mojombo/jekyll/tree/master">Jekyll @ GitHub</a><br />
<a href="http://media.pragprog.com/titles/tsgit/chap-005-extract.html">git info</a><br />
<a href="http://www.nardol.org/2009/2/19/git-basics-reversing-the-git-sucks-effect">more git info</a></p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2009/03/how-to-maintain-static-sites-with-git-jekyll/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Scraping Google Trends with Mechanize and Hpricot</title>
		<link>http://biodegradablegeek.com/2009/01/scraping-google-trends-with-mechanize-and-hpricot/</link>
		<comments>http://biodegradablegeek.com/2009/01/scraping-google-trends-with-mechanize-and-hpricot/#comments</comments>
		<pubDate>Sat, 24 Jan 2009 06:53:06 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scraping]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Code example]]></category>
		<category><![CDATA[making monies]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[public domain]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=313</guid>
		<description><![CDATA[This is a small Ruby script that fetches the 100 trends of the day for a specific date. If multiple dates are searched, one can find out how many times a keyword occurred between two dates, or just find out what keywords are constantly appearing on the top 100 list. Very profitable info! but alas, [...]]]></description>
			<content:encoded><![CDATA[<p>This is a small Ruby script that fetches the 100 trends of the day for a specific date. If multiple dates are searched, one can find out how many times a keyword occurred between two dates, or just find out what keywords are constantly appearing on the top 100 list. <strong>Very profitable info!</strong> but alas, the script is incomplete and one must implement the &#8220;implement me!&#8221; methods to get full functionality. This, in its current state, should serve as a good starting point for scraping Google Trends.</p>
<p>On a technical note, it&#8217;s using mechanize, hpricot, tempfile (for the cache). A lot of this is just <a href="http://en.wikipedia.org/wiki/Copy_and_paste_programming">copy &amp; paste programming</a> from the <a href="http://biodegradablegeek.com/2009/01/animecrazy-scraper-example-using-hpricot-mechanize/">earlier anime scraper</a>. </p>
<p>To grab the gems <em>(rdoc takes 10x as long as the gem to fetch and install)</em>:</p>

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


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#008000; font-style:italic;"># biodegradablegeek.com</span>
<span style="color:#008000; font-style:italic;"># public domain</span>
<span style="color:#008000; font-style:italic;"># </span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'hpricot'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'tempfile'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mechanize'</span>
<span style="color:#008000; font-style:italic;">#require 'highline/import'</span>
<span style="color:#008000; font-style:italic;">#HighLine.track_eof = false</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$mech</span> = <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize</span>.<span style="color:#9900CC;">new</span>
<span style="color:#ff6633; font-weight:bold;">$mech</span>.<span style="color:#9900CC;">user_agent_alias</span> = <span style="color:#996600;">'Mac Safari'</span>
<span style="color:#ff6633; font-weight:bold;">$master</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> puts2<span style="color:#006600; font-weight:bold;">&#40;</span>txt=<span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;*** #{txt}&quot;</span>; <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Cache
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#008000; font-style:italic;"># Setup physical cache location </span>
    <span style="color:#0066ff; font-weight:bold;">@path</span> = <span style="color:#996600;">'cache'</span>
    <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">mkdir</span> <span style="color:#0066ff; font-weight:bold;">@path</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>? <span style="color:#0066ff; font-weight:bold;">@path</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># key/val = url/filename (of fetched data)</span>
    <span style="color:#0066ff; font-weight:bold;">@datafile</span> = <span style="color:#996600;">&quot;#{@path}/cache.data&quot;</span>
    <span style="color:#0066ff; font-weight:bold;">@cache</span> = <span style="color:#CC0066; font-weight:bold;">load</span> <span style="color:#0066ff; font-weight:bold;">@datafile</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> put key, val
    tf = <span style="color:#CC00FF; font-weight:bold;">Tempfile</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'googletrends'</span>, <span style="color:#0066ff; font-weight:bold;">@path</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    path = tf.<span style="color:#9900CC;">path</span>
    tf.<span style="color:#9900CC;">close</span>! <span style="color:#008000; font-style:italic;"># important!</span>
&nbsp;
    puts2 <span style="color:#996600;">&quot;Saving to cache (#{path})&quot;</span>
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
      f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@cache</span><span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> = path
    <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
    save <span style="color:#0066ff; font-weight:bold;">@datafile</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get key
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">unless</span> exists?<span style="color:#006600; font-weight:bold;">&#40;</span>key<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>@cache<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cache<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">read</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> files
    <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">values</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> first
    <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">first</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> exists? key
    <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">has_key</span>? key
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
private
  <span style="color:#008000; font-style:italic;"># Load saved cache </span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">load</span> file
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Save cache </span>
  <span style="color:#9966CC; font-weight:bold;">def</span> save path
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
      f.<span style="color:#9900CC;">write</span> <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">to_yaml</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$cache</span> = Cache.<span style="color:#9900CC;">new</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fetch<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  body = <span style="color:#ff6633; font-weight:bold;">$mech</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#ff6633; font-weight:bold;">$cache</span>.<span style="color:#9900CC;">put</span><span style="color:#006600; font-weight:bold;">&#40;</span>url, body<span style="color:#006600; font-weight:bold;">&#41;</span>
  body
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> getPage<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  body = <span style="color:#ff6633; font-weight:bold;">$cache</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> body.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Not cached. Fetching from site...&quot;</span>
    body = fetch url 
  <span style="color:#9966CC; font-weight:bold;">end</span>
  body
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> loadState
  mf = <span style="color:#996600;">'cache/master.data'</span>
  <span style="color:#ff6633; font-weight:bold;">$master</span> = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>mf<span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>mf<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#ff6633; font-weight:bold;">$master</span> = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#ff6633; font-weight:bold;">$master</span>==<span style="color:#0000FF; font-weight:bold;">false</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> saveState
  <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'cache/master.data'</span>, <span style="color:#996600;">'w+'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
    f.<span style="color:#9900CC;">write</span> <span style="color:#ff6633; font-weight:bold;">$master</span>.<span style="color:#9900CC;">to_yaml</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> main
  <span style="color:#008000; font-style:italic;">#loadState</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Grab top 100 Google Trends (today)</span>
  <span style="color:#008000; font-style:italic;">#date = Time.now.strftime '%Y-%m-%d'</span>
  date = <span style="color:#996600;">'2009-01-21'</span>
&nbsp;
  puts2 <span style="color:#996600;">&quot;Getting Google's top 100 search trends for #{date}&quot;</span>
  url = <span style="color:#996600;">&quot;http://www.google.com/trends/hottrends?sa=X&amp;date=#{date}&quot;</span>
  puts2 url
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">begin</span>
    body = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize::ResponseCodeError</span>
    puts2 <span style="color:#996600;">&quot;Couldn't fetch URL. Invalid date..?&quot;</span>
    <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">5</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  puts2 <span style="color:#996600;">&quot;Fetched page (#{body.size} bytes)&quot;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> body<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'There is no data on date'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    puts2 <span style="color:#996600;">'No data available for this date.'</span>
    puts2 <span style="color:#996600;">'Date might be too old or too early for report, or just invalid'</span>
    <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">3</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  doc = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span>body<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#006600; font-weight:bold;">&#40;</span>doc<span style="color:#006600; font-weight:bold;">/</span><span style="color:#996600;">&quot;td[@class='hotColumn']/table[@class='Z2_list']//tr&quot;</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> <span style="color:#006600; font-weight:bold;">|</span>tr<span style="color:#006600; font-weight:bold;">|</span>
    td = <span style="color:#006600; font-weight:bold;">&#40;</span>tr<span style="color:#006600; font-weight:bold;">/</span>:td<span style="color:#006600; font-weight:bold;">&#41;</span>
    num = td<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:#9900CC;">inner_text</span>.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'.'</span>,<span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">strip</span>
    kw = td<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;">inner_text</span>
    url = <span style="color:#006600; font-weight:bold;">&#40;</span>td<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:#006600; font-weight:bold;">/</span>:a<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    Keyword.<span style="color:#9900CC;">find_or_new</span><span style="color:#006600; font-weight:bold;">&#40;</span>kw<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> Occurance.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>num, date, url<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Got info on #{$master.size} keywords for #{date}&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;keyword '#{$master.first.name}' occured #{$master.first.occurances} times&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Occurance
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:pos</span>, <span style="color:#ff3333; font-weight:bold;">:date</span>, <span style="color:#ff3333; font-weight:bold;">:url</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>pos, date, url<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@pos</span> = pos
    <span style="color:#0066ff; font-weight:bold;">@date</span> = date
    <span style="color:#0066ff; font-weight:bold;">@url</span> = url
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Keyword
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:occurances</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span> = name
    <span style="color:#0066ff; font-weight:bold;">@occurances</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@position_average</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#0066ff; font-weight:bold;">@count</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#ff6633; font-weight:bold;">$master</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_or_new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>
    x = <span style="color:#ff6633; font-weight:bold;">$master</span>.<span style="color:#9900CC;">find</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>m<span style="color:#006600; font-weight:bold;">|</span> name==m.<span style="color:#9900CC;">name</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    x <span style="color:#006600; font-weight:bold;">||</span> Keyword.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> occurance
    <span style="color:#0066ff; font-weight:bold;">@occurances</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> occurance
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> occured_on? datetime
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'implement me'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> occured_between? datetime
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'implement me'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> occurances datetime=<span style="color:#0000FF; font-weight:bold;">nil</span>
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'implement me'</span> <span style="color:#9966CC; font-weight:bold;">if</span> datetime
    <span style="color:#0066ff; font-weight:bold;">@occurances</span>.<span style="color:#9900CC;">size</span> 
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> occurances_between datetime
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'implement me'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> pos_latest
    <span style="color:#0066ff; font-weight:bold;">@occurances</span>.<span style="color:#9900CC;">last</span>.<span style="color:#9900CC;">date</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> pos_average
    <span style="color:#0066ff; font-weight:bold;">@position_average</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> pos_average_between datetime
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'implement me'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#   Instance= [num, date, url]</span>
<span style="color:#008000; font-style:italic;">#   Keyword=[Instance, Intance, Instance]</span>
<span style="color:#008000; font-style:italic;">#   Methods for keywords: </span>
<span style="color:#008000; font-style:italic;">#   KW.occured_on? date </span>
<span style="color:#008000; font-style:italic;">#   KW.occured_between? d1, d2 </span>
<span style="color:#008000; font-style:italic;">#   KW.occurances</span>
<span style="color:#008000; font-style:italic;">#   KW.occurances_between? d1, d2</span>
<span style="color:#008000; font-style:italic;">#   KW.pos_latest</span>
<span style="color:#008000; font-style:italic;">#   KW.pos_average</span>
<span style="color:#008000; font-style:italic;">#   KW.pos_average_between</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#   KW has been on the top 100 list KW.occurances.size times</span>
<span style="color:#008000; font-style:italic;">#   The #1 keywords for the month of January: Master.sort_by KW.occurances_between? Jan1,Jan31.pos_average_between Jan1,Jan31 </span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;">#   Top keywords: sort by KW.occurances.size = N keyword was listed the most.</span>
<span style="color:#008000; font-style:italic;">#   Top keywords for date D: Master.sort_by KW.occured_on (x).num</span>
&nbsp;
main</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2009/01/scraping-google-trends-with-mechanize-and-hpricot/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>AnimeCrazy Scraper Example Using Hpricot &amp; Mechanize</title>
		<link>http://biodegradablegeek.com/2009/01/animecrazy-scraper-example-using-hpricot-mechanize/</link>
		<comments>http://biodegradablegeek.com/2009/01/animecrazy-scraper-example-using-hpricot-mechanize/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 20:44:40 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scraping]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Code example]]></category>
		<category><![CDATA[hpricot]]></category>
		<category><![CDATA[mechanize]]></category>
		<category><![CDATA[tuts]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=306</guid>
		<description><![CDATA[This is a little (as of now incomplete) scraper I wrote to grab all the anime video code off of AnimeCrazy (dot) net. This site doesn&#8217;t host any videos on its own server, but just embeds ones that have been uploaded to other sites (Megavideo, YouTube, Vimeo, etc). I don&#8217;t know who the original uploaders [...]]]></description>
			<content:encoded><![CDATA[<p>This is a little <em>(as of now incomplete)</em> scraper I wrote to grab all the anime video code off of AnimeCrazy (dot) net. This site doesn&#8217;t host any videos on its own server, but just embeds ones that have been uploaded to other sites (Megavideo, YouTube, Vimeo, etc). I don&#8217;t know who the original uploaders of the videos are, but I&#8217;ve seen this same collection of anime links being used on some other sites. This site has about 10,000 episodes/parts (1 movie may have 6+ parts). The scraper below was only tested with &#8220;completed anime shows&#8221; and got around 6300 episodes. The remaining content (anime movies and running anime shows) should work as-is, but I personally held off on getting those because I want to examine them closely to try cleaning up the inconsistencies as much as possible.</p>
<p>This scraper needs some initial setup and <strong>won&#8217;t work out of the box</strong>, but I&#8217;m including it here in the hopes that it will serve as a decent example of a small real world scraper, if you&#8217;re looking to learn the basics of scraping with <a href="http://redhanded.hobix.com/inspect/hpricot01.html">Hpricot</a> and Mechanize. Let me know if you find any use for it. I will update the posted code later this week when I have time to complete it and add some more features.</p>
<p>There&#8217;s one major problem with the organization of episodes on AnimeCrazy, and it&#8217;s the fact that some episodes are glued together into one post. Right now the scraper stops and asks you how to proceed when it comes across such a post. You basically need to tell the scraper if a post (page) contains 1 episode (video) or multiple. If there&#8217;s 1, it proceeds on its own, but if there&#8217;s two, it requires that you give it the names and links of each individual episode (part1 and part2 usually). Sometimes 2 episodes are together in 1 video. Sorta like those music albums on KaZaA or LimeWire that are basically ripped as one huge mp3 instead of individual songs.</p>
<p>This only accounts for maybe 30-40 out of 6000 videos, and it&#8217;s not that big of a deal because the amount of work needed to proceed with the scraping is small, but it IS work, and is a bitch slap to the entire concept of automation, but coding around the issue is a major hassle and there would still be a high chance that some inconsistencies will still come through. It would be far less work to just find another anime site which is far more consistent, though the reason animecrazy is good is because it&#8217;s active, and the site IS updated manually these days, as far as I can tell.</p>
<p>BTW, <strong><a href="http://whytheluckystiff.net/">Why The Lucky Stiff rocks</a>, and Hpricot is amazing.</strong> But the serious scrapologist should consider <a href="http://blog.labnotes.org/2006/07/11/scraping-with-style-scrapi-toolkit-for-ruby/">scrAPI</a> or <a href="http://scrubyt.org/">sCRUBYt</a> (uses Hpricot) for big projects.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
<span style="color:#008000; font-style:italic;"># License: Public domain. Go sell it to newbs on DigitalPoint.</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'hpricot'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mechanize'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'tempfile'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'highline/import'</span>
HighLine.<span style="color:#9900CC;">track_eof</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$mech</span> = <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize</span>.<span style="color:#9900CC;">new</span>
<span style="color:#ff6633; font-weight:bold;">$mech</span>.<span style="color:#9900CC;">user_agent_alias</span> = <span style="color:#996600;">'Mac Safari'</span>
&nbsp;
<span style="color:#008000; font-style:italic;">###############################</span>
<span style="color:#ff6633; font-weight:bold;">$skip_until</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
DEBUG=<span style="color:#0000FF; font-weight:bold;">false</span>
<span style="color:#008000; font-style:italic;">###############################</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> debug?
  DEBUG
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> puts2<span style="color:#006600; font-weight:bold;">&#40;</span>txt=<span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;*** #{txt}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#  Anime has: title, type (series, movie), series</span>
<span style="color:#008000; font-style:italic;">#  Episode has name/#, description, parts (video code)</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Episode
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:src</span>, <span style="color:#ff3333; font-weight:bold;">:desc</span>, <span style="color:#ff3333; font-weight:bold;">:cover</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>title, page<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@src</span> = page <span style="color:#008000; font-style:italic;"># parts (megavideo, youtube etc)</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span> = title
    <span style="color:#0066ff; font-weight:bold;">@desc</span> = <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#008000; font-style:italic;"># episode description</span>
    <span style="color:#0066ff; font-weight:bold;">@cover</span> = <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#008000; font-style:italic;"># file path</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Anime
  attr_accessor <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:page</span>, <span style="color:#ff3333; font-weight:bold;">:completed</span>, <span style="color:#ff3333; font-weight:bold;">:anime_type</span>, <span style="color:#ff3333; font-weight:bold;">:episodes</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>title, page<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@name</span> = title
    <span style="color:#0066ff; font-weight:bold;">@page</span> = page
    <span style="color:#0066ff; font-weight:bold;">@episodes</span> = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#0066ff; font-weight:bold;">@anime_type</span> = <span style="color:#996600;">'series'</span>
    <span style="color:#0066ff; font-weight:bold;">@completed</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> complete!
    <span style="color:#0066ff; font-weight:bold;">@completed</span> = <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> episode! episode
    <span style="color:#0066ff; font-weight:bold;">@episodes</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; episode
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Cache
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize
    <span style="color:#008000; font-style:italic;"># Setup physical cache location</span>
    <span style="color:#0066ff; font-weight:bold;">@path</span> = <span style="color:#996600;">'cache'</span>
    <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">mkdir</span> <span style="color:#0066ff; font-weight:bold;">@path</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>? <span style="color:#0066ff; font-weight:bold;">@path</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># key/val = url/filename (of fetched data)</span>
    <span style="color:#0066ff; font-weight:bold;">@datafile</span> = <span style="color:#996600;">&quot;#{@path}/cache.data&quot;</span>
    <span style="color:#0066ff; font-weight:bold;">@cache</span> = <span style="color:#CC0066; font-weight:bold;">load</span> <span style="color:#0066ff; font-weight:bold;">@datafile</span>
    <span style="color:#008000; font-style:italic;">#puts @cache.inspect</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> put key, val
    tf = <span style="color:#CC00FF; font-weight:bold;">Tempfile</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'animecrazy'</span>, <span style="color:#0066ff; font-weight:bold;">@path</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    path = tf.<span style="color:#9900CC;">path</span>
    tf.<span style="color:#9900CC;">close</span>! <span style="color:#008000; font-style:italic;"># important!</span>
&nbsp;
    puts2 <span style="color:#996600;">&quot;Saving to cache (#{path})&quot;</span>
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
      f.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>val<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0066ff; font-weight:bold;">@cache</span><span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> = path
    <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
    save <span style="color:#0066ff; font-weight:bold;">@datafile</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> get key
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">unless</span> exists?<span style="color:#006600; font-weight:bold;">&#40;</span>key<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&amp;</span>amp; <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>@cache<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>@cache<span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">read</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> exists? key
    <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">has_key</span>? key
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
private
  <span style="color:#008000; font-style:italic;"># Load saved cache</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#CC0066; font-weight:bold;">load</span> file
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>file<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">read</span><span style="color:#006600; font-weight:bold;">&#41;</span> : <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Save cache</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> save path
    <span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>path, <span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
      f.<span style="color:#9900CC;">write</span> <span style="color:#0066ff; font-weight:bold;">@cache</span>.<span style="color:#9900CC;">to_yaml</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#ff6633; font-weight:bold;">$cache</span> = Cache.<span style="color:#9900CC;">new</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> fetch<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  body = <span style="color:#ff6633; font-weight:bold;">$mech</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">body</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#ff6633; font-weight:bold;">$cache</span>.<span style="color:#9900CC;">put</span><span style="color:#006600; font-weight:bold;">&#40;</span>url, body<span style="color:#006600; font-weight:bold;">&#41;</span>
  body
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> getPage<span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># First let's see if this is cached already.</span>
  body = <span style="color:#ff6633; font-weight:bold;">$cache</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>url<span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">if</span> body.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Not cached. Fetching from site...&quot;</span>
    body = fetch url
  <span style="color:#9966CC; font-weight:bold;">end</span>
  body
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> main
  <span style="color:#008000; font-style:italic;"># Open anime list (anime_list = saved HTML of</span>
<span style="color:#006600; font-weight:bold;">&lt;</span>ul<span style="color:#006600; font-weight:bold;">&gt;</span>...<span style="color:#006600; font-weight:bold;">&lt;/</span>ul<span style="color:#006600; font-weight:bold;">&gt;</span>
sidebar from animecrazy.<span style="color:#9900CC;">net</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  anime_list = 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><span style="color:#996600;">'anime_list'</span>, <span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">read</span> <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  puts2 <span style="color:#996600;">&quot;Anime list open&quot;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Read in the URL to every series</span>
  masterlist = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  <span style="color:#006600; font-weight:bold;">&#40;</span>anime_list<span style="color:#006600; font-weight:bold;">/</span>:li<span style="color:#006600; font-weight:bold;">/</span>:a<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>series<span style="color:#006600; font-weight:bold;">|</span>
    anime = Anime.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>series.<span style="color:#9900CC;">inner_text</span>, series<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    masterlist <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; anime
    puts2 <span style="color:#996600;">&quot;Built structure for #{anime.name}...&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  puts2
&nbsp;
  puts2 <span style="color:#996600;">&quot;Fetched #{masterlist.size} animes. Now fetching episodes...&quot;</span>
  masterlist.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>anime<span style="color:#006600; font-weight:bold;">|</span>
    puts2 <span style="color:#996600;">&quot;Fetching body (#{anime.name})&quot;</span>
    body = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>anime.<span style="color:#9900CC;">page</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    puts2 <span style="color:#996600;">&quot;Snatched that bitch (#{body.size} bytes of Goku Goodness)&quot;</span>
    puts2
&nbsp;
    doc = Hpricot<span style="color:#006600; font-weight:bold;">&#40;</span>body<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>doc<span style="color:#006600; font-weight:bold;">/</span><span style="color:#996600;">&quot;h1/a[@rel='bookmark']&quot;</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> <span style="color:#006600; font-weight:bold;">|</span>episode<span style="color:#006600; font-weight:bold;">|</span>
      name = clean<span style="color:#006600; font-weight:bold;">&#40;</span>episode.<span style="color:#9900CC;">inner_text</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#ff6633; font-weight:bold;">$skip_until</span>
        <span style="color:#008000; font-style:italic;">#$skip_until = !inUrl(episode[:href], 'basilisk-episode-2')</span>
        <span style="color:#008000; font-style:italic;">#$skip_until = nil == name['Tsubasa Chronicles']</span>
        puts2 <span style="color:#996600;">&quot;Resuming from #{episode[:href]}&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> !$skip_until
        <span style="color:#9966CC; font-weight:bold;">next</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># Here it gets tricky. This is a major source of inconsistencies in the site.</span>
      <span style="color:#008000; font-style:italic;"># They group episodes into 1 post sometimes, and the only way to find</span>
      <span style="color:#008000; font-style:italic;"># out from the title of the post is by checking for the following patterns</span>
      <span style="color:#008000; font-style:italic;"># (7 and 8 are example episode #s)</span>
      <span style="color:#008000; font-style:italic;"># X = 7+8, 7 + 8, 7 and 8, 7and8, 7 &amp;amp; 8, 7&amp;amp;8</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># If an episode has no X then it is 1 episode.</span>
      <span style="color:#008000; font-style:italic;"># If it has multiple parts, they are mirrors.</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> single_episode? name
        <span style="color:#9966CC; font-weight:bold;">begin</span>
&nbsp;
          puts2 <span style="color:#996600;">&quot;Adding episode #{name}...&quot;</span>
          ep = Episode.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          ep.<span style="color:#9900CC;">src</span> = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          anime.<span style="color:#9900CC;">episode</span>! ep
        <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize::ResponseCodeError</span>
          puts2 <span style="color:#996600;">&quot;ERROR: Page not found? Skipping...&quot;</span>
          <span style="color:#CC0066; font-weight:bold;">puts</span> name
          puts2 episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        <span style="color:#008000; font-style:italic;"># If an episode DOES have X, it *may* have 2 episodes (but may have mirrors, going up to 4 parts/vids per page).</span>
        <span style="color:#008000; font-style:italic;"># Multiple parts will be the individual episodes in chronological order.</span>
        puts2 <span style="color:#996600;">&quot;Help me! I'm confused @ '#{name}'&quot;</span>
        puts2 <span style="color:#996600;">&quot;This post might contain multiple episodes...&quot;</span>
&nbsp;
        puts2 <span style="color:#996600;">&quot;Please visit this URL and verify the following:&quot;</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span> episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">if</span> agree<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Is this 1 episode? yes/no &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#9966CC; font-weight:bold;">begin</span>
            puts2 <span style="color:#996600;">&quot;Adding episode #{name}...&quot;</span>
            ep = Episode.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            ep.<span style="color:#9900CC;">src</span> = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            anime.<span style="color:#9900CC;">episode</span>! ep
          <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize::ResponseCodeError</span>
            puts2 <span style="color:#996600;">&quot;ERROR: Page not found? Skipping...&quot;</span>
            <span style="color:#CC0066; font-weight:bold;">puts</span> name
            puts2 episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">else</span>
          more = <span style="color:#0000FF; font-weight:bold;">true</span>
          <span style="color:#9966CC; font-weight:bold;">while</span> more
            ename = ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Enter the name of an episode: &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            eurl =  ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Enter the URL of an episode: &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
            <span style="color:#9966CC; font-weight:bold;">begin</span>
              puts2 <span style="color:#996600;">&quot;Adding episode #{ename}...&quot;</span>
              ep = Episode.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>name, episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
              ep.<span style="color:#9900CC;">src</span> = getPage<span style="color:#006600; font-weight:bold;">&#40;</span>episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
              anime.<span style="color:#9900CC;">episode</span>! ep
            <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">WWW::Mechanize::ResponseCodeError</span>
              puts2 <span style="color:#996600;">&quot;ERROR: Page not found? Skipping...&quot;</span>
              <span style="color:#CC0066; font-weight:bold;">puts</span> name
              puts2 episode<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:href</span><span style="color:#006600; font-weight:bold;">&#93;</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
            more = agree<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Add another episode? Y/N&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
          puts2 <span style="color:#996600;">&quot;Added episodes manually... moving on&quot;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    anime.<span style="color:#9900CC;">complete</span>!
    <span style="color:#008000; font-style:italic;"># XXX save the entire anime object, instead of just cache</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> inTitle<span style="color:#006600; font-weight:bold;">&#40;</span>document, title<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#006600; font-weight:bold;">&#40;</span>document<span style="color:#006600; font-weight:bold;">/</span>:title<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">inner_text</span><span style="color:#006600; font-weight:bold;">&#91;</span>title<span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> inUrl<span style="color:#006600; font-weight:bold;">&#40;</span>url, part<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> url<span style="color:#006600; font-weight:bold;">&#91;</span>part<span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> single_episode?<span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>
  !<span style="color:#006600; font-weight:bold;">&#40;</span>name =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span> ?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">+&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">|</span>and<span style="color:#006600; font-weight:bold;">&#41;</span> ?<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> clean<span style="color:#006600; font-weight:bold;">&#40;</span>txt<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># This picks up most of them, but some are missing. Like *Final* and just plain &quot;Final&quot;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (Final)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (Final)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (Final Episode)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (Final Episode)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL EPISODE)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL EPISODE)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(Final)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(Final)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(Final Episode)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(Final Episode)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(FINAL)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'(FINAL EPISODE)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">''</span> <span style="color:#9966CC; font-weight:bold;">if</span> txt<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">' (FINAL EPISODE)'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  txt
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
main</pre></div></div>

<p>If you&#8217;re writing your own scraper and would like to use the minimal caching functionality present below, you can gut everything in main() out and put in your own code. Feel free to <a href="/contact">contact me for assistance</a>.</p>
<p>Here is some sample output:<br />
<span id="more-306"></span></p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">*** Adding episode Initial D: Episode 1 (Stage 2)...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090111-12300-mbdpcl-0)
*** Fetching body (Initial D: Third Stage)
*** Snatched that bitch (77695 bytes of Goku Goodness)
***
*** Adding episode Initial D: Third Stage...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090111-12300-ea69nr-0)
*** Fetching body (Kaiji)
*** Snatched that bitch (87553 bytes of Goku Goodness)
***
*** Adding episode Basilisk Episode 4...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-fomoh0-0)
*** Adding episode Basilisk Episode 3...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-1dx9xm-0)
*** Adding episode Basilisk Episode 2...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-5xt774-0)
*** Adding episode Basilisk Episode 1...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-br5fxd-0)
*** Adding episode Tsubasa Chronicles: Tokyo Revelations Episode 3...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-zmuwix-0)
*** Adding episode Tsubasa Chronicles: Tokyo Revelations Episode 2...
Not cached. Fetching from site...
*** Saving to cache (cache/animecrazy20090110-14992-1ah20eg-0)
*** Adding episode Tsubasa Chronicles: Tokyo Revelations Episode 1...
Not cached. Fetching from site...</pre></div></div>

<p>This was written for fun, but primarily profit, and not for my own viewing pleasure. The only anime I&#8217;ve seen was Akira a decade or so ago, and only because the cover looked cool, but feel free to recommend your favorites.</p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2009/01/animecrazy-scraper-example-using-hpricot-mechanize/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Script to Quickly Setup WebApp Environment and Domain</title>
		<link>http://biodegradablegeek.com/2008/10/script-to-quickly-setup-webapp-environment-and-domain/</link>
		<comments>http://biodegradablegeek.com/2008/10/script-to-quickly-setup-webapp-environment-and-domain/#comments</comments>
		<pubDate>Sun, 12 Oct 2008 04:10:32 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[joomla]]></category>
		<category><![CDATA[phpmotion]]></category>
		<category><![CDATA[rio]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[warez]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=240</guid>
		<description><![CDATA[Just sharing a script I wrote to quickly deploy Wordpress (and eventually a few other webapps) sites, which somebody might find useful. This uses Linode&#8217;s API* to add the domain name to the DNS server along with some subdomains. If you&#8217;re using another server, (Slicehost, your own, etc), you can alter the dns class to [...]]]></description>
			<content:encoded><![CDATA[<p>Just sharing a script I wrote to quickly deploy Wordpress (and eventually a few other webapps) sites, which somebody might find useful. This uses <a href="http://linode.com">Linode</a>&#8217;s API* to add the domain name to the DNS server along with some subdomains. If you&#8217;re using another server, (Slicehost, your own, etc), you can alter the dns class to use that API, or just ignore the DNS stuff completely; Its optional.</p>
<p>This will be updated periodically as I refactor and add support for more apps (notably Joomla and Clipshare &#8211; though this would violate their terms unless you have the unlimited license). This was written primarily because I couldn&#8217;t stand setting up another vhost and Wordpress installation. There are plenty of existing deployers but I plan on adding very specific features and tweaking this for in-house work. I also wanted to try Rio (Ruby-IO). GPL license. Go nuts.</p>
<p><em>* As of 10/11, the apicore.rb file on the site has some syntactic errors in the domainResourceSave method. I sent an email out to the author about it. Problems aren&#8217;t major. You can get <a href="http://biodegradablegeek.com/wp-content/uploads/2008/10/apicore.rb" target="_new">my apicore.rb here</a>.</em></p>
<p>This won&#8217;t run unless you create the appropriate folder structure in /etc/mksite/. I&#8217;ll get going on this in a bit. See the code below:</p>
<p><span id="more-240"></span></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby </span>
&nbsp;
<span style="color:#008000; font-style:italic;">########################################################</span>
<span style="color:#008000; font-style:italic;"># Isam M. </span>
<span style="color:#008000; font-style:italic;"># http://biodegradablegeek.com</span>
<span style="color:#008000; font-style:italic;"># MKSITE.RB (0.2) Last updated Oct 19th, 2008</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># mksite makes it quicker to setup sites and web</span>
<span style="color:#008000; font-style:italic;"># apps by doing most of the tedious work.</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;">#                     UNSTABLE</span>
<span style="color:#008000; font-style:italic;">#           Run it in your imagination,</span>
<span style="color:#008000; font-style:italic;">#              not on your system!</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;">######################################################## </span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rio'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'yaml'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mysql'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'highline/import'</span>
HighLine.<span style="color:#9900CC;">track_eof</span> = <span style="color:#0000FF; font-weight:bold;">false</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">begin</span>
  <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'apicore'</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">LoadError</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;NOTICE: Unable to load apicore.rb - domains will not be added automatically&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
Apache_sites = <span style="color:#996600;">'/etc/apache2/sites-available/'</span>
Subdomains = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">''</span>, <span style="color:#996600;">'www'</span>, <span style="color:#996600;">'mail'</span>, <span style="color:#996600;">'blog'</span>, <span style="color:#996600;">&quot;dev#{(rand*10).floor}&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
Testing = <span style="color:#0000FF; font-weight:bold;">false</span>
Homedir = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'HOME'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
Username = ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'USER'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
Applications = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Skeleton</span>, <span style="color:#ff3333; font-weight:bold;">:Clipshare</span>, <span style="color:#ff3333; font-weight:bold;">:Joomla</span>, <span style="color:#ff3333; font-weight:bold;">:PHPMotion</span>, <span style="color:#996600;">'PmWiki (N/A)'</span>, <span style="color:#ff3333; font-weight:bold;">:Wordpress</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#ff6633; font-weight:bold;">$config</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
<span style="color:#ff6633; font-weight:bold;">$log</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> say<span style="color:#006600; font-weight:bold;">&#40;</span>txt<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">super</span> txt
<span style="color:#008000; font-style:italic;">#  $log &amp;lt;&amp;lt; txt if $log</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># flash('message', :notice || :error) to output msg</span>
<span style="color:#9966CC; font-weight:bold;">def</span> flash<span style="color:#006600; font-weight:bold;">&#40;</span>msg, message_type = <span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#9966CC; font-weight:bold;">if</span> message_type.<span style="color:#9900CC;">eql</span>? <span style="color:#ff3333; font-weight:bold;">:notice</span>
    say<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;INFORMATION: #{msg}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">elsif</span> message_type.<span style="color:#9900CC;">eql</span>? <span style="color:#ff3333; font-weight:bold;">:emphasize</span>
    say<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;***************************************************&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    say<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;NOTICE: #{msg}n&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    say<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;***************************************************&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">elsif</span> message_type.<span style="color:#9900CC;">eql</span>? <span style="color:#ff3333; font-weight:bold;">:error</span>
    STDERR.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;FATAL ERROR: #{msg}n&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># DZone 2111</span>
<span style="color:#9966CC; font-weight:bold;">def</span> genAlpha<span style="color:#006600; font-weight:bold;">&#40;</span>size=<span style="color:#006666;">64</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  s=<span style="color:#996600;">''</span>
  size.<span style="color:#9900CC;">times</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    s <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#006600; font-weight:bold;">&#40;</span>i = <span style="color:#CC00FF; font-weight:bold;">Kernel</span>.<span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">62</span><span style="color:#006600; font-weight:bold;">&#41;</span>; i <span style="color:#006600; font-weight:bold;">+</span>= <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>i <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#006666;">48</span> : <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>i <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#006666;">36</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#006666;">55</span> : <span style="color:#006666;">61</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;">&#41;</span>.<span style="color:#9900CC;">chr</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
  s
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#9966CC; font-weight:bold;">defined</span>? ApiCore
  <span style="color:#9966CC; font-weight:bold;">class</span> DNSAPI <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApiCore
    <span style="color:#008000; font-style:italic;"># This depends on the Linode API Ruby bindings (apicore.rb)</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>key, debug=<span style="color:#0000FF; font-weight:bold;">false</span>, batching=<span style="color:#0000FF; font-weight:bold;">false</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">super</span>
      <span style="color:#0066ff; font-weight:bold;">@batching</span>=<span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Add domain. Return ID on success, nil on failure</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> addDomain domain
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> !domain
      params = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:DomainID</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Domain</span><span style="color:#006600; font-weight:bold;">&#93;</span> = domain
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Type</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'master'</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Status</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">1</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:SOA_Email</span><span style="color:#006600; font-weight:bold;">&#93;</span> = getVal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'email'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Enter SOA email for the domain: &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      domainSave params
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> addDomainResource<span style="color:#006600; font-weight:bold;">&#40;</span>domain, resource, target, record_type = <span style="color:#996600;">'A'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>did = getDomainIdByName domain<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      params = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:ResourceID</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006666;">0</span>
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:DomainID</span><span style="color:#006600; font-weight:bold;">&#93;</span> = did
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Name</span><span style="color:#006600; font-weight:bold;">&#93;</span> = resource
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Type</span><span style="color:#006600; font-weight:bold;">&#93;</span> = record_type
      params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:Target</span><span style="color:#006600; font-weight:bold;">&#93;</span> = target
      domainResourceSave params
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> getDomainIdByName domain
      domainList.<span style="color:#9900CC;">find</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>dom<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> dom<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;DOMAINID&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> dom<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;DOMAIN&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">downcase</span> == domain.<span style="color:#9900CC;">downcase</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">else</span>
  flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'ApiCore not loaded. Skipping DNS stuff'</span>, <span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> App
  <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#0000FF; font-weight:bold;">self</span>; attr_reader <span style="color:#ff3333; font-weight:bold;">:message</span>, <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:version</span>, <span style="color:#ff3333; font-weight:bold;">:description</span>, <span style="color:#ff3333; font-weight:bold;">:vhost</span>; <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#0066ff; font-weight:bold;">@message</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#0066ff; font-weight:bold;">@name</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#0066ff; font-weight:bold;">@version</span> = <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#0066ff; font-weight:bold;">@description</span> = <span style="color:#996600;">'Just Another Web App'</span>
  <span style="color:#0066ff; font-weight:bold;">@vhost</span> = <span style="color:#996600;">'generic'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>rootdir, domain, db<span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Initializing application (dir=#{rootdir}, domain=#{domain})&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@rootdir</span> = <span style="color:#006600; font-weight:bold;">&#40;</span>rootdir<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">chr</span>.<span style="color:#9900CC;">eql</span>? <span style="color:#996600;">'/'</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? rootdir.<span style="color:#CC0066; font-weight:bold;">chop</span> : rootdir
    <span style="color:#0066ff; font-weight:bold;">@domain</span> = domain
    <span style="color:#0066ff; font-weight:bold;">@db</span> = db <span style="color:#008000; font-style:italic;"># hash of database info </span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># System stuff</span>
    <span style="color:#008000; font-style:italic;">#if Testing</span>
      <span style="color:#008000; font-style:italic;">#@templates = '/home/kiwi/Code/mksite/templates'</span>
      <span style="color:#008000; font-style:italic;">#@configs = '/home/kiwi/Code/mksite/configs'</span>
      <span style="color:#008000; font-style:italic;">#@vhosts = '/home/kiwi/Code/mksite/vhosts'</span>
    <span style="color:#008000; font-style:italic;">#else</span>
      <span style="color:#0066ff; font-weight:bold;">@templates</span> = <span style="color:#996600;">'/etc/mksite/templates'</span>
      <span style="color:#0066ff; font-weight:bold;">@configs</span> = <span style="color:#996600;">'/etc/mksite/configs'</span>
      <span style="color:#0066ff; font-weight:bold;">@vhosts</span> = <span style="color:#996600;">'/etc/mksite/vhosts'</span>
    <span style="color:#008000; font-style:italic;">#end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># This generally does not need to be overriden.</span>
  <span style="color:#008000; font-style:italic;"># It does 'generic shit' like creating the rootdir</span>
  <span style="color:#008000; font-style:italic;"># and setting permissions</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> envSetup
    <span style="color:#9966CC; font-weight:bold;">if</span> !rio<span style="color:#006600; font-weight:bold;">&#40;</span>@rootdir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">exist</span>?
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Creating directory #{@rootdir}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span>@rootdir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">mkpath</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>@rootdir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chdir</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>root<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#008000; font-style:italic;"># Copy the generic public/private/log apache</span>
      <span style="color:#008000; font-style:italic;"># structure to rootdir</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Changing working dir to #{@rootdir}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Working inside '#{root.to_s}'&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span>@templates,<span style="color:#996600;">'skeleton.www'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>df<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#008000; font-style:italic;"># Overwrite existing files? .. yes.</span>
        <span style="color:#008000; font-style:italic;">#while rio(root, df).exist? do</span>
        df <span style="color:#006600; font-weight:bold;">&amp;</span>gt; root
        <span style="color:#008000; font-style:italic;">#flash(&quot;Copied #{df.to_s} to #{root.to_s}&quot;)</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
      <span style="color:#008000; font-style:italic;"># Set permissions (a+w on logs, etc)</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Setting permissions...'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'666 ./log/*.log'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'./log/access.log'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>00666<span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'./log/error.log'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>00666<span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'700 ./private'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'./private/'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>00700<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#008000; font-style:italic;"># envSetup()</span>
    <span style="color:#008000; font-style:italic;"># databaseSetup()</span>
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'OVERRIDE ME'</span>
    <span style="color:#008000; font-style:italic;">#flash(&quot;setup() template function invoked. 'OVERRIDE ME'&quot;, :log)</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> databaseSetup
    <span style="color:#008000; font-style:italic;"># Create database if it doesn't already exist</span>
    <span style="color:#008000; font-style:italic;"># This usually doesn't need to be overriden</span>
    <span style="color:#008000; font-style:italic;">#Mysql.server_connect(@db['name'])</span>
    <span style="color:#008000; font-style:italic;">#  flash('Checking database connection... ')</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      dbo = Mysql.<span style="color:#9900CC;">real_connect</span><span style="color:#006600; font-weight:bold;">&#40;</span>@db<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'pass'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Creating database '#{@db['name']}'&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;
      res = dbo.<span style="color:#9900CC;">query</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;CREATE DATABASE IF NOT EXISTS #{@db['name']};&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Database server returned #{res}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> res
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Mysql::Error</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; err
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Unable to connect to access/create database'</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Error returned (#{err.errno}) = '#{err.error}'&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">1</span>
    <span style="color:#9966CC; font-weight:bold;">ensure</span>
      dbo.<span style="color:#9900CC;">close</span> <span style="color:#9966CC; font-weight:bold;">if</span> dbo
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> dnsSetup
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#9966CC; font-weight:bold;">if</span> !<span style="color:#9966CC; font-weight:bold;">defined</span>? ApiCore
&nbsp;
    <span style="color:#008000; font-style:italic;"># Setup DNS - currently uses Linode API</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Setting up DNS for '#{@domain}'&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;This requires a Linode API keynLogin to linode.com and find it under 'My Profile'&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    dns = <span style="color:#0000FF; font-weight:bold;">nil</span>
    api_key = getVal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'apikey'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">loop</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      api_key = ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Paste your Linode API key (or '</span>skip<span style="color:#996600;">'): '</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> api_key.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#006600; font-weight:bold;">||</span> api_key.<span style="color:#9900CC;">empty</span>?
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> api_key.<span style="color:#9900CC;">downcase</span>.<span style="color:#9900CC;">eql</span>? <span style="color:#996600;">'skip'</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># Check API key</span>
      <span style="color:#9966CC; font-weight:bold;">begin</span>
        dns = DNSAPI.<span style="color:#9900CC;">new</span> api_key
        dns.<span style="color:#9900CC;">domainList</span>
        <span style="color:#9966CC; font-weight:bold;">break</span>
      <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">RuntimeError</span>
        flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;API key invalid (or service down?). Learn to paste and try again.n&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        api_key = <span style="color:#0000FF; font-weight:bold;">nil</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">unless</span> api_key.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#9966CC; font-weight:bold;">or</span> api_key.<span style="color:#9900CC;">downcase</span>.<span style="color:#9900CC;">eql</span>? <span style="color:#996600;">'skip'</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Adding master domain '#{@domain}'&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">begin</span>
        <span style="color:#9966CC; font-weight:bold;">begin</span>
          dns.<span style="color:#9900CC;">addDomain</span><span style="color:#006600; font-weight:bold;">&#40;</span>@domain<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">RuntimeError</span>
          flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Unable to add domain (exists already?). Attempting to add subdomains...'</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
        server = getVal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'server'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span>
                   ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Enter IP subdomains should point to (or 'skip'): &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>q<span style="color:#006600; font-weight:bold;">|</span> q.<span style="color:#9900CC;">default</span> = <span style="color:#996600;">'skip'</span> <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
        <span style="color:#9966CC; font-weight:bold;">unless</span> server.<span style="color:#9900CC;">downcase</span>.<span style="color:#9900CC;">eql</span>? <span style="color:#996600;">'skip'</span>
          Subdomains.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>sub<span style="color:#006600; font-weight:bold;">|</span>
            flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Adding subdomain '#{sub}.#{@domain}' (points to #{server})&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Could not add subdomain'</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> !dns.<span style="color:#9900CC;">addDomainResource</span><span style="color:#006600; font-weight:bold;">&#40;</span>@domain, <span style="color:#CC0066; font-weight:bold;">sub</span>, server<span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
     <span style="color:#9966CC; font-weight:bold;">rescue</span>
       <span style="color:#CC0066; font-weight:bold;">raise</span>
       flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Unable to add domain/subdomain. Skipping&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
     <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> serverSetup
    <span style="color:#008000; font-style:italic;"># Set Apache vhost</span>
    vhost_file = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#9966CC; font-weight:bold;">defined</span>? <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">vhost</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">vhost</span> : <span style="color:#996600;">'generic'</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Generating vhost file (#{@vhosts}/#{vhost_file}) for Apache 2.x&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    vhost = <span style="color:#996600;">''</span>
    email = getVal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'email'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">||</span> ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Enter a valid email for tech support: &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>@vhosts, vhost_file<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>gt; vhost
    vhost.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_DOMAIN_'</span>, <span style="color:#0066ff; font-weight:bold;">@domain</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    vhost.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_EMAIL_'</span>, email<span style="color:#006600; font-weight:bold;">&#41;</span>
    vhost.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_ROOT_'</span>, <span style="color:#996600;">&quot;#{@rootdir}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    vhost.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_PUBLIC_'</span>, <span style="color:#996600;">&quot;#{@rootdir}/public&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;">#rio(Testing ? '/tmp/' : Apache_sites, @domain).puts(vhost)</span>
    rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/tmp/'</span>, <span style="color:#0066ff; font-weight:bold;">@domain</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>vhost<span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Your enemies should not read this</span>
    rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/tmp/'</span>, <span style="color:#0066ff; font-weight:bold;">@domain</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>00600<span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;vhost file has been generated as /tmp/#{@domain}n
          It is YOUR responsibility to move this to #{Apache_sites}n
          Site will not work until you 'a2ensite &amp;amp;&amp;amp; apache2ctl restart'&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> postInstall<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Finished!&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Skeleton <span style="color:#006600; font-weight:bold;">&amp;</span>lt; App
  <span style="color:#0066ff; font-weight:bold;">@name</span> = <span style="color:#996600;">'Skeleton'</span>
  <span style="color:#0066ff; font-weight:bold;">@description</span> = <span style="color:#996600;">'Generic WWW directory structure'</span>
  <span style="color:#0066ff; font-weight:bold;">@message</span> = <span style="color:#996600;">''</span>
  <span style="color:#0066ff; font-weight:bold;">@vhost</span> = <span style="color:#996600;">'generic'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">envSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">dnsSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">serverSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Wordpress <span style="color:#006600; font-weight:bold;">&amp;</span>lt; App
  <span style="color:#0066ff; font-weight:bold;">@name</span> = <span style="color:#996600;">'Wordpress'</span>
  <span style="color:#0066ff; font-weight:bold;">@version</span> = <span style="color:#996600;">'2.6.2'</span>
  <span style="color:#0066ff; font-weight:bold;">@description</span> = <span style="color:#996600;">'A popular blogging platform'</span>
  <span style="color:#0066ff; font-weight:bold;">@message</span> = <span style="color:#996600;">'Trying to make monies on the Internets?'</span>
  <span style="color:#0066ff; font-weight:bold;">@vhost</span> = <span style="color:#996600;">'generic'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#008000; font-style:italic;"># This sets up the initial environment / permissions</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">envSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Copy the wordpress skeleton directory to the new dir</span>
    wproot = rio<span style="color:#006600; font-weight:bold;">&#40;</span>@rootdir,<span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Wordpress root will be #{wproot}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Copying Wordpress data over... (may take awhile)'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>@templates,<span style="color:#996600;">'wordpress'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>df<span style="color:#006600; font-weight:bold;">|</span> df <span style="color:#006600; font-weight:bold;">&amp;</span>gt; wproot <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>wproot<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chdir</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'wp-config-sample.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">rm</span><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;"># Generate and output wp config</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Generating wp-config.php based on your DB settings...'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      wpcfg = rio<span style="color:#006600; font-weight:bold;">&#40;</span>@configs, <span style="color:#996600;">'wordpress.cfg'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> !wpcfg.<span style="color:#9900CC;">exist</span>? <span style="color:#006600; font-weight:bold;">||</span> !wpcfg.<span style="color:#9900CC;">readable</span>?
        flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Wordpress config template missing or unreadable, quitting&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">2</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># Copy the config into a string, do things with it and then write it to disk</span>
      config = <span style="color:#996600;">''</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span>@configs, <span style="color:#996600;">'wordpress.cfg'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>gt; config
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Warning: config file '#{@configs}/wordpress.cfg' is empty&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> config.<span style="color:#9900CC;">empty</span>?
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_HOST_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_USER_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_PASS_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'pass'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_NAME_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'name'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_SECRET_'</span>, genAlpha<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;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Writing #{wpcfg} data&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'wp-config.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">w</span>!.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Setup the database</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">databaseSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Add DNS info</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">dnsSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Setup the server/vhost</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">serverSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Clipshare <span style="color:#006600; font-weight:bold;">&amp;</span>lt; App
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'Clipshare support is currently not available. sowwie'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Joomla <span style="color:#006600; font-weight:bold;">&amp;</span>lt; App
  <span style="color:#0066ff; font-weight:bold;">@name</span> = <span style="color:#996600;">'Joomla'</span>
  <span style="color:#0066ff; font-weight:bold;">@version</span> = <span style="color:#996600;">'1.5.7'</span>
  <span style="color:#0066ff; font-weight:bold;">@description</span> = <span style="color:#996600;">'A widely used Content Management System'</span>
  <span style="color:#0066ff; font-weight:bold;">@message</span> = <span style="color:#996600;">''</span>
  <span style="color:#0066ff; font-weight:bold;">@vhost</span> = <span style="color:#996600;">'generic'</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#008000; font-style:italic;"># This sets up the initial environment / permissions</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">envSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Copy the wordpress skeleton directory to the new dir</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Copying Joomla data over... (may take awhile)'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    jooroot = rio<span style="color:#006600; font-weight:bold;">&#40;</span>@rootdir,<span style="color:#996600;">'public'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Joomla root will be #{jooroot}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>@templates,<span style="color:#996600;">'joomla-1.5.7'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>df<span style="color:#006600; font-weight:bold;">|</span> df <span style="color:#006600; font-weight:bold;">&amp;</span>gt; jooroot <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
    rio<span style="color:#006600; font-weight:bold;">&#40;</span>jooroot<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chdir</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Removing stock Joomla config...'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'configuration.php-dist'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">rm</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># Generate and output joomla config</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Generating configuration.php based on provided settings...'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      joocfg = rio<span style="color:#006600; font-weight:bold;">&#40;</span>@configs, <span style="color:#996600;">'joomla.cfg'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> !joocfg.<span style="color:#9900CC;">exist</span>? <span style="color:#006600; font-weight:bold;">||</span> !joocfg.<span style="color:#9900CC;">readable</span>?
        flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Joomla config template missing or unreadable, quitting&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">2</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># Copy the config into a string, do things with it and then write it to disk</span>
      config = <span style="color:#996600;">''</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span>@configs, <span style="color:#996600;">'joomla.cfg'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&amp;</span>gt; config
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Warning: config file '#{@configs}/joomla.cfg' is empty&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> config.<span style="color:#9900CC;">empty</span>?
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_HOST_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_USER_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_PASS_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'pass'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_MKS_DB_NAME_'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0066ff; font-weight:bold;">@db</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'name'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      config.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_DOMAIN_'</span>, <span style="color:#0066ff; font-weight:bold;">@domain</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      config.<span style="color:#CC0066; font-weight:bold;">gsub!</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'_MKS_SECRET_'</span>, genAlpha<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;">&#41;</span> 
&nbsp;
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Writing ./configuration.php&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'configuration.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">w</span>!.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>config<span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Making configuration.php world writable (0666)&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'configuration.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>0666<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Setup the database</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">databaseSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Add DNS info</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">dnsSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    <span style="color:#008000; font-style:italic;"># Setup the server/vhost</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">serverSetup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> postInstall<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Joomla is ready to be setup using the web interface'</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Go to #{@domain} where the Joomla! web based installer will
           guide you through the rest of the installation&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Here's the database information:n
           USERNAME: #{@db['user']}n
           DB HOST : #{@db['host']}n
           DB NAME : #{@db['name']}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
&nbsp;
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;nAdmin panel is located @ #{@domain}/administrator &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;You can log into Admin using the username 'admin' along with the
    password that was generated or you chose during the web based install.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">super</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> PHPMotion <span style="color:#006600; font-weight:bold;">&amp;</span>lt; App
  <span style="color:#9966CC; font-weight:bold;">def</span> setup
    <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">'PHPMotion support is currently not available. sowwie'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Log
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>filename=<span style="color:#996600;">&quot;/tmp/#{Username}_mksite.log&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@log</span> = rio<span style="color:#006600; font-weight:bold;">&#40;</span>filename<span style="color:#006600; font-weight:bold;">&#41;</span>
    n=<span style="color:#006666;">0</span>; <span style="color:#0066ff; font-weight:bold;">@log</span> = rio<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{filename}.#{n+=1}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#0066ff; font-weight:bold;">@log</span>.<span style="color:#9900CC;">exist</span>?
    <span style="color:#0066ff; font-weight:bold;">@log</span>.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;# GENERATED BY MKS - BEGAN @ #{Time.now.to_i}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@log</span>.<span style="color:#9900CC;">chmod</span><span style="color:#006600; font-weight:bold;">&#40;</span>00600<span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Log file generated (important): #{@log.to_s} (no worries, set to 600)&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0066ff; font-weight:bold;">@log</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># append to log</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;">#super &amp;lt;&amp;lt;(data)</span>
    <span style="color:#0066ff; font-weight:bold;">@log</span>.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@log</span>.<span style="color:#CC0066; font-weight:bold;">puts</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;n&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;">#@log &amp;lt;&amp;lt; data &amp;lt;&amp;lt; &quot;n&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> loadConfig<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  cfgpath = <span style="color:#996600;">&quot;#{ENV['HOME']}/.mksite&quot;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#CC00FF; font-weight:bold;">YAML</span>.<span style="color:#CC0066; font-weight:bold;">load</span><span style="color:#006600; font-weight:bold;">&#40;</span>rio<span style="color:#006600; font-weight:bold;">&#40;</span>cfgpath<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">read</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;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> rio<span style="color:#006600; font-weight:bold;">&#40;</span>cfgpath<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">exist</span>?
  <span style="color:#0000FF; font-weight:bold;">nil</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> getVal<span style="color:#006600; font-weight:bold;">&#40;</span>key, default=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#ff6633; font-weight:bold;">$config</span><span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#ff6633; font-weight:bold;">$config</span> <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#9966CC; font-weight:bold;">defined</span>? <span style="color:#ff6633; font-weight:bold;">$config</span><span style="color:#006600; font-weight:bold;">&#91;</span>key<span style="color:#006600; font-weight:bold;">&#93;</span>
  default
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> main
  <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">1</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#996600;">'root'</span>==ENV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'USER'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>$config = loadConfig<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;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'~/.mksite config loaded'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'~/.mksite not found. It'</span>s fine, I<span style="color:#996600;">'ll annoy you with questions.'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#ff6633; font-weight:bold;">$config</span>.<span style="color:#9900CC;">inspect</span> <span style="color:#9966CC; font-weight:bold;">if</span> Testing
  flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Press ^C (CTRL+C) at any time quit'</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># Let's ask neutral questions about the new site.</span>
  <span style="color:#9966CC; font-weight:bold;">if</span> Testing
    rootdir = <span style="color:#996600;">'/tmp/sandbox9/'</span>
    domain = <span style="color:#996600;">'domain.cxm'</span>
  <span style="color:#9966CC; font-weight:bold;">else</span>
    domain = ask<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Enter site'</span>s domain name <span style="color:#006600; font-weight:bold;">&#40;</span>no http:<span style="color:#006600; font-weight:bold;">//</span> <span style="color:#9966CC; font-weight:bold;">or</span> www<span style="color:#006600; font-weight:bold;">&#41;</span>: <span style="color:#996600;">') #{ |d| d.validate = !! /^www.|^http:/// }
    rootdir = ask('</span>Root site directory <span style="color:#006600; font-weight:bold;">&#40;</span>leave blank <span style="color:#9966CC; font-weight:bold;">for</span> default<span style="color:#006600; font-weight:bold;">&#41;</span>: <span style="color:#996600;">') { |q|
      q.default = &quot;/home/#{Username}/www/#{domain}/&quot;
      q.validate = /^/home/#{Username}//
    }
  end
&nbsp;
  flash(&quot;Domain has been set to &quot;#{domain}&quot;&quot;)
  #$log = Log.new(&quot;/tmp/mks_#{domain}.log&quot;) 
&nbsp;
  flash(&quot;Site will reside in &quot;#{rootdir}&quot;, and the index/script&quot;)
  flash(&quot; files (index.php, .htaccess etc) will go in &quot;#{rootdir}/public/&quot;nn&quot;)
&nbsp;
  # Ask the user what app she wants to install and specific questions about that app
  app = nil
  choose do |menu|
    menu.prompt = '</span>Choose the software <span style="color:#9966CC; font-weight:bold;">for</span> your new site: <span style="color:#996600;">'
    Applications.each do |app|
      menu.choice app do |a|
        app = a
      end
    end
  end
&nbsp;
  flash(&quot;You chose #{app}. #{Kernel.const_get(app).message}n&quot;) 
&nbsp;
  # Fetch DB info if this app needs a database
  # XXX Should just have a db flag in the App'</span>s <span style="color:#9966CC; font-weight:bold;">class</span>
  db = <span style="color:#0000FF; font-weight:bold;">nil</span>
  <span style="color:#9966CC; font-weight:bold;">unless</span> app.<span style="color:#9900CC;">eql</span>? <span style="color:#ff3333; font-weight:bold;">:Skeleton</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'This app requires a database (only MySQL supported)'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'It will be created if it doesn'</span>t exist<span style="color:#996600;">')
&nbsp;
    db = {}
    db['</span>host<span style="color:#996600;">'] = '</span>localhost<span style="color:#996600;">'
    loop do
      if Testing
        db['</span>user<span style="color:#996600;">'] = '</span>kiwi<span style="color:#996600;">'
        db['</span>pass<span style="color:#996600;">'] = '</span><span style="color:#996600;">'
        db['</span>name<span style="color:#996600;">'] = '</span>kiwi_sandbox9<span style="color:#996600;">'
      else
        db['</span>user<span style="color:#996600;">'] = getVal('</span>db_user<span style="color:#996600;">') || ask('</span>Enter MySQL username: <span style="color:#996600;">')
        db['</span>pass<span style="color:#996600;">'] = getVal('</span>db_pass<span style="color:#996600;">') || ask('</span>Enter MySQL password: <span style="color:#996600;">') { |q| q.echo = '</span><span style="color:#006600; font-weight:bold;">*</span><span style="color:#996600;">'}
        db['</span>name<span style="color:#996600;">'] = ask('</span>Enter database name <span style="color:#006600; font-weight:bold;">&#40;</span>should <span style="color:#9966CC; font-weight:bold;">begin</span> w<span style="color:#006600; font-weight:bold;">/</span> your <span style="color:#996600;">'username_'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#996600;">') { |dbn| dbn.validate = /^#{Username}_/}
        puts db.inspect
      end
      flash(&quot;Please double check: mysql://#{db['</span>user<span style="color:#996600;">']}:#{'</span><span style="color:#006600; font-weight:bold;">*</span><span style="color:#996600;">' * (db['</span>pass<span style="color:#996600;">']).size}@#{db['</span>host<span style="color:#996600;">']}/#{db['</span>name<span style="color:#996600;">']}&quot;)
      break if Testing || agree('</span>Is this correct?<span style="color:#996600;">')
      flash(&quot;Please re-enter database infon&quot;)
    end
  end
&nbsp;
  # Check permissions and database login
  flash('</span>Doing a preliminary check<span style="color:#996600;">', :emphasize)
  flash('</span>Checking installation environment<span style="color:#996600;">')
  # Quit if the directory exists and the user does not want to go ahead
  unless Testing
    exit 1 if rio(rootdir).exist? &amp;amp;&amp;amp; !agree(&quot;Directory '</span><span style="color:#008000; font-style:italic;">#{rootdir}' exists! Continue? (Y/N)&quot;)</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Is the parent directory available and writable?</span>
  parentdir = rio<span style="color:#006600; font-weight:bold;">&#40;</span>rootdir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">dirname</span>
  <span style="color:#9966CC; font-weight:bold;">unless</span> parentdir.<span style="color:#9900CC;">exist</span>? <span style="color:#006600; font-weight:bold;">&amp;</span>amp;<span style="color:#006600; font-weight:bold;">&amp;</span>amp; parentdir.<span style="color:#9900CC;">writable</span>?
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Directory '#{parentdir.to_s}' either doesn't exist or is not writable. Check permissions&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">1</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">unless</span> db.<span style="color:#0000FF; font-weight:bold;">nil</span>? <span style="color:#006600; font-weight:bold;">||</span> <span style="color:#0000FF; font-weight:bold;">false</span>==getVal<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'db_confirm'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#008000; font-style:italic;"># Check DB connection - but this does not check if user has any privileges</span>
    flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Checking database connection'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      dbo = Mysql.<span style="color:#9900CC;">real_connect</span><span style="color:#006600; font-weight:bold;">&#40;</span>db<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'host'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, db<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'user'</span><span style="color:#006600; font-weight:bold;">&#93;</span>, db<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'pass'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Successfully connected to '#{dbo.get_server_info}'&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">Mysql::Error</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; err
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'Unable to connect to database server'</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Error returned (#{err.errno}) = '#{err.error}'&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:error</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#CC0066; font-weight:bold;">exit</span> <span style="color:#006666;">1</span>
    <span style="color:#9966CC; font-weight:bold;">ensure</span>
      dbo.<span style="color:#9900CC;">close</span> <span style="color:#9966CC; font-weight:bold;">if</span> dbo
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Begin installation</span>
  flash<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Word on the server racks is... you're good to go&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:emphasize</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  klass = <span style="color:#CC00FF; font-weight:bold;">Kernel</span>.<span style="color:#9900CC;">const_get</span><span style="color:#006600; font-weight:bold;">&#40;</span>app<span style="color:#006600; font-weight:bold;">&#41;</span>
  webapp = klass.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>rootdir, domain, db<span style="color:#006600; font-weight:bold;">&#41;</span>
  webapp.<span style="color:#9900CC;">setup</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  webapp.<span style="color:#9900CC;">postInstall</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
main<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p><a href="http://biodegradablegeek.com/wp-content/uploads/2008/10/mksite.rb" target="_new"><strong>Download</strong> the ASCII mksite.rb file here.</a></p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/10/script-to-quickly-setup-webapp-environment-and-domain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Got API? Instantly Search API Documentation</title>
		<link>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/</link>
		<comments>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 07:21:04 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/06/01/got-api-instantly-search-api-documentation/</guid>
		<description><![CDATA[gotAPI.com does an excellent job congregating API documentation for numerous programming languages under an AJAX interface. No more bulging neck veins or fulmination when you can&#8217;t remember the order of those pesky arguments.
No support for your favorite language? Contribute.
You can add a gotAPI Search Widget to your site: http://www.gotapi.com/widgets/index.html
See Ruby/Rails widget below (requires Javascript). Still [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gotapi.com/">gotAPI.com</a> does an excellent job congregating API documentation for numerous programming languages under an AJAX interface. No more bulging neck veins or fulmination when you can&#8217;t remember the order of those pesky <a href="http://project.ioni.st/post/790">arguments</a>.</p>
<p>No support for your favorite language? <a href="http://www.gotapi.com/contribute/index.html">Contribute</a>.</p>
<p>You can add a gotAPI Search Widget to your site: <a href="http://www.gotapi.com/widgets/index.html">http://www.gotapi.com/widgets/index.html</a><br />
See Ruby/Rails widget below (requires Javascript). Still in beta and might have UI issues, but it&#8217;s functional. Try typing <em>map</em> or <em>validates</em> and hitting enter.</p>
<p><!-- gotAPI.com search widget v2 begin --></p>
<div><!-- 	.gaMenu{border:1px solid #505050;background-color:#FAFAFA;padding:0px 5px 0px 5px;} 	.gaHeaderRow{font:bold 8pt Arial;color:#359155;border-top:1px solid #C0C0C0;width:250px;} 	.gaRegularRow,.gaFooterRow{font:8pt Arial;cursor:pointer;} 	.gaSelectedRow{font:8pt Arial;background-color:#c1e0e6;cursor:pointer;} --><script type="text/javascript"><!--
	gaMod='module_rubyrails.js';gaTitle='Ruby / Rails';updateWhenLoaded=false;
	var gaL=false;function gaInit(){if(gaL)return;gaL=true;var s=document.createElement('script');
	s.type='text/javascript';s.src='http://www.gotapi.com/widgets/compiled/c1_module_rubyrails.js.jsz';s.defer='defer';s.defered='yes';
	document.getElementById('gaInfo').parentNode.appendChild(s)}function gaSearching(){
	document.getElementById('gaWait').style.display='';updateWhenLoaded=true;
	document.getElementById('gaInfo').style.display='none'}
// --></script></p>
<div style="font:bold 10pt Arial">Quick Ruby / Rails lookup</div>
<input id="gaSearch" onkeydown="gaSearching()" size="20" />
<div id="gaInfo" style="font:7pt Arial">powered by <a style="padding:0px" href="http://www.gotapi.com">gotAPI.com</a></div>
<div id="gaWait" style="font:7pt Arial;display:none">Searching&#8230;</div>
</div>
<p><!-- gotAPI.com search widget v2 end --></p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to POST Form Data Using Ruby</title>
		<link>http://biodegradablegeek.com/2008/04/how-to-post-form-data-using-ruby/</link>
		<comments>http://biodegradablegeek.com/2008/04/how-to-post-form-data-using-ruby/#comments</comments>
		<pubDate>Thu, 24 Apr 2008 15:43:09 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Scraping]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/04/24/how-to-post-form-data-using-ruby/</guid>
		<description><![CDATA[POSTing data on web forms is essential for writing tools and services that interact with resources already available on the web. You can grab information from your Gmail account, add a new thread to a forum from your own app, etc. 
The following is a brief example on how this can be done in Ruby [...]]]></description>
			<content:encoded><![CDATA[<p><strong>POST</strong>ing data on web forms is essential for writing tools and services that interact with resources already available on the web. You can grab information from your Gmail account, add a new thread to a forum from your own app, etc. </p>
<p>The following is a brief example on how this can be done in Ruby using <a href="http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html" target="_blank">Net::HTTP</a>and <a href="http://www.interlacken.com/webdbdev/ch05/formpost.asp" target="_blank">this POST form example</a>.</p>
<p>Looking at the source (interlacken.com/webdbdev/ch05/formpost.asp):</p>
<pre class="brush: xml;">
&lt;form method=&quot;POST&quot; action=&quot;formpost.asp&quot;&gt;
&lt;p&gt;&lt;input type=&quot;text&quot; name=&quot;box1″ size=&quot;20″ value=&quot;&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Submit&quot; name=&quot;button1″&gt;&lt;/p&gt;
&lt;/form&gt;
</pre>
<p>We see two attributes are sent to the formpost.asp script when the user hits the submit button: A textbox named <strong>box1</strong> and the value of the submit button, named <strong>Submit</strong>. If this form used a GET method, we would just fetch the URL postfixed with (for example) <strong>?box1=our+text+here</strong>. Fortunately, Ruby&#8217;s Net::HTTP makes posting data just as easy.</p>
<p>The Ruby code: </p>
<pre class="brush: ruby;">
#!/usr/bin/ruby

require &quot;uri&quot;
require &quot;net/http&quot;

params = {'box1′ =&gt; 'Nothing is less important than which fork you use. Etiquette is the science of living. It embraces everything. It is ethics. It is honor. -Emily Post',
'button1′ =&gt; 'Submit'
}
x = Net::HTTP.post_form(URI.parse('http://www.interlacken.com/webdbdev/ch05/formpost.asp'), params)
puts x.body

# Uncomment this if you want output in a file
# File.open('out.htm', 'w') { |f| f.write x.body }
</pre>
<p>Sending the value of button1 is optional in this case, but sometimes this value is checked in the server side script. One example is when the coder wants to find out if the form has been submitted &#8211; as opposed to it being the user&#8217;s first visit to the form &#8211; without creating a hidden attribute to send along w/ the other form fields. Besides, there&#8217;s no harm in sending a few more bytes.</p>
<p>If you&#8217;re curious about URI.parse, it simply makes the URI easier to work with by separating and classifying each of its attributes, effectively letting the methods in Net::HTTP do their sole job only, instead of having to analyze and parse the URL. More info on this in the <a href="http://www.ruby-doc.org/stdlib/libdoc/uri/rdoc/classes/URI.html#M009241" target="_blank">Ruby doc</a>.</p>
<p>Assuming no errors, running this example (<em>ruby postpost</em> or <em>chmod a+x postpost.rb; ./postpost.rb</em>) yields:</p>
<pre class="brush: xml;">
&lt;form method=&quot;POST&quot; action=&quot;formpost.asp&quot;&gt;
&lt;p&gt;&lt;input type=&quot;text&quot; name=&quot;box1″ size=&quot;20″ value=&quot;NOTHING IS LESS
IMPORTANT THAN WHICH FORK YOU USE. ETIQUETTE IS THE
SCIENCE OF LIVING. IT EMBRACES EVERYTHING. IT IS ETHICS.
IT IS HONOR. -EMILY POST&quot;&gt;
&lt;input type=&quot;submit&quot; value=&quot;Submit&quot; name=&quot;button1″&gt;&lt;/p&gt;
&lt;/form&gt;
</pre>
<p>In practice, you might want to use a more specialized library to handle what you&#8217;re doing. Be sure to check out <a href="http://mechanize.rubyforge.org/mechanize/" target="_blank">Mechanize</a> and <a href="http://github.com/adamwiggins/rest-client/tree/master" target="_blank">Rest-client</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/04/how-to-post-form-data-using-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Expanding List of Ruby on Rails Sites, Editors, Tutorials, Cheat Sheets and More</title>
		<link>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/</link>
		<comments>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 18:24:29 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/01/02/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/</guid>
		<description><![CDATA[Most of these Ruby on Rails related links are right out of my bookmarks. I checked for 404s and added more recent entries, but this list is far from complete. New blogs, sites, tutorials and tools are released on a daily basis.  Just leave a comment or contact me if you want your link(s) [...]]]></description>
			<content:encoded><![CDATA[<p>Most of these Ruby on Rails related links are right out of my bookmarks. I checked for 404s and added more recent entries, but this list is far from complete. New blogs, sites, tutorials and tools are released on a daily basis.  Just <a href="#respond">leave a comment</a> or <a href="contact/">contact me</a> if you want your link(s) or anything related added, or have spotted any broken links.</p>
<p><em>(Updated 02/22/2008. Keep the suggestions coming!)</em></p>
<p><span id="more-46"></span></p>
<h2>Installation Guides</h2>
<p>These are to help you get Ruby and Rails installed and configured, ready for Hello World.</p>
<ul>
<li><a href="http://wiki.rubyonrails.com/rails/pages/GettingStartedWithRails">GettingStartedWithRails &#8211; A page on the official Wiki</a></li>
<li><a href="http://www.fearoffish.co.uk/ruby-on-rails-getting-started-book">Fear of Fish &#8211; Getting Started with Ruby on Rails</a></li>
<li><a href="http://digitalmediaminute.com/howto/fc4rails/">Installing Ruby on Rails with Lighttpd and MySQL on Fedora Core 4</a></li>
<li><a href="http://www.hivelogic.com/narrative/articles/ruby_rails_lighttpd_mysql_tiger?status=301">Building Ruby, Rails, LightTPD, and MySQL on Tiger</a></li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/HowtosInstallation">HowtosInstallation &#8211; A page on installation, from the official Wiki</a></li>
</ul>
<h2>Freeware and Commercial Ruby on Rails IDEs and Editors</h2>
<ul>
<li><strong>Freeware IDEs</strong></li>
<li><a href="http://www.netbeans.org/features/ruby/index.html">NetBeans IDE</a> (Windows/Linux/Mac OS X/Solaris)</li>
<li><a href="http://www.aptana.org/">Aptana Studio</a> (Community Edition)</li>
<li><a href="http://www.mondrian-ide.com/">Mondrian IDE</a> (Windows/Linux)</li>
<li><a href="http://www.radrails.org/">RAD Rails</a> (now part of Aptana Studio Suite, still free)</li>
<li><a href="http://www.plasmacode.com/">RoRED</a> (Windows only at the moment)</li>
<li><a href="http://freeride.rubyforge.org/wiki/wiki.pl">FreeRIDE</a> &#8211; IDE for Ruby</li>
<li><strong>Commercial IDEs</strong></li>
<li><a href="http://www.aptana.org/">Aptana Studio</a> (Professional Edition)</li>
<li><a href="http://www.activestate.com/Products/komodo_ide/?_x=1">Komodo IDE</a> (Windows/Mac/Linux)</li>
<li><a href="http://www.ruby-ide.com/ruby/ruby_ide_and_ruby_editor.php">Arachno Ruby</a> (Windows/Linux, OS X release pending)</li>
<li><a href="http://macromates.com/">TextMate</a> (OS X only)</li>
<li><strong>Editors</strong></li>
<li><a href="http://jedit.org/">JEdit &#8211; Programmer&#8217;s Text Editor</a></li>
<li><a href="http://www.gnome.org/projects/gedit/">GEdit</a> (Official Gnome text editor)</li>
<li><a href="http://grigio.org/textmate_gedit_few_steps">Textmate-like Gedit in few steps</a></li>
<li><a href="http://www.scintilla.org/SciTE.html">SciTE</a> &#8211; A free source code editor for Win32 and X</li>
<li><a href="http://biodegradablegeek.com/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/">Using Vim as a Complete Ruby on Rails IDE</a> (Shameless plug)</li>
<li><a href="http://ruby.about.com/od/railsvim/railsvim_Ruby_on_Rails_IDE.htm">rails.vim &#8211; Ruby on Rails IDE</a></li>
<li><a href="http://platypope.org/yada/emacs-demo/">Ruby on Rails on Emacs (video)</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/HowToUseEmacsWithRails">How To Use Emacs With Rails</a></li>
<li><strong>Extensions and everything else</strong></li>
<li><a href="http://rubyeclipse.sourceforge.net/">Ruby Development Tool (RDT)</a> Requires <a href="http://www.eclipse.org/">Eclipse</a></li>
<li><a href="http://rubyweaver.gilluminate.com/">Rubyweaver &#8211; Dreamweaver extension</a> (Compatible with MX through CS3)</li>
<li><a href="http://rails.vim.tpope.net/">Rails.vim</a> (Plugin for vi/vim/gvim/cream)</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1318">snippetsEmu</a>An attempt to emulate TextMate&#8217;s snippet expansion</li>
<li><a href="http://plugins.intellij.net/plugin/?id=1293">intellij IDEA Ruby Plugn</a> Plugin for the <a href="http://www.jetbrains.com/idea/">intellijIDEA Java IDE</a></li>
</ul>
<h2>Hello World!</h2>
<ul>
<li><a href="http://webmonkey.wired.com/webmonkey/05/28/index4a.html">Getting Your Feet Wet with Ruby on Rails</a></li>
<li><a href="http://www-128.ibm.com/developerworks/linux/library/l-rubyrails/">Fast Track Your Apps with Ruby on Rails &#8211; IBM</a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html">Rolling with Ruby on Rails, Part 1</a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/03/03/rails.html">Rolling with Ruby on Rails, Part 2</a></li>
<li><a href="http://www.themolehill.com/index.php/2006/07/24/beginners-guide-setting-up-ruby-on-rails-in-windows/">Beginners Guide: Setting up Ruby on Rails in Windows</a></li>
<li><a href="http://www.themolehill.com/index.php/2006/08/14/beginners-guide-starting-with-the-model/">Beginners Guide: Starting With The Model</a></li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/Tutorial">Super-quick hello world app</a></li>
<li><a href="http://www.slash7.com/articles/2005/01/24/really-getting-started-in-rails">Amy Hoy &#8211; Really Getting Started In Rails</a></li>
<li><a href="http://www.caydel.com/so-you-wanna-begin-programming-with-ruby-on-rails/"> So You Wanna Begin Programming With Ruby on Rails?</a></li>
</ul>
<h2>More In-depth Rails Tutorials</h2>
<ul>
<li><a href="http://betterexplained.com/articles/starting-ruby-on-rails-what-i-wish-i-knew/">Starting Ruby on Rails: What I Wish I Knew</a></li>
<li><a href="http://www.digitalmediaminute.com/article/1816/top-ruby-on-rails-tutorials">Top 12 Ruby on Rails Tutorials </a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html">AJAX on Rails</a></li>
<li><a href="http://www.railsforum.com/viewtopic.php?id=265">Beginning Relationships</a></li>
<li><a href="http://www.railsenvy.com/2007/8/8/activerecord-tutorial">ActiveRecord tutorial</a></li>
<li><a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial">Rails Caching Tutorial</a></li>
<li><a href="http://www.tutorialized.com/tutorials/Ruby-on-Rails/1">Rails tutorials on Tutorialized</a></li>
<li><a href="http://www.buildingwebapps.com/articles/home">RAils tutorials at BuildingWebApps</a></li>
<li><a href="http://www.rubyrailways.com/great-ruby-on-rails-rest-resources/"> Great Ruby on Rails REST resources</a></li>
<li><a href="http://www.erikveen.dds.nl/distributingrubyapplications/rails.html">Distributing Rails Application</a></li>
<li><a href="http://thinkingrails.blogspot.com/2007/08/rails-validations.html">Rails Validations</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">The Complete Guide to Rails Plugins: Part I</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/09/the-complete-guide-to-rails-plugins-part-ii">The Complete Guide to Rails Plugins: Part II</a></li>
<li><a href="http://biodegradablegeek.com/2007/12/26/understanding-basic-database-relationships-in-rails/">Understanding Basic Database Relationships in Rails</a></li>
<li><a href="http://jrhicks.net/Projects/rails/has_many_and_belongs_to_many.pdf">Has_many_and_belongs_to_many tutorial (PDF)</a></li>
</ul>
<h2>Rails Screencasts</h2>
<ul>
<li><a href="http://railscasts.com/">Railscasts</a></li>
<li><a href="http://podcast.sdruby.com/">San Diego Ruby Users Group</a></li>
<li><a href="http://coderpath.com/">Coderpath screencasts</a></li>
<li><a href="http://rails.tumblecast.com/">Rails Tumblecast</a></li>
<li><a href="http://peepcode.com/">Peepcode</a></li>
<li><a href="http://www.bestechvideos.com/tag/ruby-on-rails/">Ruby on Rails @ Best Tech Videos</a></li>
<li><a href="http://www.rubyinside.com/12-great-new-ruby-rails-screencasts-from-july-2007-566.html">10 Great New Ruby / Rails Screencasts from July 2007</a></li>
</ul>
<h2>Code Examples and Snippets</h2>
<ul>
<li><a href="http://sl33p3r.free.fr/tutorials/rails/wiki/wiki-en.html">How to build a wiki in 20 minutes (well I did not time it)</a></li>
<li><a href="http://darkhost.mine.nu:8080/~vince/rails/tutorial.html">Make a todo list program with Ruby on Rails</a></li>
<li><a href="http://tnlessone.wordpress.com/2007/01/27/how-to-make-a-simple-image-page-counter-spyer-in-20-minutes-with-rails/">How to make a simple image page counter / spyer in 20 minutes with Rails?</a></li>
<li><a href="http://rubyonrails.org/screencasts">Creating a weblog in 15 minutes (screencast)</a></li>
<li><a href="http://www.rubyinside.com/beast-an-open-source-rails-forum-in-500-lines-of-code-191.html">Beast: An open source Rails forum in under 500 lines of code</a></li>
<li><a href="http://www.petercooper.co.uk/archives/001038.html">AJAX Powered chat in 3 minutes in Ruby on Rails</a></li>
<li><a href="http://workingwithrails.com/browse/projects">Working With Rails Projects</a></li>
<li><a href="http://workingwithrails.com/browse/code">Working With Rails Code</a></li>
<li><a href="http://textsnippets.com/tag/rails">Text Snippets</a></li>
<li><a href="http://rubyforge.org/snippet/browse.php?by=lang&amp;lang=17">Snippets at Rubyforge</a></li>
<li><a href="http://snippets.dzone.com/tag/rails">DZone Rails snippets</a></li>
</ul>
<h2>Ruby / Rails Blogs</h2>
<p>These are blogs dedicated primarily to Ruby and/or Rails.</p>
<ul>
<li><a href="http://railsenvy.com/">Rails Envy</a></li>
<li><a href="http://nubyonrails.com/">nor &#8211; Nuby on Rails</a></li>
<li><a href="http://www.rubyinside.com/">Ruby Inside</a></li>
<li><a href="http://www.sameshirteveryday.com/">Same Shirt Everyday</a></li>
<li><a href="http://www.rubynoob.com/">Rubynoob</a></li>
<li><a href="http://antoniocangiano.com/">Zen and the Art of Ruby Programming</a></li>
<li><strong><a href="http://www.rorsecurity.info/">Ruby on Rails security</a></strong></li>
<li><a href="http://www.realityforge.org/">Reality Forge</a></li>
<li><a href="http://glu.ttono.us/">Gluttonous</a></li>
<li><a href="http://thinkingrails.blogspot.com">Thinking Rails</a></li>
<li><a href="http://www.seoonrails.com/">SEO On Rails</a></li>
<li><a href="http://www.notsostupid.com/">Not So Stupid</a></li>
<li><a href="http://blog.mondragon.cc/">Mike Mondragon</a></li>
<li><a href="http://www.akitaonrails.com/">Akita on Rails</a></li>
<li><a href="http://railsjitsu.com">Railsjitsu</a></li>
<li><a href="http://blog.jayfields.com/">Jay Fields Thoughts</a></li>
<li><a href="http://www.aidanf.net/rails">Aidanf</a></li>
<li><a href="http://www.railsonwave.com/">Rails on Wave</a></li>
<li><a href="http://kurt.karmalab.org/articles/category/ruby"></a></li>
<li><a href="http://railsontherun.com/">Rails on the Run</a></li>
<li><a href="http://workingwithrails.com/browse/popular/people">Popular People on Working With Rails (WWR)</a></li>
<li><a href="http://kurt.karmalab.org/articles/category/ruby">Schrade.Blog &#8211; Tech and Business Ramblings by Kurt Schrader</a></li>
<li><a href="http://grasprubyonrails.com/">Grasp Ruby on Rails</a></li>
<li><a href="http://www.rubyrailways.com/">Ruby Railways</a></li>
<li><a href="http://www.onrails.org/articles/category/ruby-on-rails">OnRails.og &#8211; Ruby On Rails and related matters.</a></li>
<li><a href="http://www.softiesonrails.com/">Softies On Rails</a></li>
<li><a href="http://www.multiply.org/notebook/">Notebook</a></li>
</ul>
<h2>Communities / Wikis / Forums / Mailing lists / IRC</h2>
<ul>
<li><a href="http://www.rubyonrails.org/community">Official Rails community page</a></li>
<li><a href="http://www.railsforum.com/">Rails Forum</a></li>
<li><a href="http://wiki.rubyonrails.org/rails">Ruby on Rails Wiki</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/IRC">#RubyOnRails on the Freenode IRC network</a></li>
<li><a href="http://www.ruby-forum.com/">Ruby-forum</a></li>
</ul>
<h2>Gems / Plugins / Tools</h2>
<p>These are some miscellaneous Rails stuff I had bookmarked. I know there are hundreds of great things I&#8217;m missing here. Don&#8217;t hesitate to recommend your favorites.</p>
<ul>
<li><a href="http://www.railsify.com/">Railsify (directory of plugins)</a></li>
<li><a href="http://www.activescaffold.com/">ActiveScaffold</a></li>
<li><a href="http://haml.hamptoncatlin.com/">#Haml</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/LoginGenerator">LoginGenerator</a></li>
<li><a href="http://www.zenspider.com/ZSS/Products/ZenTest/">ZenTest &#8211; Testing on steroids</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/Plugins">Plugins (official RoR wiki page)</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">The Complete Guide to Rails Plugins: Part I</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/09/the-complete-guide-to-rails-plugins-part-ii">The Complete Guide to Rails Plugins: Part II</a></li>
</ul>
<h2>Rails 2.0</h2>
<ul>
<li><a href="http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial">Rolling with Rails 2.0 &#8211; The First Full Tutorial</a></li>
<li><a href="http://mislav.caboo.se/rails/rails-2-0-taking-the-plunge/">Rails 2.0: taking the plunge (with script that checks if your apps are rails2 compliant)</a></li>
<li><a href="http://www.randomsyntax.com/2008/01/10/getting-started-with-ruby-on-rails-2-making-a-link-manager-part-1/">Getting Started with Ruby on Rails 2: Making a Link Manager (Part 1)</a></li>
<li><a href="http://mentalized.net/journal/2007/03/13/rails_20_deprecations/">Rails 2.0 deprecations</a></li>
<li><a href="http://softiesonrails.com/2007/7/11/upgrading-your-views-to-rails-2-0">Upgrading your views to Rails 2.0</a></li>
<li><a href="http://assertbuggy.blogspot.com/2007/10/how-to-upgrade-ruby-on-rails-restful.html">How to upgrade Ruby on Rails Restful routes to 2.0</a></li>
<li><a href="http://www.railsontherun.com/2007/12/17/rails-2-0-2-with-few-changes">Rails 2.0.2 with few changes</a></li>
<li><a href="http://blog.codefront.net/2007/12/17/rails-202-released-so-whats-new/">Rails 2.0.2 released, so what’s new?</a></li>
<li><a href="http://www.infoq.com/articles/ruby20-dhh-interview">Talking Rails 2.0 with David Heinemeier Hansson</a></li>
<li><a href="http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done">Rails 2.0: It&#8217;s done!</a></li>
</ul>
<h2>Free Ruby / Rails Books</h2>
<p>These are books that you can read online or download for free.</p>
<ul>
<li><a href="http://poignantguide.net/ruby/">Why&#8217;s (poignant) guide to ruby</a></li>
<li><a href="http://en.wikibooks.org/wiki/Ruby_Programming">Ruby Programming (Wikibooks.org)</a></li>
<li><a href="http://media.sitepoint.com/books/ror.pdf">(PDF) Build Your Own Ruby on Rails Web Applications by Patrick Lenz (provided by Sitepoint.com)</a></li>
<li><a href="http://rails.homelinux.org/">Four days on Rails</a></li>
<li><a href="http://manuals.rubyonrails.com/">Rubyonrails.com shelf (helpful manuals)</a></li>
</ul>
<h2>References / Cheatsheets</h2>
<p>Handy references and cheat sheets to bookmark or print out.</p>
<ul>
<li><a href="http://www.railsapi.org/">RailsAPI.org &#8211; PHP.net style documentation for Rails</a></li>
<li><a href="http://noobkit.com/">Noobkit (great Rails doc)</a></li>
<li><a href="http://www.ilovejackdaniels.com/cheat-sheets/ruby-on-rails-cheat-sheet/">Ruby on Rails Cheatsheet</a></li>
<li><a href="http://www.rorsecurity.info/ruby-on-rails-security-cheatsheet/">Rails Security Cheatsheet</a></li>
<li><a href="http://garrettsnider.backpackit.com/pub/367902">Rails Migration Cheat Sheet</a></li>
<li><a href="http://topfunky.com/clients/peepcode/REST-cheatsheet.pdf">REST Cheatsheet (PDF)</a></li>
<li><a href="http://blog.invisible.ch/2006/05/01/ruby-on-rails-reference/">Ruby on Rails reference</a></li>
<li><a href="http://blogs.tech-recipes.com/johnny/rails-quick-reference/">Ruby on Rails quick reference</a></li>
<li><a href="http://topfunky.com/clients/rails/ruby_and_rails_assertions.pdf">Rails Test Assertions (PDF)</a></li>
<li><a href="http://railshandbook.com/">Railshandbook, another big collection of links</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Using Vim as a Complete Ruby on Rails IDE</title>
		<link>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/</link>
		<comments>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 23:11:46 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[editors]]></category>
		<category><![CDATA[gvim]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/</guid>
		<description><![CDATA[

NOTE: If you are experiencing segmentation faults with vim and rails.vim, see this post.
When coding in Ruby on Rails, you&#8217;ll usually be switching between files and running scripts a lot. It can be time-consuming and frustrating coding Rails using a traditional text editor designed for working on big files individually. Vim lets you hop around [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2007/12/vi_traced_with_optical_mouse.jpg" alt="vi traced with an optical mouse" align="left" title="Using Vim as a Complete Ruby on Rails IDE" /></p>
<p><br/><br />
<strong>NOTE:</strong> If you are experiencing segmentation faults with vim and rails.vim, <a href="http://biodegradablegeek.com/2008/08/has-vimrailsvim-been-crashing-lately-heres-why/">see this post</a>.</p>
<p>When coding in Ruby on Rails, you&#8217;ll usually be switching between files and running scripts a lot. It can be time-consuming and frustrating coding Rails using a traditional text editor designed for working on big files individually. Vim lets you hop around within a file with enough speed to activate the cosmic treadmill &#8211; but without a plethora of hacks and custom key mappings, it&#8217;s weak as a Rails IDE. Fortunately, for those of us who are reluctant to kick the vim habit, <a href="http://tpope.net">Tim Pope</a> comes to the rescue with rails.vim; A plugin that makes working with Rails in vim painless and efficient. In this guide, I will explain how to install and use rails.vim, along with a few other plugins you&#8217;ll find useful when writing Rails applications.<br />
<span id="more-42"></span></p>
<p>Vim would certainly fail the <i>mom test</i>, and it&#8217;s not something you can learn in one sitting. Learning vim is a lifelong process, and there are many sites and books that go over it extensively, therefore I won&#8217;t do that here. This guide assumes that you at least know what vim is and can open, edit and save files. Rails.vim works for vim, gvim and <a href="http://cream.sourceforge.net/">Cream</a>, so <i>vim</i> in this article is referring to any of these three, unless otherwise stated.</p>
<p>For those who prefer Emacs, check out <a href="http://steve.yegge.googlepages.com/effective-emacs">Effective Emacs by Steve Yegge</a> and the official Wiki&#8217;s <a href="http://wiki.rubyonrails.org/rails/pages/HowToUseEmacsWithRails">HowTouseEmacsWithRails</a>.</p>
<pre>
<strong>TOC</strong>
<a href="#config">Configuring vim/gvim</a>
<a href="#install">Rails.vim and Other Helpful Plugins</a>
<a href="#usage">Usage and Examples</a>
    <a href="#newp">Starting a New Project and Setting Up The Database</a>
        <a href="#dbsetup">Database.yml Setup</a>
    <a href="#models">Generating Models</a>
    <a href="#migrations">Migrations and :Rake</a>
        <a href="#pattern">:Rmigration <i>pattern</i></a>
        <a href="#related">Related Files and The Command :R and its Mapping ]f</a>
    <a href="#dbext">A Glimpse of the Vim Database Extension Plugin</a>
    <a href="#navigation">Controllers, Views and Interfile Navigation</a>
        <a href="#r">:R or ]f</a>
        <a href="#rview">:Rview <i>[[controller/]view]</i></a>
        <a href="#rfind">:Rfind <i>[name]</i></a>
        <a href="#gf">gf ("goto file")</a>
    <a href="#views">Views and Partials</a>
    <a href="#surround">We've Got You Surrounded</a>
        <a href="#caveats">Caveats</a>
        <a href="#add">Adding Surroundings</a>
        <a href="#rep">Replacing Surroundings</a>
        <a href="#rm">Removing Surroundings</a>
        <a href="#custom">Rails.vim and Custom Surroundings</a>
<a href="#neverends">But Wait, There's More</a>
</pre>
<h2 id="config">Configuring Vim/gvim</h2>
<p>Open your vim configuration file or create one if it doesn&#8217;t exist (i.e., new installation):</p>
<ul>
<li>$HOME/.vimrc in Linux and Mac OS X (might be ~/.gvimrc instead)</li>
<li>$HOME\_vimrc (or $HOME\_gvimrc) in Windows</li>
</ul>
<p>If you&#8217;re having trouble finding out where the config file goes, type &#8220;:version&#8221; and hit enter in vim for a list of compile flags, options and directories vim is using.</p>
<p>Add the following to the file and save it (if you must worry about what they do, see <a href="http://vimdoc.sourceforge.net/htmldoc/">the vimdoc</a>)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">filetype on  &quot; Automatically detect file types.
set nocompatible  &quot; We don't want vi compatibility.
&nbsp;
&quot; Add recently accessed projects menu (project plugin)
set viminfo^=!
&nbsp;
&quot; Minibuffer Explorer Settings
let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1
&nbsp;
&quot; alt+n or alt+p to navigate between entries in QuickFix
map &lt;silent&gt; &lt;m-p&gt; :cp &lt;cr&gt;
map &lt;silent&gt; &lt;m-n&gt; :cn &lt;cr&gt;
&nbsp;
&quot; Change which file opens after executing :Rails command
let g:rails_default_file='config/database.yml'
&nbsp;
syntax enable</pre></td></tr></table></div>

<p>Before installing rails.vim, you may want to glance over some additional (g)vim options I use. Otherwise, skip this optional step and <a href="#install">jump directly</a> to the installation.</p>
<p>The following settings in my config are worth looking over. These can be appended to the same vimrc file as above:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">set cf  &quot; Enable error files &amp; error jumping.
set clipboard+=unnamed  &quot; Yanks go on clipboard instead.
set history=256  &quot; Number of things to remember in history.
set autowrite  &quot; Writes on make/shell commands
set ruler  &quot; Ruler on
set nu  &quot; Line numbers on
set nowrap  &quot; Line wrapping off
set timeoutlen=250  &quot; Time to wait after ESC (default causes an annoying delay)
&quot; colorscheme vividchalk  &quot; Uncomment this to set a default theme
&nbsp;
&quot; Formatting (some of these are for coding in C and C++)
set ts=2  &quot; Tabs are 2 spaces
set bs=2  &quot; Backspace over everything in insert mode
set shiftwidth=2  &quot; Tabs under smart indent
set nocp incsearch
set cinoptions=:0,p0,t0
set cinwords=if,else,while,do,for,switch,case
set formatoptions=tcqr
set cindent
set autoindent
set smarttab
set expandtab
&nbsp;
&quot; Visual
set showmatch  &quot; Show matching brackets.
set mat=5  &quot; Bracket blinking.
set list
&quot; Show $ at end of line and trailing space as ~
set lcs=tab:\ \ ,eol:$,trail:~,extends:&gt;,precedes:&lt;
set novisualbell  &quot; No blinking .
set noerrorbells  &quot; No noise.
set laststatus=2  &quot; Always show status line.
&nbsp;
&quot; gvim specific
set mousehide  &quot; Hide mouse after chars typed
set mouse=a  &quot; Mouse in all modes</pre></td></tr></table></div>

<p>The following optional commands are helpful but require explicit creation of directories and files:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">&quot; Backups &amp; Files
set backup                     &quot; Enable creation of backup file.
set backupdir=~/.vim/backups &quot; Where backups will go.
set directory=~/.vim/tmp     &quot; Where temporary files will go.</pre></td></tr></table></div>

<p>Run vim to make sure it doesn&#8217;t halt to display any warnings or error messages. If it does, check that the specific folders (~/.vim/skeletons and ~/.vim/backups etc) exist and vim has write permission on them.</p>
<h2 id="install">Rails.vim and Other Helpful Plugins</h2>
<p>Installing vim plugins just requires putting files where they belong in vim&#8217;s root directory. We will be installing rails.vim along with some dependency plugins and a few others that make coding Rails in vim much simpler.</p>
<p>Below is a list of all the plugins you need to download and install. If they are <strong>.vim files</strong>, move them into your <i>plugin</i> folder, probably $HOME/.vim/plugin or $VIM\vimfiles\plugin (probably C:\vim\vimfiles\plugin). <strong>Doc files (.txt)</strong> go in $HOME/.vim/doc or vimfiles\doc\. Do the same with the contents of compressed files after you&#8217;ve extracted them. Again, if you&#8217;re having trouble locating where these files should go, type &#8220;:version&#8221; in vim and hit enter.</p>
<ul>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1567">rails.vim</a>: This is the magic. The rails.zip file contains plugin/rails.vim and doc/rails.txt. Both should be moved into their proper location in your root vim directory ($VIM).</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=69">Project</a>: This adds a list of frequently used files to the lefthand side of vim. Rails.vim utilizes this script to create a directory tree of your Rails application. You&#8217;re probably familiar with this feature already, as is a basic feature of most modern IDEs.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=197">genutils 1.20 <strong>(NOT 2.x)</strong></a>: Adds many useful functions</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=171">multvals.vim</a>: genutils depends on this.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=159">minibufexpl.vim</a>: This adds (ugly, but functional) tabs to vim, making it much easier to keep track of the many files you&#8217;ll be working on simultaneously.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=356">dbext.vim</a>: Adds database support to vim. This integrates seemlessly with rails.vim. More on it below.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1697">surround</a>: Surround.vim adds mappings to let you easily work with &#8220;surroundings&#8221; in pairs. Such as { }, &#8221; &#8221; and < >. More on it below.</li>
</ul>
<p>To get the help files working, Rails needs to generate help tags from the txt files you placed in the doc directory. Open vim and in <i>normal</i> (command) mode type the following and hit enter:<br />
<strong>Linux:</strong> :helptags $HOME/.vim/doc<br />
<strong>Windows:</strong> :helptags $VIM\vimfiles\doc</p>
<p>Your directory might differ from the above. In which case, again, check &#8220;:version<enter>&#8221;</p>
<p>Make sure it worked:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:help rails</pre></td></tr></table></div>

<p>For more information on vim&#8217;s help feature, use <strong>:help help</strong> or read about it <a href="http://www.vim.org/htmldoc/various.html#:help">in your browser</a>. For help about a specific command, use :help <i>command</i>. Command can be a vim, rails.vim or other plugin command. For example <i>:help rails</i> or <i>:help rgenerate</i>.</p>
<h2 id="usage">Usage and Examples</h2>
<p>Usage might seem intimidating at first because the plugins have-on top of vim&#8217;s already rich set of functions-added so much more functionality and commands to memorize, but you&#8217;ll quickly realize that getting used to rails.vim is easy due to the natural command names (and tab completion). Let&#8217;s begin by creating a dummy rails project.</p>
<h3 id="newp">Starting a New Project and Setting Up The Database</h3>
<p>In Cream or gvim, you can create projects using the menu </strong>Plugin -> Rails -> Projects -> New</strong>. Alternatively, you can use the <strong>:Rails</strong> command in <i>normal</i> mode. Both the menu option and the :Rails command are wrappers for the native <i>rails</i> application, making it possible to pass them what you would normally pass <i>rails</i> in the console.</p>
<p><i>If you do not specify an absolute path when passing :Rails your project name, the rails application will be generated in the current working directory, usually the directory you were in when you started vim.</i></p>
<p>Let&#8217;s create a new framework named <i>dummy</i>. This command is typed in vim while in command mode (not the mode you type content in) and followed with the Enter key. Change /tmp/ to where ever you want this to reside (I.e., C:\Windows\Temp\):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rails /tmp/dummy</pre></td></tr></table></div>

<p><strong id="dbsetup">Database.yml Setup</strong><br />
The usual rails output will scroll across the screen and you will be dumped at the default file you specified in the vimrc file (g:rails_default_file). This will be README by default. If you haven&#8217;t changed it to database.yml like in my config above, you can jump to the database config file by typing <strong>:Rfind database.yml</strong>.</p>
<p>Put your database information under <i>dummy_development</i> and save as usual (:w). Now creating our dummy_development database is as easy as one short command:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rdbext!</pre></td></tr></table></div>

<p><i>(You can use a database frontend (like the excellent <a href="http://www.phpmyadmin.net">PHPMyAdmin</a>) or the mysql command in a console to create your dummy_development database if you did not install dbext.)</i></p>
<p><strong>Note:</strong> This issues a CREATE DATABASE command on the Rails environment in $RAILS_ENV, which is <i>development</i> by default, but you can have it create the <i>test</i> and <i>production</i> environments as well:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rdbext! test
:Rdbext! production</pre></td></tr></table></div>

<p>The last loaded environment configuration is what will be used throughout the Rails application. To change the environment, just provide the desired one as a parameter to the :Rdbext command (notice lack of bang: <strong>!</strong>). If you&#8217;ve created three environments and want to switch to the test environment:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rdbext test</pre></td></tr></table></div>

<p>This commands opens up a Results tab and displays the results on the bottom of the screen in a new window. Sometimes, this window can be intrusive and downright annoying. To close it, click it and hit <strong>ctrl+w</strong>, let go of both and quickly hit <strong>c</strong>.</p>
<p>For more information, check <strong>:help Rdbext</strong>. More on DBExt later.</p>
<h3 id="models">Generating Models</h3>
<p>If you wish to run something in the application&#8217;s script directory, you can use :Rscript:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rscript about
:Rscript console
:Rscript breakpointer
etc...</pre></td></tr></table></div>

<p>but you will probably never need to, as Rails.vim provides wrappers for most of Rails&#8217; scripts and functions. The names of these will usually be <strong>:R</strong> followed by the name of the script. For example, :Rgenerate, :Rserver, :Rconsole, etcetra&#8230;</p>
<p>:Rgenerate takes the same parameters as Rails&#8217; generate script. Let&#8217;s generate a model named Thing:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rgenerate model Thing</pre></td></tr></table></div>

<p>The model file is automatically loaded and given focus after its creation. Notice that you can still access database.yml via its tab on top of the vim window. Double click a tab to open it, and click it once to give it focus, then hit <strong>d</strong> to close it. Try that now on database.yml (and Results if it&#8217;s still open). More on tabs and the minibufexpl later.</p>
<h3 id="migrations">Migrations and :Rake</h3>
<p>Let&#8217;s edit the model&#8217;s migration file, which is created automatically for each generated model. You have a number of choices for jumping to this file:</p>
<p><strong id="pattern">:Rmigration <i>pattern</i></strong><br />
The optional <i>pattern</i> can be any part of the migration&#8217;s filename (in this case, 001_create_things.rb). You can use <i>things</i> (notice it&#8217;s plural) because it matches the filename:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rmigration things</pre></td></tr></table></div>

<p>The migration number with or without the zeros. All three examples open the same migration:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rmigration 1
:Rmigration 01
:Rmigration 001</pre></td></tr></table></div>

<p>or any string of characters that match part of that migration&#8217;s filename without causing an ambiguity, like 001_crea<strong>te_t</strong>hings.rb:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rmigration te_t</pre></td></tr></table></div>

<p>Rmigration is context aware. It will default to opening the <i>related</i> migration file if executed without a parameter while the model file is open:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rmigration</pre></td></tr></table></div>

<p>More on related files below.</p>
<p><strong>Related files and the command :R and its mapping ]f</strong><br />
The <strong>:R</strong> command or its mapping <strong>]f</strong> open up the related file of whatever is currently open. A related file is something that is usually associated with the file you are opening. This is a construct in rails.vim, and that&#8217;s where the rules are defined. For example, a model&#8217;s related file is its migration. Even though both can be independent (you can have migrations without models and vice versa). Don&#8217;t think about this too much.</p>
<p>Below is an excerpt from <strong>:help rails-related</strong>. It shows a list of what file will be open when :R is issued while the Current File is open:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">&lt;strong&gt;Current File            Related File&lt;/strong&gt;
model            related migration
controller (in method)    template (view)
template (view)            controller (jump to method)
migration            next migration
config/routes.rb        config/environment.rb</pre></td></tr></table></div>

<p>Open the migration file and add the following to the create_table block in the self.up method:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:description</span>, <span style="color:#ff3333; font-weight:bold;">:text</span>
t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:weight</span>, <span style="color:#ff3333; font-weight:bold;">:integer</span></pre></td></tr></table></div>

<p>After writing your self.up, you can use :Rinvert to have self.down automatically generated. You don&#8217;t have to do this here because self.down is already filled in (drop_table), but let&#8217;s try it anyway by creating a test table called &#8220;test&#8221; and using :Rinvert to update self.down. Your self.up should now look like this:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    create_table <span style="color:#ff3333; font-weight:bold;">:things</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
      t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:description</span>, <span style="color:#ff3333; font-weight:bold;">:text</span>
      t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:weight</span>, <span style="color:#ff3333; font-weight:bold;">:integer</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    create_table <span style="color:#ff3333; font-weight:bold;">:test</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span>
      t.<span style="color:#9900CC;">column</span> <span style="color:#ff3333; font-weight:bold;">:hi</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>and after running :Rinvert, your self.down will be:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">down</span>
    drop_table <span style="color:#ff3333; font-weight:bold;">:test</span>
    drop_table <span style="color:#ff3333; font-weight:bold;">:things</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>:Rinvert works great for most commands, even some complex queries, but it can&#8217;t reverse everything. A low level SQL query or a blank self.up might produce an IrreversableMigration error. Let&#8217;s apply our migration to the database by running <strong>:Rake</strong>. It defaults to db:migrate when run in the context of our migration file.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rake</pre></td></tr></table></div>

<h3 id="dbext">A Glimpse of the Vim Database Extension Plugin</h3>
<p>DBExt is powerful and deserves its own paper, but before getting derailed from our main topic, here are some useful DBExt commands:</p>
<p><strong>:DBDescribeTable <i>table</i></strong> outputs a table&#8217;s columns and their data types. Run it now on the <i>things</i> table:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:DBDescribeTable things
&nbsp;
Connection: T(MYSQL)  D(bic_development)  U(username)
Field    Type    Null    Key        Default        Extra
id    int(11)    NO        PRI        NULL        auto_increment
description    text    YES        NULL
weight    int(11)    YES        NULL</pre></td></tr></table></div>

<p><strong>:DBExecSQL <i>query</i></strong> executes low level SQL queries that are either under the cursor, or passed as parameters. Let&#8217;s use it to populate our table:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:DBExecSQL INSERT INTO things VALUES (1, 'Worlds fattest man', 1200);
:DBExecSQL INSERT INTO things VALUES (2, 'Four quarter pounders', 1);</pre></td></tr></table></div>

<p>Let&#8217;s view the contents of the <i>things</i> table:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:DBSelectFromTable things</pre></td></tr></table></div>

<p><i>If the results window on the bottom gets stuck, click it and then hit ctrl+w the c to close it.</i></p>
<p>Read the extensive help file using <strong>:help DBExt</strong>.</p>
<h3 id="navigation">Controllers, Views and Interfile Navigation</h3>
<p>Let&#8217;s create a controller and a skeleton for a method named index:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rgenerate controller Things index</pre></td></tr></table></div>

<p>We want to display all the records from our Thing table in our index view. Let&#8217;s add some code this controller&#8217;s index method:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> index
    <span style="color:#0066ff; font-weight:bold;">@people</span> = Thing.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>For test purposes later, add the following method to ThingsController, under the index method:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> viewless
    <span style="color:#0066ff; font-weight:bold;">@cast</span> = <span style="color:#996600;">&quot;Cloud Strife&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Since we passed a method name (<i>index</i>) to :Rgenerate, Rails has automatically generated a view for that method. We have a number of ways to navigate to that view:</p>
<p><strong id="r">:R or ]f</strong><br />
The Related command was discussed above under <a href="#migrake">Migrations and :Rake</a>. A controller can have many views, so :R looks at the current method the cursor resides in to look up what view to open. Place the cursor anywhere in the index method and type :R (or hit <i>]f</i>) to open up index.rhtml.</p>
<p>This command only works if the related file exists. If the view doesn&#8217;t exist, you&#8217;ll get an &#8220;E345: Can&#8217;t find file &#8230; in path&#8221; error. Try this by putting the cursor on the viewless method before running the :R command again.</p>
<p>You can use :RS to split (what the S stands for) the current window into two, allowing you to view and edit both the controller and view simultaneously.</p>
<p><strong id="rview">:Rview <i>[[controller/]view]</i></strong><br />
Typed with no arguments, this command behaves the same as :R. If that view doesn&#8217;t exist, you can specify a name, either by the full path or just the view name and extension, and that view will be created.</p>
<p>For example, let&#8217;s create a view on the fly for the viewless method (extension is mandatory):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rview viewless.rhtml</pre></td></tr></table></div>

<p>We haven&#8217;t defined a controller above, so by default, :Rview assumes it is for the current controller. It will go into app/views/things/. We could specify a controller by using <strong>:Rview controller/view_name.extension</strong>.</p>
<p>Note that the file is only generated in memory and must be saved to disk explicitly (:w).</p>
<p><strong>Alternating between files</strong></p>
<p>A lot of times, you&#8217;ll be working exclusively on two files, back and forth. To alternate between the current file and the last file you were editing, use <i>CTRL+^</i> (although in practice, you&#8217;re actually just hitting CTRL+6).</p>
<p>Rails.vim also has an <i>alternate</i> command (:A or the [f mapping), similar in function to related. It usually takes you to the current file's test file.</p>
<p>From <strong>:help rails-alternate</strong>, this tells you what the alternate file will be for the Current File open:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">&lt;strong&gt;Current file      Alternate file&lt;/strong&gt;
model                               unit test
controller (in method)    functional test
template (view)              helper
migration                         previous migration
config/routes.rb               config/database.yml</pre></td></tr></table></div>

<p><strong id="rfind">:Rfind <i>[name]</i></strong><br />
Like vim&#8217;s :find command, this one also opens a file it finds either by the name you pass it or by whatever is under the cursor (behaves similarly to <i>gf</i>, more on that below). Rails.vim enhances the native command by giving it the ability to find files by controller and model name.</p>
<p>This opens the Thing model:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rfind thing</pre></td></tr></table></div>

<p>This opens the Things controller (case sensitive):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rfind ThingsController</pre></td></tr></table></div>

<p>This opens the index.rhtml view (you must be in the ThingsController):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:Rfind index</pre></td></tr></table></div>

<p><strong id="gf">gf (&#8220;goto file&#8221;)</strong><br />
In rails.vim, the <i>gf</i> mapping is used to jump to a file under the cursor taking context into account. The following is from <strong>:help rails-gf</strong>:<br />
&#8212;<br />
Example uses of gf, and where they might lead. <i>(* indicates cursor position)</i><br />
    Pos*t.find(:first)<br />
    app/models/post.rb</p>
<p>    has_many :c*omments<br />
    app/models/comment.rb</p>
<p>    link_to &#8220;Home&#8221;, :controller => :bl*og<br />
    app/controllers/blog_controller.rb</p>
<p>    <%= render :partial => &#8217;sh*ared/sidebar&#8217; %><br />
    app/views/shared/_sidebar.rhtml</p>
<p>    <%= stylesheet_link_tag :scaf*fold %><br />
    public/stylesheets/scaffold.css</p>
<p>    class BlogController < Applica*tionController<br />
    app/controllers/application.rb</p>
<p>    class ApplicationController < ActionCont*roller::Base<br />
    .../action_controller/base.rb</p>
<p>    fixtures :pos*ts<br />
    test/fixtures/posts.yml</p>
<p>    layout :pri*nt<br />
    app/views/layouts/print.rhtml</p>
<p>    # In the Blog controller<br />
    def li*st<br />
    app/views/blog/list.rhtml</p>
<p>    <%= link_to "New", new_comme*nt_path %><br />
    app/controllers/comments_controller.rb (jumps to def new)</p>
<p>In the last example, the controller and action for the named route are determined by evaluating routes.rb as Ruby and doing some introspection. This means code from the application is executed. Keep this in mind when navigating unfamiliar applications.<br />
&#8212;</p>
<p>Add the following to the index.rhtml view file, overwriting the default code already in there:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;h1&gt;All the things in our Thing table&lt;/h1&gt;
&amp;lt;h1&amp;gt;All the things in our Thing table&amp;lt;/h1&amp;gt;
&lt;ol&gt;
  &lt;% @stuff.each do |x| %&gt;
    &lt;li&gt;
    &lt;%= x.description %&gt; (weight: &lt;%= x.weight %&gt; pound(s))
    &lt;/li&gt;
  &lt;% end %&gt;
&lt;/ol&gt;</pre></td></tr></table></div>

<h3 id="views">Views and Partials</h3>
<p>The :Rextract command (:Rpartial is deprecated) makes creating <a href="http://wiki.rubyonrails.org/rails/pages/Partials">partials</a> a breeze. You choose a range of lines and supply the command a name you want for the new partial. The lines get replaced by a call to render the newly created partial, which now holds the lines that were extracted.</p>
<p>Let&#8217;s try using this by delegating output code between the &lt;li&gt; and &lt;/li&gt; tags in our index.rhtml view into a partial named &#8220;ppp&#8221; by explicitly defining the line numbers (your line numbers might not match. Alter it accordingly):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="text" style="font-family:monospace;">:5,5Rextract ppp</pre></td></tr></table></div>

<p>A new partial with the filename _ppp.rhtml is created containing line #5 from our index.rhtml view. Line #5 now is a call to render the newly created ppp view: <i><%= render :partial => &#8216;ppp&#8217; %></i> &#8211; The new partial only exists in memory at this point, and must be saved to disk explicitly.</p>
<p>This could also have been done in visual mode, selecting the lines we want extracted visually instead of by line numbers. Place the cursor at the beginning of the line, press v to enter visual mode and hit &#8216;$&#8217; (shift+4) to jump to the end of the line, selecting the entire line along the way. Now hit : and type :Rextract ppp (it will come out as <i>:&#8217;<,'>Rextract ppp</i>) and hit enter. Same effect as above.</p>
<h3 id="surround">We&#8217;ve Got You Surrounded</h3>
<p>Whether you&#8217;re coding, writing, or editing, Tim Pope&#8217;s surround plugin is very useful. It adds vim mappings to add, remove or edit &#8220;surroundings.&#8221; A surrounding is a pair of parentheses, brackets, quotes, tags, etc.</p>
<p>Some mappings require that you press the first few keystrokes within a second. For full functionality, make sure you&#8217;re using vim 7 or greater. Let&#8217;s begin by making sure the plugin is installed and works properly by testing a command:</p>
<p>Type <i>(hello world)</i> into vim, and with your cursor anywhere in that phrase, hit <strong>ds(</strong>. If <i>(hello world)</i> turns to <i>hello world</i>, the plugin is working fine. If not, then make sure you&#8217;re installed it correctly and are using Vim 7.0.</p>
<p><strong id="caveats">Caveats</strong><br />
* The keystrokes need to be typed in succession very fast. The <i>timeoutlen</i> setting in the vim config file can impair the ys* functions. The smaller the value for <i>timeoutlen</i>, the less time you have in between keystrokes to ensure vim catches the command. I set <i>timeoutlen</i> to 200, but put 250 as the value in the example vimrc at the beginning of this tutorial. Delete this setting or use a higher value (300+) if you&#8217;re having trouble using commands like yssa or yss.</p>
<p>* b, B, r, and a are aliases for ), }, ], and > respectively, and t represents a pair of HTML or XML tags.</p>
<p>* In the examples below, the cursor position is represented by an asterisk (*).</p>
<p><strong id="add">Adding Surroundings</strong><br />
You can add a pair of surroundings around a word, line, sentence, paragraph or a specific number of characters.</p>
<p>Adding quotes around a word:<br />
<u>Old text | Command | Result</u><br />
H*eya world | ysiw&#8221; | &#8220;Heya&#8221; world</p>
<p>Adding a pair of tags around a word:<br />
<u>Old text | Command | Result</u><br />
I*talic text | ysiw&lt;i&gt; | &lt;i&gt;Italic&lt;/i&gt; text</p>
<p>Adding arrows around a sentence:<br />
<u>Old text | Command | Result</u><br />
Clandestin*e operation | yssa | &lt;Clandestine operation&gt;</p>
<p>An angry Kenny face:<br />
<u>Old text | Command | Result</u><br />
*>< | yss)yss)yss( | ( ((><)) )<br />
<i>(notice usage of parantheses in the command. Using the opening bracket adds spaces between the target being surrounded.)</i></p>
<p><strong id="rep">Replacing Surroundings</strong><br />
Replacing parentheses with quotes in a word:<br />
<u>Old text | Command | Result</u><br />
(qu*ack) quack | cs(&#8221; | &#8220;quack&#8221; quack</p>
<p>Changing those double quotes to a pair of tags:<br />
<u>Old text | Command | Result</u><br />
&#8220;q*uack&#8221; quack | cs&#8221;<qqqqq> | <qqqqq>quack</qqqqq> quack</p>
<p>Changing those tags to brackets:<br />
<u>Old text | Command | Result</u><br />
&lt;qqqqq&gt;q*uack&lt;/qqqqq&gt; quack | cstr | [quack] quack</p>
<p><strong id="rm">Removing Surroundings</strong><br />
Remove quotes around a word:<br />
<u>Old text | Command | Result</u><br />
Hash &#8220;eater*&#8221;  | ds&#8221; | Hash eater</p>
<p>Remove tags around a word:<br />
<u>Old text | Command | Result</u><br />
&lt;h1&gt;h*ead&lt;/h1&gt; | dst | head</p>
<p>Removing multiple surroundings around a sentence:<br />
<u>Old text | Command | Result</u><br />
{&#8220;(iiight)&#8221;} | ds(ds&#8221;dsB | iiight</p>
<p><strong id="custom">Rails.vim and Custom Surroundings</strong><br />
Rails.vim makes use of the surround plugin by adding a few useful surroundings. These only work when rails.vim is enabled (when RoR projects are open):</p>
<p><u>Old text | Command | Result</u><br />
*end | yss= | <%= end %></p>
<p><u>Old text | Command | Result</u><br />
*end | yss- | <%= end -%></p>
<p><u>Old text | Command | Result</u><br />
*cat | yss# | <%# cat %></p>
<p>You can create custom surroundings. Here&#8217;s one example:<br />
:let g:surround_65 = &#8220;&lt;a href=\&#8221;\&#8221;&gt; \r &lt;/a&gt;&#8221;</p>
<p>65 is the ASCII decimal for the &#8216;A&#8217; character. You can use <a href="http://web.cs.mun.ca/~michael/c/ascii-table.html">an ascii table</a> to find the decimal corresponding to the character you want to use.</p>
<p>Usage:<br />
<u>Old text | Command | Result</u><br />
I*Shot The Sheriff | yssA | &lt;a href=&#8221;"&gt; I Shot The Sheriff &lt;/a&gt;</p>
<p>Be sure to read the extensive help files :help surround and :help rails-surround. They provide details and examples.</p>
<h2 id="neverends">But Wait, There&#8217;s More</h2>
<p>We&#8217;ve merely scratched the surface of rails.vim here. Be sure to check out the <a href="http://rails.vim.tpope.net/">Official rails.vim Website</a>, the <a href="http://tpope.net">author&#8217;s site</a>, and the external links I provided below. For those looking for a more user-friendly, &#8220;real&#8221; GUI-based (as opposed to a TUI) IDE based around vim, try out <a href="http://vimmate.rubyforge.org/">VimMate</a>.</p>
<div class="externallinks" style="font-size:80%;">
<strong>External links</strong></p>
<ul>
<li><a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails">How To Use Vim With Rails (official RoR wiki)</a></li>
<li><a href="http://ruby.about.com/od/railsvim/railsvim_Ruby_on_Rails_IDE.htm">Rails.vim RoR IDE (About.com)</a></li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1658">NERD tree &#8211; A great plugin that adds a nested file explorer to vim, much like the Project plugin</a></li>
<li><a href="http://eigenclass.org/hiki.rb?rcodetools">rcodetools</a></li>
</ul>
<p><i>Thanks to <a href="http://flickr.com/photos/heyvikram/152929481/">_vikram</a> for the vi photo. It was done using an optical mouse and a long exposure. He was actually attempting to spell out &#8220;vik&#8221;</i>
</div>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
	</channel>
</rss>
