<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title>Sepcot.com Blog</title>
    <description>This feed shows the blog updates on Sepcot.com.</description>
    <link>http://www.sepcot.com/</link>
    <copyright>Copyright 2006 - 2008, Michael J. Sepcot</copyright>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <language>en-us</language>
    <atom:link href="http://www.sepcot.com/blog/feed" rel="self" type="application/rss+xml"/>
    <item>
      <title>Countdown to Second Skydive</title>
      <link>http://www.sepcot.com/blog/2008/07/countdown-second-skydive</link>
      <description>&lt;p&gt;After reading a few skydiving books*, I have been itching to jump out of a plane again. Well, the date has finally been set, the weekend of July 18th I will be performing my second tandem skydive. After I complete my second tandem jump, I will be eligible to enroll in the &lt;a href="http://www.skydivechicago.com/Services/StudentJumpers/tabid/111/Default.aspx#LicenseInAWeek"&gt;A-License In A Week&lt;/a&gt; course at Skydive Chicago! I &lt;em&gt;really&lt;/em&gt; want to be able to get my Class A Skydiving License this Summer...&lt;/p&gt;

&lt;p&gt;* List of skydiving books I've read so far:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.amazon.com/Parachuting-Skydivers-Handbook-Dan-Poynter/dp/1568601417/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1215030166&amp;sr=8-1"&gt;Parachuting: The Skydiver's Handbook, 10th Edition&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.amazon.com/Mental-Training-Skydiving-Life-Derosalia/dp/0970776306/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1215030148&amp;sr=8-1"&gt;Mental Training for Skydiving and Life&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.amazon.com/Base-66-Story-Fear-Freefall/dp/0595335101/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1215030191&amp;sr=8-1"&gt;Base 66: A Story of Fear, Fun, and Freefall&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Wed, 02 Jul 2008 20:24:04 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/07/countdown-second-skydive</guid>
    </item>
    <item>
      <title>Finally Up At Github</title>
      <link>http://www.sepcot.com/blog/2008/06/finally-up-at-github</link>
      <description>&lt;p&gt;After dragging my feet for a while, I finally created a &lt;a href="http://github.com"&gt;Github&lt;/a&gt; account during &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt;. And after more dragging of my feet, I have finally created my first repository; the code for my &lt;a href="http://github.com/msepcot/svn_task/tree/master"&gt;SVN Rake Tasks&lt;/a&gt; is now publicly available, so feel free to fork the master branch and make some additions!&lt;/p&gt;

&lt;p&gt;More code moving to Github soon...&lt;/p&gt;</description>
      <pubDate>Wed, 18 Jun 2008 14:46:17 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/06/finally-up-at-github</guid>
    </item>
    <item>
      <title>RailsConf 2008 Recap</title>
      <link>http://www.sepcot.com/blog/2008/06/railsconf-2008-recap</link>
      <description>&lt;p&gt;RailsConf 2008 has come and gone, I'm now back at work and trying to collect my thoughts on the events of the past few days. I really enjoyed the keynotes at RailsConf, I am glad that they were more than a sales pitch, it felt more like the "zen of coding" with &lt;a href="http://www.joelonsoftware.com"&gt;Joel Spolsky&lt;/a&gt; talking about the aesthetic building blocks of good software, &lt;a href="http://loudthinking.com/"&gt;David Heinemeier Hansson&lt;/a&gt; stressing the importance of taking time away from programming to grow as an individual, and &lt;a href="http://www.threeriversinstitute.org/Kent%20Beck.htm"&gt;Kent Beck&lt;/a&gt; telling stories of the twenty year progress in Design Patterns, Developer Testing, and Extreme Programming. Overall, a good time was had. Below are my notes, briefly polished, from the sessions I attended with a massive amount of links to further resources on the net.&lt;/p&gt;

&lt;h2&gt;Birds of a Feather: Presenter Class&lt;/h2&gt;
&lt;p&gt;Presented by: &lt;a href="http://www.subelsky.com/"&gt;Mike Subelsky&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The idea of a &lt;em&gt;Presenter Class&lt;/em&gt; is to help &lt;a href="http://www.youtube.com/watch?v=91C7ax0UAAc"&gt;prevent controller obesity&lt;/a&gt; and &lt;a href="http://www.youtube.com/watch?v=ku3QkWcPSEw"&gt;keep views stupid&lt;/a&gt; through an abstraction layer to keep the state of the view.&lt;/p&gt;
&lt;p&gt;When are Presenter Classes useful?&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Forms with multiple models&lt;/li&gt;
  &lt;li&gt;Complicated view logic&lt;/li&gt;
  &lt;li&gt;Complex retrieval&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Presenter Class resources:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://blog.otherinbox.com/2008/06/railsconf---pre.html"&gt;Presenter Classes and the Power of Abstraction&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://blog.jayfields.com/2007/03/rails-presenter-pattern.html"&gt;Rails Presenter Pattern&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Lightning Talks (All Sessions)&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.5valleys.com/posts/56-GateKeeper-attachment-fu"&gt;GateKeeper&lt;/a&gt; - permission control per model&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://varnish.projects.linpro.no/"&gt;Varnish&lt;/a&gt; - page caching outside of Rails&lt;/li&gt;
  &lt;li&gt;Prabode Weebadde - Optimal Paging Plugin, &lt;a href="http://rubyforge.org/projects/pro-paging/"&gt;pro-paging&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/schacon/git-lighthouse/tree/master"&gt;git-lighthouse&lt;/a&gt; - Command line utility to work with Git and Lighthouse&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://sharedcopy.com/"&gt;SharedCopy&lt;/a&gt; - collaborative annotation service, add and share comments about any web page&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://fanchatter.com/"&gt;FanChatter.com&lt;/a&gt; - uses &lt;a href="http://peepcode.com/products/mms2r-pdf"&gt;MMS2R&lt;/a&gt; to take cell phone photos that get placed on a JumboTron (active now with the Minnesota Twins)&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.acunote.com/open-source/javascript-keyboard-shortcuts"&gt;JavaScript Keyboard Shortcuts&lt;/a&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/forum/forum.php?forum_id=9909"&gt;MiniUnit&lt;/a&gt; - Drop in replacement for TestUnit - includes specs and mocks&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/mwarnock/activesesame/tree/master"&gt;ActiveSesame&lt;/a&gt; - HTML Sesame Interface to Triple Store (ORM for RDF/OWL)&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://blog.pastie.org/2008/05/pastie-lightnin.html"&gt;Pastie&lt;/a&gt; - TextMate Integration added&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rad.rubyforge.org"&gt;RAD&lt;/a&gt; - Ruby Arduino Development&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://scrumninja.com/"&gt;Scrum Ninja&lt;/a&gt;, hosted project management&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/rubber/"&gt;Rubber&lt;/a&gt; - capistrano plugin to get up and running on EC2&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://blog.evanweaver.com/files/doc/fauna/ultrasphinx/files/README.html"&gt;UltraSphinx&lt;/a&gt; - Geo-distance searching with sphinx&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://primospot.com/"&gt;Primospot&lt;/a&gt; - find parking spots in NYC&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/fatjam/acts_as_revisable/tree/master"&gt;acts_as_revisable&lt;/a&gt; - versioning system per model&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://earfl.com"&gt;earfl&lt;/a&gt; - Voice Flickr&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.wesabe.com/"&gt;wesabe&lt;/a&gt; - get API access to financial services (personal bank accounts, etc.)&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.railsbrain.com"&gt;RailsBrain&lt;/a&gt; - JavaScript enhanced API docs.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://blog.chak.org/2008/06/01/activeresource-kool-aid/"&gt;ActiveResource Kool-Aid&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/djwonk/method_trails"&gt;MethodTrails&lt;/a&gt; - uses &lt;a href="http://www.graphviz.org/"&gt;graphvis&lt;/a&gt; and Ruby 1.9 to generate a representational map of method processing&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.buildingwebapps.com/"&gt;BuildingWebApps.com&lt;/a&gt; - an information portal for web application developers&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/noelrappin/rails-iui"&gt;iPhone on Rails&lt;/a&gt; - (on view wraps iUi toolkit)&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://dev.smartleaf.com/permissioning"&gt;Permissioning&lt;/a&gt; - User has_many Roles which are a group of Permissions&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/seancribbs/restful_workflow"&gt;RESTful Workflow&lt;/a&gt; - Interview Style Workflow&lt;/li&gt;
  &lt;li&gt;REST with Rails &amp; ejabberd - send SMS through web based Jabber client&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/lazymethods/"&gt;Lazy Methods&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/pseudocursors/"&gt;Pseudo Cursors&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/seamlessdbpool/"&gt;Seamless Database Pool&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://code.google.com/p/kablame"&gt;KABLAME!!&lt;/a&gt; - count test code per user&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/bmabey/rspec-story-bundle"&gt;RSpec Story Runner, Textmate Bundle&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://geminstaller.rubyforge.org"&gt;GemInstaller&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/joannou/nstableviewftw"&gt;NSTableViewFTW&lt;/a&gt; - iTunes like tables&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://github.com/pmark/jivepages"&gt;jivepages&lt;/a&gt; - YUI Grid Style, Real-Time Editor&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://www.urbanhonking.com/ideasfordozens/2008/06/railsconf-2008-lightning-talks.html"&gt;RailsConf 2008 Lightning Talk Summaries&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;DataMapper&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://datamapper.org/"&gt;DataMapper&lt;/a&gt; is an Object Relation Mapper (ORM) that improves on the ActiveRecord concept. DataMapper adds &lt;code&gt;repository(:legacy)&lt;/code&gt; type syntax to change object mappings and allows you to copy between data repositories.&lt;/p&gt;

&lt;h2&gt;Profitable Programmer: Creating Successful Side Projects&lt;/h2&gt;
&lt;p&gt;Main Topics: Idea, Implementation, Promotion, Success&lt;/p&gt;

&lt;h2&gt;23 Hacks&lt;/h2&gt;
&lt;p&gt;This presentation was a collection of random code to do fun things. Examples:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Ruby Ook Interpreter&lt;/li&gt;
  &lt;li&gt;Changing LCD messages on HP printers&lt;/li&gt;
  &lt;li&gt;Haskell code that plays &lt;a href="http://en.wikipedia.org/wiki/Moola_(game)"&gt;Moola&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/gitjour/"&gt;gitjour&lt;/a&gt; (written during RailsConf 2008) - Bonjour-based method of getting git repositories and cloning them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Asynchronous Processing&lt;/h2&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Using &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/"&gt;attachment_fu&lt;/a&gt; to store files locally on the filesystem before uploading to the S3 cloud&lt;/li&gt;
  &lt;li&gt;Using &lt;code&gt;thread.join&lt;/code&gt; to query multiple services and wait for all to finish before returning&lt;/li&gt;
  &lt;li&gt;Using &lt;a href="http://spawn.rubyforge.org/svn/spawn/"&gt;spawn&lt;/a&gt; to fork off background processes&lt;/li&gt;
  &lt;li&gt;Using task storage in the database or message queue and trigger jobs via daemons or cron&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://simple-daemon.rubyforge.org/"&gt;simple-daemon&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyforge.org/projects/cronedit/"&gt;CronEdit&lt;/a&gt; - control cron through ruby&lt;/li&gt;
  &lt;li&gt;Others: &lt;a href="http://backgroundrb.rubyforge.org/"&gt;BackgroundDRb&lt;/a&gt;, &lt;a href="http://rubyforge.org/projects/ap4r/"&gt;AP4R&lt;/a&gt; (Asynchronous Processing for Ruby), &lt;a href="http://codeforpeople.rubyforge.org/svn/bj/trunk/README"&gt;Bj&lt;/a&gt; (Background Job - store in DB tables)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Small Things, Loosely Joined, Written Fast&lt;/h2&gt;
&lt;p&gt;Integrate small modules to get the job done faster. Examples:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://code.google.com/p/rubycas-server/"&gt;RubyCAS&lt;/a&gt; - a Single Sign-On Server (that works with Active Directory). RubyCAS is a centralized service that must sit behind firewall. Rails integrated documentation at: &lt;a href="http://rubycas-client.rubyforge.org/"&gt;http://rubycas-client.rubyforge.org/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://activemq.apache.org/ruby.html"&gt;ActiveMQ&lt;/a&gt; or &lt;a href="http://code.google.com/p/activemessaging/wiki/ActiveMessaging"&gt;ActiveMessaging&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;What To Do when Mongrel Stops Responding to Your Requests and Ruby Doesn't Want to Tell You About It&lt;/h2&gt;
&lt;p&gt;Ruby/Rails Debugging Tools:&lt;/p&gt;
&lt;p&gt;Use the C debugger: &lt;code&gt;gdb -p PID&lt;/code&gt;. Then you can play around with the options:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;bt&lt;/code&gt; - C backtrace&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;eval "RAILS_ENV"&lt;/code&gt; - eval puts to STDOUT, you will see it in your Rails log&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;eval "caller"&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;eval "ObjectSpace.each_object(String) { |s| p s }"&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;rb_object_counts&lt;/code&gt; - macro that shows summary of ruby objects&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;rb_finish&lt;code&gt; - macro that gets you a cleaner environment&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;rb_bt&lt;/code&gt; - Ruby backtrace&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;rb_raise&lt;/code&gt; - macro to raise exceptions&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;redirect_stdout&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;restore_stdout&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;"Design Patterns" in Ruby&lt;/h2&gt;
&lt;p&gt;Important design book: &lt;a href="http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1212526540&amp;sr=8-1"&gt;Design Patterns: Elements of Reusable Object-Oriented Software&lt;/a&gt; (the GoF or Gang of Four book)&lt;/p&gt;
&lt;p&gt;GoF Patterns:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;iterator&lt;/strong&gt;: sequential access of objects in a collection (Ruby's &lt;code&gt;each&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;command&lt;/strong&gt;: something that can be executed (closures or proc) that support undo operations (create a command class with undo functions) - &lt;a href="http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html"&gt;Steve Yegge: Execution in the Kingdom of Nouns&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;strategy&lt;/strong&gt;: let algorithms vary independently by caller (Ruby's mixins)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;interpreter&lt;/strong&gt;: create grammar/lexer/parser (or use DSLs in Ruby as an embedded interpreter)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;adapter&lt;/strong&gt;: create a class that wraps another by adding methods to allow it to work with something else (Ruby allows you to re-open a class)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;state&lt;/strong&gt;: allow an object to change its behavior when its internal state changes (Ruby allows mixin behavior, the &lt;a href="http://www.somethingnimble.com/bliki/mixology"&gt;mixology&lt;/a&gt; gem allows unmixing)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dynamic Language Patterns:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;null object&lt;/strong&gt;: use object representing null that acts like null, no special cases (Ruby's &lt;code&gt;NilClass&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;aridifier&lt;/strong&gt;: remove duplication - Book: &lt;a href="http://pragprog.com/the-pragmatic-programmer"&gt;Pragmatic Programmer&lt;/a&gt; by Andrew Hunt and David Thomas introduced the concept of DRY (Don't Repeat Yourself)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Traditional design patterns rely heavily on structure to solve problems. Dynamic languages use language facilities to create simpler solutions.&lt;/p&gt;

&lt;h2&gt;De-Railing: Smashing the Rails Stack&lt;/h2&gt;
&lt;p&gt;Beware of SQL Injection, &lt;code&gt;find_by_sql&lt;/code&gt;, &lt;code&gt;execute&lt;/code&gt;, &lt;code&gt;limit&lt;/code&gt;, &lt;code&gt;offset&lt;/code&gt;, &lt;code&gt;group_by&lt;/code&gt;, and &lt;code&gt;order&lt;/code&gt; are not sanitized by Rails. Take advantage of the &lt;code&gt;quote()&lt;/code&gt; function to sanitize user input (for SQL).&lt;/p&gt;
&lt;p&gt;Cross Site Scripting preventive measures: SafeERb, XSS Shield, Manual Escaping with &lt;code&gt;h()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://opensource.thinkrelevance.com/wiki/tarantula"&gt;Tarantula&lt;/a&gt; plugin crawls everything and performs form fuzzing.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Don't let a ninja get your neck&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;add firewall script that blocks all non used ports&lt;/li&gt;
  &lt;li&gt;don't allow the root user to login remotely&lt;/li&gt;
  &lt;li&gt;more your SSH port to a non-standard place&lt;/li&gt;
  &lt;li&gt;demand strong passwords for all your users&lt;/li&gt;
  &lt;li&gt;turn off password authentication entirely and use SSH keys&lt;/li&gt;
  &lt;li&gt;monitor your server logs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Security Resources:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://rubythis.blogspot.com/2006/11/rails-security-checklist.html"&gt;http://rorsecurity.info&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubythis.blogspot.com/2006/11/rails-security-checklist.html"&gt;http://owasp.org&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubythis.blogspot.com/2006/11/rails-security-checklist.html"&gt;http://quarkruby.com/2007/9/20/ruby-on-rails-security-guide&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubythis.blogspot.com/2006/11/rails-security-checklist.html"&gt;http://rubythis.blogspot.com/2006/11/rails-security-checklist.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Advanced Active Record Techniques: Best Practice Refactoring&lt;/h2&gt;
&lt;p&gt;Key Points: use callbacks and move business logic to models.&lt;/p&gt;</description>
      <pubDate>Tue, 03 Jun 2008 21:41:45 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/06/railsconf-2008-recap</guid>
    </item>
    <item>
      <title>Custom Subversion Rake Tasks, Part II</title>
      <link>http://www.sepcot.com/blog/2008/05/svn-rake-tasks-2</link>
      <description>&lt;p&gt;In this long overdue follow up to &lt;a href="http://www.sepcot.com/blog/2008/04/svn-rake-tasks-1"&gt;Custom Subversion Rake Tasks, Part I&lt;/a&gt;, I will guide you through the remainder of my custom Subversion Rake Tasks (&lt;code&gt;svn:add&lt;/code&gt;, &lt;code&gt;svn:delete&lt;/code&gt;, &lt;code&gt;svn:update&lt;/code&gt;, &lt;code&gt;svn:commit&lt;/code&gt;, and &lt;code&gt;svn:status&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;rake svn:add&lt;/h3&gt;

&lt;div&gt;&lt;code class="block"&gt;
task :add do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = `svn status`.split("\n").find_all{ |f| f =~ /^\?/ }.collect { |f| f.split()[1] }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts `svn add #{files.join(" ")} --force` unless files.empty?&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Add new files (svn status of '?') to the Subversion repository. We perform an &lt;code&gt;svn status&lt;/code&gt; call, split the response string into an array and search the array for any line that starts with a '?'. For each line that we find, we split the string to store only the filename. To perform the &lt;code&gt;svn add&lt;/code&gt; in one line, we join all of our filenames with a space.&lt;/p&gt;

&lt;h3&gt;rake svn:commit&lt;/h3&gt;

&lt;div&gt;&lt;code class="block"&gt;
task :commit =&gt; [:add, :delete, :update] do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;comment = ENV['comment'] || ENV['m']&lt;br /&gt;
&amp;nbsp;&amp;nbsp;comment = '[rake svn:commit with no comment]' if not comment or '' == comment&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts `svn commit -m '#{comment}'`&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Commit files to the Subversion repository. To add comments to our commit we use &lt;code&gt;rake svn:commit m="message"&lt;/code&gt; or more detailed, &lt;code&gt;rake svn:commit comment="message"&lt;/code&gt;. This task will perform &lt;code&gt;svn:add&lt;/code&gt; and &lt;code&gt;svn:delete&lt;/code&gt; to get a complete commit, and &lt;code&gt;svn:update&lt;/code&gt; to get the latest code, check for conflicts, and run our rake tests to ensure a clean commit.&lt;/p&gt;

&lt;h3&gt;rake svn:delete&lt;/h3&gt;

&lt;div&gt;&lt;code class="block"&gt;
task :delete do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = `svn status`.split("\n").find_all{ |f| f =~ /^\!/ }.collect { |f| f.split()[1] }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts `svn delete #{files.join(" ")} --force` unless files.empty?&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Remove deleted files (svn status of '!') from the Subversion repository. Implementation is the same as &lt;code&gt;svn:add&lt;/code&gt; above.&lt;/p&gt;

&lt;h3&gt;rake svn:status&lt;/h3&gt;

&lt;div&gt;&lt;code class="block"&gt;
task :status do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = `svn status`.split("\n")&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;modified = files.grep /^M/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts "", "Changed Files", "-------------------------", modified unless modified.empty?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = files - modified&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;added = files.grep /^(A|\?)/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts "", "Files to Add", "-------------------------", added unless added.empty?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = files - added&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;deleted = files.grep /^(D|!)/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts "", "Files to Delete", "-------------------------", deleted unless deleted.empty?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = files - deleted&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts "", "UNKNOWN ACTION", "-------------------------", files unless files.empty?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts ""&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Show the status of your local files as compared to the Subversion repository, grouped by Modified, Added, Deleted, and Unknown. An example of 'unknown' is svn externals (svn status 'X'), where we just let svn do it's thing.&lt;/p&gt;

&lt;h3&gt;rake svn:update&lt;/h3&gt;

&lt;div&gt;&lt;code class="block"&gt;
task :update do&lt;br /&gt;
&amp;nbsp;&amp;nbsp;files = `svn up`&lt;br /&gt;
&amp;nbsp;&amp;nbsp;puts files&lt;br /&gt;
&amp;nbsp;&amp;nbsp;raise "One or more conflicts found." unless files.grep(/^C/).empty?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Rake::Task["db:migrate"].invoke&lt;br /&gt;
&amp;nbsp;&amp;nbsp;Rake::Task[:test].invoke&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Update files from the Subversion repository, raises an error if conflicts (svn status 'C') were found that could not be merged (svn status 'G'). If the &lt;code&gt;svn up&lt;/code&gt; goes well, we rake the database if needed and run our test suite to ensure everything is kosher.&lt;/p&gt;

&lt;p&gt;Wheh! That wasn't so bad, I don't know why it took me over a month to get this out. Well, I'm off to &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; tomorrow. Going to try to take in some of the city (Portand, Oregon) tomorrow night, before all of the Rails madness starts in with the Tutorial Sessions on Thursday :)&lt;/p&gt;

&lt;h4&gt;Files&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Github Repository: &lt;a href="http://github.com/msepcot/svn_task/tree/master"&gt;http://github.com/msepcot/svn_task/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Tue, 27 May 2008 21:15:10 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/svn-rake-tasks-2</guid>
    </item>
    <item>
      <title>Photos from Wayne and Shalese's Birthday Party</title>
      <link>http://www.sepcot.com/blog/2008/05/Wayne-Shalese-Birthday-Party</link>
      <description>&lt;p&gt;I have updated my &lt;a href="http://flickr.com/photos/sepcot/sets/72157594550779490/"&gt;Special Occasion Photo Set&lt;/a&gt; on Flickr to include pictures from my dad's 50th and Shalese's 4th birthday party.&lt;/p&gt;

&lt;div class="align-center"&gt;
  &lt;a href="http://flickr.com/photos/sepcot/2497420238/in/set-72157594550779490/"&gt;&lt;img src="http://farm3.static.flickr.com/2405/2497420238_08791c55a4_m.jpg" height="240" weight="160" alt="Wayne's Birthday Cake" /&gt;&lt;/a&gt;
  &lt;a href="http://flickr.com/photos/sepcot/2497417582/in/set-72157594550779490/"&gt;&lt;img src="http://farm3.static.flickr.com/2047/2497417582_5b644ac892_m.jpg" height="240" weight="160" alt="Shalese's Birthday Cake" /&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 16 May 2008 16:21:20 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/Wayne-Shalese-Birthday-Party</guid>
    </item>
    <item>
      <title>Agnes's Skydive Video</title>
      <link>http://www.sepcot.com/blog/2008/05/Agnes-Skydive-Video</link>
      <description>&lt;p&gt;We had a blast at &lt;a href="http://www.skydivechicago.com"&gt;Skydive Chicago&lt;/a&gt; this weekend! Of the seven of us in our group, Agnes was the only one who had her skydive recorded. Rob transcoded the DVD and put the video up on YouTube: &lt;a href="http://www.youtube.com/watch?v=MoiV_oDN3Vw#GU5U2spHI_4"&gt;First Tandem Skydive&lt;/a&gt;. I jumped right before Agnes, so I'm actually on the video! My jump starts around 3:30 in... If you haven't jumped, I highly recommend it; it's a great experience!&lt;/p&gt;</description>
      <pubDate>Tue, 13 May 2008 15:31:46 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/Agnes-Skydive-Video</guid>
    </item>
    <item>
      <title>Charles Stross on Spam</title>
      <link>http://www.sepcot.com/blog/2008/05/Charles-Stross-Spam</link>
      <description>&lt;p&gt;A great quotation from &lt;a href="http://www.antipope.org/charlie/"&gt;Charles Stross&lt;/a&gt;'s book &lt;em&gt;Toast&lt;/em&gt; about spam and spammers:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Something the junk advertisers don't seem to understand: we live in an information-supersaturated world. If I don't want to buy something, no amount of shouting or propagandizing will budge me; all it will do is get me annoyed. On the other hand, if I have a need for your product, I can seek it out in an eyeblink.&lt;/p&gt;
  &lt;p class="end_quote"&gt;&lt;cite&gt;-- from the short story, &lt;em&gt;TOAST: A Con Report&lt;/em&gt;, by Charles Stross&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <pubDate>Sun, 11 May 2008 17:49:09 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/Charles-Stross-Spam</guid>
    </item>
    <item>
      <title>Rails Tip: Accessible Field Errors in Tight Spaces</title>
      <link>http://www.sepcot.com/blog/2008/05/Accessible-Field-Errors</link>
      <description>&lt;h3&gt;Problem&lt;/h3&gt;

&lt;p&gt;I am currently working on a project to migrate a bunch of one-off promotional sites onto a single platform that can serve them all. Pretty basic user experience: a consumer performs a search for a product, clicks on an advertisement, is brought to one of these promotional sites, and, if interested, the consumer fills out a form and is taken off-site to perform the necessary action to complete the promotion. One problem I inherited is an image heavy layout, completed by a third-party agency, which allows no room for form field error messages. Current site behavior is to report errors by highlighting the invalid fields with a red border:&lt;/p&gt;

&lt;div class="align-center"&gt;
  &lt;img src="/images/blog/error-highlighting-old.png" width="245" height="60" alt="Old style error highlighting with form fields highlighted with a red border" /&gt;
&lt;/div&gt;

&lt;p&gt;This can be pretty uninformative if the consumer enters data, but the data fails validation. What I want is to be able to give consumers a way to find out &lt;em&gt;why&lt;/em&gt; the field is invalid, while not breaking the third-party developed layout that doesn't supply room for error messages.&lt;/p&gt;

&lt;h3&gt;Solution&lt;/h3&gt;

&lt;p&gt;Instead of highlighting the field that is invalid, I want to highlight the field's label; and within that label, I want to apply a title tag, that if the consumer hovers over, will give them a description of why the field is invalid.&lt;/p&gt;

&lt;h3&gt;Implementation&lt;/h3&gt;

&lt;p&gt;In order to implement the solution, we need to build a custom &lt;code&gt;FormBuilder&lt;/code&gt; that will auto-generate our label and form field for us, applying a title tag with error messages when applicable.&lt;/p&gt;

&lt;p&gt;Filename: &lt;code&gt;app/helpers/tagged_builder.rb&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;code class="block"&gt;
class TaggedBuilder &amp;lt; ActionView::Helpers::FormBuilder&lt;br /&gt;
&amp;nbsp;&amp;nbsp;def self.create_tagged_field(method_name)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;define_method(method_name) do |label, *args|&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;errors = object.errors.on(label.to_sym)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;klass = errors.blank? ? nil : 'errorLabel'&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;msg = label.to_s.humanize&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;unless errors.blank?&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;msg += ' ' + ((errors.class == Array) ? errors.join(' and ') : errors)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;@template.content_tag("div", @template.content_tag("label", "#{label.to_s.humanize}:", :for =&gt; "#{@object_name}_#{label}", :class =&amp;gt; klass, :title =&amp;gt; msg) + super)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;field_helpers.each do |name|&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;create_tagged_field(name) unless ('hidden_field' == name)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;end&lt;br /&gt;&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;For each of the predefined &lt;code&gt;field_helpers&lt;/code&gt; (except hidden fields) we want to process our custom &lt;code&gt;create_tagged_field&lt;/code&gt; method to build a containing &lt;code&gt;div&lt;/code&gt; and our &lt;code&gt;label&lt;/code&gt; with optional error messages, before we call &lt;code&gt;super&lt;/code&gt; to build the form field.&lt;/p&gt;

&lt;p&gt;In generating the error message string, we check to see if there are any error messages recorded on the field we are building: &lt;code&gt;object.errors.on(label.to_sym)&lt;/code&gt;. If we find errors, (&lt;code&gt;errors.blank?&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;), we assign an &lt;code&gt;errorLabel&lt;/code&gt; class to the label we are creating. &lt;code&gt;errors.on&lt;/code&gt; will return a string if one error was found, or an array of error messages if more than one were found. To format our error messages appropriately for a title attribute, we need to perform a join if we have an array of errors (&lt;code&gt;errors.join(' and ')&lt;/code&gt;), otherwise we can just use the error message string.&lt;/p&gt;

&lt;p&gt;When creating a form in our view, we need to tell &lt;code&gt;form_for&lt;/code&gt; to use the custom builder we just wrote:&lt;/p&gt;

&lt;p&gt;Filename: &lt;code&gt;app/views/your_class/_form.html.erb&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;code class="block"&gt;
&amp;lt;% form_for(@model, :builder =&amp;gt; TaggedBuilder) do |f| %&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;%= f.text_field :my_field %&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;...&lt;br /&gt;
&amp;lt;%- end -%&amp;gt;
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;This will now generate our labels and form fields appropriately, but another thing we should consider doing is overwriting the default error handling behavior of Rails. By default, when a field has an error, Rails will surround the form field in a &lt;code&gt;div&lt;/code&gt; with a class of &lt;code&gt;fieldWithErrors&lt;/code&gt; -- even with our custom form builder. What we are going to do is keep the &lt;code&gt;fieldWithErrors&lt;/code&gt; class, but move it into the field directly by overwriting &lt;code&gt;ActionView::Base.field_error_proc&lt;/code&gt;:&lt;/p&gt;


&lt;p&gt;Filename: &lt;code&gt;config/environment.rb&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;code class="block"&gt;
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|&lt;br /&gt;
&amp;nbsp;&amp;nbsp;error_class = "fieldWithErrors"&lt;br /&gt;
&amp;nbsp;&amp;nbsp;if html_tag =~ /&amp;lt;(input|textarea|select)[^&amp;gt;]+class=/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;class_attribute = html_tag =~ /class=['"]/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;html_tag.insert(class_attribute + 7, "#{error_class} ")&lt;br /&gt;
&amp;nbsp;&amp;nbsp;elsif html_tag =~ /&amp;lt;(input|textarea|select)/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;first_whitespace = html_tag =~ /\s/&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;html_tag[first_whitespace] = " class='#{error_class}' "&lt;br /&gt;
&amp;nbsp;&amp;nbsp;end&lt;br /&gt;
&amp;nbsp;&amp;nbsp;html_tag&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;This procedure keeps any user defined classes and appends the &lt;code&gt;fieldWithErrors&lt;/code&gt; class when necessary, without wrapping the form field in a &lt;code&gt;div&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we add a little style to make the errors stand out more:&lt;/p&gt;
&lt;div&gt;&lt;code class="block"&gt;label.errorLabel { color: #F00; cursor: help; }&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;What we end up with is a nice compact form that still informs consumers of validation errors:&lt;/p&gt;

&lt;div class="align-center"&gt;
  &lt;img src="/images/blog/error-highlighting-new.png" width="250" height="60" alt="New style error highlighting with error messages as title tags to a form field's label" /&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 09 May 2008 16:40:21 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/Accessible-Field-Errors</guid>
    </item>
    <item>
      <title>Skydiving This Saturday</title>
      <link>http://www.sepcot.com/blog/2008/05/Skydiving-This-Saturday</link>
      <description>&lt;p&gt;Woo! I've thought about skydiving for quite some time now and I finally have the option. My friend Rob wanted to surprise his girlfriend Agnes for her 25th birthday by taking her skydiving a couple of weeks ago, but with crappy weather and Agnes being sick, plans were delayed. The skydiving trip has been rescheduled, to this weekend!&lt;/p&gt;

&lt;p&gt;On Saturday, May 10th, 2008 at 10:30 a.m., Stephanie and I will be joining Rob, Agnes, and a few other friends at &lt;a href="http://www.skydivechicago.com/"&gt;Skydive Chicago&lt;/a&gt; for our first tandem dive!&lt;/p&gt; </description>
      <pubDate>Tue, 06 May 2008 19:15:41 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/05/Skydiving-This-Saturday</guid>
    </item>
    <item>
      <title>Setting Up Ruby on Rails in a Windows Environment</title>
      <link>http://www.sepcot.com/blog/2008/04/RoR-Windows</link>
      <description>&lt;p&gt;At work, we have been running new &lt;a href="http://www.rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; 2.0.x projects on top of &lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt; and &lt;a href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt;. Being the only developer at my company who had his start on a Windows box, I was tasked with getting a new Web Producer up and running on Rails. From a clean Windows install, setting up the machine took a matter of minutes. And, for documentation purposes, I'll write the steps out here:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Download and Run the &lt;a href="http://rubyforge.org/projects/rubyinstaller/"&gt;Ruby One-Click Installer&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Grab the SQLite3 command line program and DLL from the &lt;a href="http://www.sqlite.org/download.html"&gt;SQLite Download&lt;/a&gt; page. Unzip into &lt;code&gt;C:\WINDOWS\system32\&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;From the command line run:
    &lt;ol&gt;
      &lt;li&gt;&lt;code&gt;gem install mongrel --include-dependencies&lt;/code&gt; (choose the &lt;code&gt;mswin32&lt;/code&gt; option)&lt;/li&gt;
      &lt;li&gt;&lt;code&gt;gem install rails --include-dependencies&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;&lt;code&gt;gem install sqlite3-ruby&lt;/code&gt; (choose the &lt;code&gt;mswin32&lt;/code&gt; option)&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. You can now run &lt;code&gt;rails test&lt;/code&gt; to create a test project using SQLite running on top of Mongrel.&lt;/p&gt;

&lt;p&gt;As a bonus, these are also helpful to install for Rails development on Windows:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://tortoisesvn.tigris.org/"&gt;Tortoise SVN&lt;/a&gt; - a subversion client, implemented as a windows shell extension.&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://rubyweaver.gilluminate.com/"&gt;RubyWeaver&lt;/a&gt; - a Dreamweaver extension that makes Ruby on Rails development easier on Windows. NOTE: Adobe really needs to integrate better with Rails, support right now is nil.&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Thu, 17 Apr 2008 16:29:46 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/04/RoR-Windows</guid>
    </item>
    <item>
      <title>Wedding Photos</title>
      <link>http://www.sepcot.com/blog/2008/04/Wedding-Photos</link>
      <description>&lt;p&gt;All of our wedding tasks are officially over! Last night we drove out to Lisle, IL and picked up our Wedding Album from Timothy Whaley &amp;amp; Associates, thus closing the book on our wedding. No more appointments to worry about, no more payments to make, nothing!&lt;/p&gt;

&lt;p&gt;As part of picking up our album, we also got possession of our proofs, which I have promptly placed in my &lt;a href="http://www.flickr.com/photos/sepcot/sets/72157603792402508/"&gt;Flickr Wedding Set&lt;/a&gt; for all to see. Anyone who missed the ordering deadline from Timothy Whaley (or anyone who wants more pictures) can now grab the photos straight from Flickr and have them printed anywhere.&lt;/p&gt;</description>
      <pubDate>Tue, 15 Apr 2008 21:31:55 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/04/Wedding-Photos</guid>
    </item>
    <item>
      <title>Custom Subversion Rake Tasks, Part I</title>
      <link>http://www.sepcot.com/blog/2008/04/svn-rake-tasks-1</link>
      <description>&lt;p&gt;One of the most tedious aspects of working with Ruby on Rails with Subversion is setting up the initial project to exclude the right files and set up all of the directory &lt;code&gt;propset&lt;/code&gt;s. Having fallen into the role of checking in the initial Rails project for a new platform I have been asked to help build at work, I thought it was about time to get the Rails Subversion Setup down to 3 steps. This post is not going to talk about how to setup and run Subversion, there are plenty of articles out there on that. So, once your project is setup in &lt;code&gt;svnadmin&lt;/code&gt;, check out the empty &lt;code&gt;trunk&lt;/code&gt; directory, and from there:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Run &lt;code&gt;rails .&lt;/code&gt; from inside &lt;code&gt;trunk&lt;/code&gt; to have Ruby on Rails build a blank project&lt;/li&gt;
  &lt;li&gt;Copy &lt;a href="http://www.sepcot.com/files/coding/Miscellaneous/svn.rake"&gt;svn.rake&lt;/a&gt; into the &lt;code&gt;lib/tasks&lt;/code&gt; directory and run &lt;code&gt;rake svn:setup&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;There is no step 3&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! You are now be all set to begin development on your &amp;lt;NEW BUZZWORD&amp;gt; application and are one step closer to being bought out by &amp;lt;CORPORATE CONGLOMERATE&amp;gt;!&lt;/p&gt;

&lt;h3&gt;rake svn:setup&lt;/h3&gt;

&lt;p&gt;You could just believe that the above process works by magic, but let's take a step-by-step look at what the &lt;code&gt;svn:setup&lt;/code&gt; rake task actually does.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
if File.exists? 'config/database.yml'&lt;br /&gt;
&amp;nbsp;&amp;nbsp;move 'config/database.yml', 'config/database.example.yml'&lt;br /&gt;
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Pretty straight forward, we don't want to store our &lt;code&gt;database.yml&lt;/code&gt; file in subversion because, let's face it, access to your production database should probably be safe-guarded just a little bit. We first make sure the default &lt;code&gt;config/database.yml&lt;/code&gt; exists, then rename it to what it is, an example file: &lt;code&gt;config/database.example.yml&lt;/code&gt;.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
files = Dir.glob('log/*') + Dir.glob('tmp/*') + Dir.glob('db/*.sqlite3')&lt;br /&gt;
files.each { |file| remove_entry file }
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;We don't want to store log files, temporary files, or development databases in subversion. &lt;code&gt;Dir.glob&lt;/code&gt; returns a list of filenames (paths) that match a given pattern. Combine all the paths found into one list and use &lt;code&gt;remove_entry&lt;/code&gt; to delete each file or directory.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
mkdir_p ['doc/api', 'doc/app']
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;If you want to have Ruby on Rails documentation (&lt;code&gt;rake doc:rails&lt;/code&gt;) or your application's documentation (&lt;code&gt;rake doc:app&lt;/code&gt;) on your local machine, you shouldn't pollute subversion with it. Let's make the &lt;code&gt;doc/api&lt;/code&gt; and &lt;code&gt;doc/app&lt;/code&gt; directories now, so we can setup subversion rules later to prevent the documentation from being added to the repository.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
Rake::Task["rails:freeze:gems"].invoke
Rake::Task["rails:update"].invoke
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;You should freeze rails in your application to ensure you are developing against the same version of Rails no matter where the code is checked out or deployed. See &lt;a href="http://www.softiesonrails.com/2008/1/3/freezing-your-rails-application"&gt;Freezing Your Rails Application&lt;/a&gt; for more information.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
Rake::Task["svn:add"].invoke&lt;br /&gt;
`svn commit -m "Initial checkin with frozen rails"`
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;We then invoke another helpful Subversion Rake task I wrote (to be explained in Part II) to mark all of the files we have in &lt;code&gt;trunk&lt;/code&gt; to be added to the subversion repository and make a system call to actually make the &lt;code&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;div&gt;&lt;code class="block"&gt;
`svn propset svn:ignore "database.yml" config/`&lt;br /&gt;
`svn propset svn:ignore "*" log/`&lt;br /&gt;
`svn propset svn:ignore "*" tmp/`&lt;br /&gt;
`svn propset svn:ignore "*" doc/app/`&lt;br /&gt;
`svn propset svn:ignore "*" doc/api/`&lt;br /&gt;
`svn propset svn:ignore "*.sqlite3" db/`
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Finally, we set up our &lt;code&gt;svn propset&lt;/code&gt;s so subversion will ignore (&lt;code&gt;svn:ignore&lt;/code&gt;) all unnecessary files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;config/database.yml&lt;/code&gt; - ignore local database settings&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;log/*&lt;/code&gt; - ignore all log files&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;tmp/*&lt;/code&gt; - ignore all temporary files&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;doc/app/*&lt;/code&gt; - ignore all application documentation&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;doc/api/*&lt;/code&gt; - ignore all Rails documentation&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;db/*.sqlite3&lt;/code&gt; - ignore all local SQLite database files (development, test, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;div&gt;&lt;code class="block"&gt;
`svn commit -m "Initial svn:ignore list - config/database.yml log/* tmp/* doc/app/* doc/api/* db/*.sqlite3"`
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;And commit the settings to our subversion repository.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="http://www.sepcot.com/blog/2008/05/svn-rake-tasks-2"&gt;Custom Subversion Rake Tasks, Part II&lt;/a&gt; for an explanation of the rest of the custom Subversion Rake Tasks (&lt;code&gt;svn:add&lt;/code&gt;, &lt;code&gt;svn:delete&lt;/code&gt;, &lt;code&gt;svn:update&lt;/code&gt;, &lt;code&gt;svn:commit&lt;/code&gt;, and &lt;code&gt;svn:status&lt;/code&gt;).&lt;/p&gt;

&lt;h4&gt;Files&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;Github Repository: &lt;a href="http://github.com/msepcot/svn_task/tree/master"&gt;http://github.com/msepcot/svn_task/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Thu, 10 Apr 2008 14:42:38 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/04/svn-rake-tasks-1</guid>
    </item>
    <item>
      <title>Jigsaw Puzzle Map</title>
      <link>http://www.sepcot.com/blog/2008/04/jigsaw-puzzle-map</link>
      <description>&lt;div class="product"&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/sepcot/2386572162/"&gt;&lt;img src="http://farm3.static.flickr.com/2277/2386572162_ab58cb5a80_m.jpg" width="240" height="160" alt="Jigsaw Puzzle Map" /&gt;&lt;br /&gt;Jigsaw Puzzle Map&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;Stephanie and I like all kinds of puzzle. We play puzzle video games (she became addicted to Picross DS), watch puzzle game shows (we went to the &lt;a href="http://www.sepcot.com/blog/2007/10/Wheelmobile-2"&gt;Wheel of Fortune auditions in Rosemont&lt;/a&gt;), have puzzle books (Crossword, Sudoku, Kakuro, etc.), and have put together a good deal of jigsaw puzzles together. So, receiving a puzzle as a gift at Christmas came as no big surprise.&lt;/p&gt;

&lt;p&gt;What was surprising was the type of puzzle. Steph's grandma (Grandma B) found a site online that custom prints a 400-piece jigsaw puzzle from US Geological Survey data. Through &lt;a href="http://www.my-jigsaw.info"&gt;http://www.my-jigsaw.info&lt;/a&gt;, you can enter a US address that serves as the center of a 4 mile (north-to-south) by 6 mile (east-to-west) map. The centerpiece of the resulting puzzle is shaped like house. Now, even though we live in Chicago, we don't actually own a house yet (we're still in an apartment), so Grandma B gave Stephanie a puzzle to remind her of roots: Saint Paul, Minnesota. And after three months, we finally put the puzzle together :-)&lt;/p&gt;

&lt;p&gt;As an interesting side note: having grown up in the area, Stephanie's approach to piecing together the puzzle was to identify the streets in each of the puzzle pieces to figure out the general location of where they go; while I relied solely on color and line keys to fit pieces together.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Apr 2008 01:53:18 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/04/jigsaw-puzzle-map</guid>
    </item>
    <item>
      <title>Watching Baseball at Work</title>
      <link>http://www.sepcot.com/blog/2008/03/Watching-Baseball-Work</link>
      <description>&lt;p&gt;It's baseball season again (hockey season is pretty much over as the Chicago Blackhawks have a very slim chance of making the NHL post-season). The Chicago Cubs started the 2008 Season today and thanks to my &lt;a href="http://www.elgato.com/"&gt;Elgato&lt;/a&gt; TV Tuner and eyeTV software, I can enjoy the network broadcast (WGN) games in High Definition on my MacBook :-)&lt;/p&gt;
&lt;p&gt;I picked up the TV tuner a few months ago (before the writer's strike began) to record TV shows that Steph and I watch on my MacBook and have been pleased with the quality of video since.&lt;/p&gt;</description>
      <pubDate>Mon, 31 Mar 2008 22:04:37 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/03/Watching-Baseball-Work</guid>
    </item>
    <item>
      <title>Gibson Melody Maker</title>
      <link>http://www.sepcot.com/blog/2008/03/Gibson-Meldoy-Maker</link>
      <description>&lt;div class="product"&gt;
  &lt;p&gt;&lt;a href="http://www.flickr.com/photos/sepcot/2281623133/"&gt;
    &lt;img src="http://farm4.static.flickr.com/3185/2281623133_396821e750_m.jpg" width="160" height="240" alt="Gibson Melody Maker" /&gt;&lt;br /&gt;Gibson Melody Maker
  &lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;The &lt;a href="http://www.guitarhero.com/"&gt;Guitar Hero&lt;/a&gt; franchise finally peaked my interest in music. So, for Christmas last year, I asked my parents for a &lt;em&gt;Gibson Melody Maker&lt;/em&gt;. Unfortunately, I sent my dad a link to &lt;a href="http://www.guitarcenter.com/"&gt;Guitar Center&lt;/a&gt; and a simple online purchase became a two-month in-store ordeal in which their order (for a Sunburst colored, Gibson Melody Maker) was delayed, deleted, re-entered with errors, corrected, and finally delivered (in Black). But, I now have my guitar and Guitar Center offered up a free &lt;a href="http://www.peavey.com/"&gt;Peavey&lt;/a&gt; amp, a guitar strap, a stand, and a box of &lt;a href="http://www.ernieball.com/"&gt;Ernie Ball&lt;/a&gt; strings, so all is forgiven. :-)&lt;/p&gt;

&lt;p&gt;My original plan was to teach myself guitar from books and miscellaneous sources online. After going solo for about a month now, I realize that when I get home from work, I'm not always that motivated to try and learn on my own. When spring finally gets here, I think I'm going to start looking for guitar lessons to help kick me into gear.&lt;/p&gt;

&lt;p&gt;Until then, I'm going to keep at it on my own, slowly progressing through the books I have:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The "First Stage" Guitar Book - Learn How To Play Guitar Easily &amp;amp; Quickly!&lt;/li&gt;
  &lt;li&gt;Hal Leonard Guitar Method: Rock Guitar&lt;/li&gt;
  &lt;li&gt;Learn to Play Guitar with Metallica&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm also looking forward to the release of &lt;a href="http://www.guitarrising.com/index.html"&gt;Guitar Rising&lt;/a&gt; sometime this year...&lt;/p&gt;
&lt;p&gt;\m/&lt;/p&gt;</description>
      <pubDate>Wed, 12 Mar 2008 20:01:54 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/03/Gibson-Meldoy-Maker</guid>
    </item>
    <item>
      <title>Spicy Baked Fish</title>
      <link>http://www.sepcot.com/blog/2008/02/Spicy-Baked-Fish</link>
      <description>&lt;div class="product"&gt;&lt;p&gt;&lt;a href="http://flickr.com/photos/sepcot/2282403236/"&gt;&lt;img src="http://farm4.static.flickr.com/3034/2282403236_c25c1360f8_m.jpg" width="240" height="160" alt="Spicy Baked Fish" /&gt;&lt;br /&gt;Spicy Baked Fish&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;
&lt;p class="info"&gt;Serves: 4 - Serving Size: 3 oz&lt;/p&gt;
&lt;p&gt;&lt;q&gt;This spicy seafood dish will delight everyone.&lt;/q&gt;&lt;/p&gt;
&lt;h4&gt;Ingredients&lt;/h4&gt;
&lt;ul&gt;
	&lt;li&gt;1 lb Cod (or other fish) Fillet&lt;/li&gt;
	&lt;li&gt;1 Tbsp Olive Oil&lt;/li&gt;
	&lt;li&gt;1 tsp Hot and Spicy Seasoning Mix&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Directions&lt;/h4&gt;
&lt;ol&gt;
	&lt;li&gt;Preheat oven to 350 degrees F. Spray casserole dish with nonstick cooking oil spray.&lt;/li&gt;
	&lt;li&gt;Wash and dry fish. Place in dish. Drizzle with oil and seasoning mixture.&lt;/li&gt;
	&lt;li&gt;Bake uncovered for 15 minutes or until fish flakes with fork. Cut into 4 pieces. Serve with rice.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Hot and Spicy Seasoning&lt;/h3&gt;
&lt;p class="info"&gt;Makes: 1/3 cup - Serving Size: 1/2 tsp&lt;/p&gt;
&lt;p&gt;&lt;q&gt;Spices can make the ordinary extraordinary. Here's a great all purpose spice mix.&lt;/q&gt;&lt;/p&gt;
&lt;h4&gt;Ingredients&lt;/h4&gt;
&lt;ul&gt;&lt;li&gt;1 1/2 tsp White Pepper&lt;/li&gt;
	&lt;li&gt;1/2 tsp Cayenne Pepper&lt;/li&gt;
	&lt;li&gt;1/2 tsp Black Pepper&lt;/li&gt;
	&lt;li&gt;1 tsp Onion Powder&lt;/li&gt;
	&lt;li&gt;1 1/4 tsp Garlic Powder&lt;/li&gt;
	&lt;li&gt;1 Tbsp Basil&lt;/li&gt;
	&lt;li&gt;1 1/2 tsp Thyme&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Directions&lt;/h4&gt;
&lt;ol&gt;&lt;li&gt;Mix all ingredients together. Store in an airtight container.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;&lt;cite&gt;Recipe from the National Heart, Lung, and Blood Institute's Keep the Beat - Heart Healthy Recipes.&lt;/cite&gt;&lt;/p&gt;</description>
      <pubDate>Thu, 21 Feb 2008 13:46:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/02/Spicy-Baked-Fish</guid>
    </item>
    <item>
      <title>Registered for RailsConf 2008</title>
      <link>http://www.sepcot.com/blog/2008/02/Registered-RailsConf-2008</link>
      <description>&lt;p&gt;My co-worker, &lt;a href="http://somethingunimportant.com/"&gt;Andrew Bloom&lt;/a&gt;, and I will be in Portland, Oregon from May 28th through June 2nd for &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; (arriving the day before, leaving the day after). We will be there for the Tutorials Day taking part in Meta-programming Ruby for Fun &amp;amp; Profit and Developer Testing Tricks sessions. This will be my first time up to Portland, so it should be fun!&lt;/p&gt;</description>
      <pubDate>Wed, 20 Feb 2008 15:01:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/02/Registered-RailsConf-2008</guid>
    </item>
    <item>
      <title>Costa Rica (22-26 March 2006)</title>
      <link>http://www.sepcot.com/blog/2008/02/Costa-Rica-2006</link>
      <description>&lt;p&gt;&lt;em&gt;Originally posted in the former 'Travel' section back in March/April 2006.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We had a wonderful time in Costa Rica. The Tortuga Island cruise was great! We got to go snorkeling and see sea snakes, sea stars, and all sorts of colorful fish. The island was lined with palm trees up and down the coast and we got to enjoy lunch with a live band. Hotel Villa Calatas was unbelievable! The food was great, their private rocky beach was full of life (hundreds of crabs, snails, and little fish), and the amphitheater had the most amazing view of the country. Although we didn't get to go up to Arenal Volcano, we did get to walk over the remains of the 1992 eruption and see lava rocks skidding down the side of the volcano glowing red and throwing up debris. We did not get to spend that much time at the Tabacon Hot Springs Resort and Spa, but sharing the hot springs with iguanas and other little lizards on the morning of our departure was a thrilling experience. I can't wait to go back!&lt;/p&gt;
&lt;p&gt;I've been playing around with Microsoft's &lt;a href="http://www.microsoft.com/windowsxp/using/digitalphotography/photostory/default.mspx"&gt;Photo Story 3&lt;/a&gt; for Windows (which is a tool to bring digital photos to life) and imported a lot of my Costa Rican photos. Download the Photo Story I created: &lt;a href="http://www.sepcot.com/videos/CostaRicaPhotoStory.wmv"&gt;Costa Rica Photo Story&lt;/a&gt; (14.5 MB - 11 minutes).&lt;/p&gt;
&lt;p&gt;If you want to look through all of the photos we took in Costa Rica at your own pace, take a look at my &lt;a href="http://www.flickr.com/photos/sepcot/sets/72157594564140349/"&gt;Costa Rica Photo Album&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 20 Feb 2008 10:40:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/02/Costa-Rica-2006</guid>
    </item>
    <item>
      <title>Web Site Update</title>
      <link>http://www.sepcot.com/blog/2008/02/Web-Site-Update</link>
      <description>&lt;p&gt;So, it's been a while since my last post. Quite a bit has happened in that time, most of which I will cover in later posts. The main reason for the lack of posting in the past month has to do with my hosting account at Godaddy.com expiring. Instead of renewing my basic Windows account, I opted to move to a &lt;abbr title="Virtual Private Server"&gt;VPS&lt;/abbr&gt; with Slicehost. Timing was a big problem, I had a few weeks to move my entire site to a new provider. This, in itself, is no big deal; copy... paste... done. Well, I also wanted to move away from having just a flat static site. With each thought, I had to create a new post, update the home page, add the post to the archive listing, and update the &lt;abbr title="Really Simple Syndication"&gt;RSS&lt;/abbr&gt; feed. With a dynamic site, all of this can be done in one step: add the post to the database. The home page, archive list, and &lt;abbr title="Really Simple Syndication"&gt;RSS&lt;/abbr&gt; feed should all be able to update themselves.&lt;/p&gt;
&lt;p&gt;The move away from Godaddy also allowed me to do some site cleaning. If you frequented the site in the past, you will have noticed a few navigation items missing: Code Monkey, Customization, Healthy Food, Travel, and Wedding are all gone! This is not to say that none of that information will make it back to my site, it will just appear through the blog posts I make. Cleaning the site helps me focus, remove the clutter and concentrate on only a few tasks. One goal I have been wanting to accomplish with this site is to add tag support to my posts to make them easier to find and group together, thus allowing me to eliminate some of those navigational items. And in the week since I migrated my site, I have added tag support! Code Monkey topics should now appear grouped together with the tag &lt;a href="http://www.sepcot.com/blog/tag/coding"&gt;coding&lt;/a&gt;, Healthy Food with the tag &lt;a href="http://www.sepcot.com/blog/tag/food"&gt;food&lt;/a&gt;, with &lt;a href="http://www.sepcot.com/blog/tag/travel"&gt;Travel&lt;/a&gt; and &lt;a href="http://www.sepcot.com/blog/tag/wedding"&gt;Wedding&lt;/a&gt; following similar patterns.&lt;/p&gt;
&lt;p&gt;That's all I got for now. Topics for upcoming posts include: my new Guitar, books I've been reading, and more on Ruby and Rails programming.&lt;/p&gt;</description>
      <pubDate>Tue, 19 Feb 2008 14:05:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/02/Web-Site-Update</guid>
    </item>
    <item>
      <title>Meg and Matt's Wedding Date is Set!</title>
      <link>http://www.sepcot.com/blog/2008/01/Meg-Matt-Wedding</link>
      <description>&lt;p&gt;Congratulations to Meg and Matt (and Jack)! They have been engaged for a little while now, but they just set their wedding date: August 9th, 2008.&lt;/p&gt;</description>
      <pubDate>Fri, 11 Jan 2008 14:21:00 +0000</pubDate>
      <guid isPermaLink="true">http://www.sepcot.com/blog/2008/01/Meg-Matt-Wedding</guid>
    </item>
  </channel>
</rss>
