<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>I am awesome.</description><title>Shpigford</title><generator>Tumblr (3.0; @shpigford)</generator><link>http://jo.shpigford.com/</link><item><title>ZuZu during her first bath….could a puppy face look any...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_ku9n5rj2y61qz4kkpo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://pugspot.com/photos/zuzu0609/2e85aaa796a4061a"&gt;ZuZu during her first bath….could a puppy face look any more sad??&lt;/a&gt;&lt;/p&gt;</description><link>http://jo.shpigford.com/post/272753910</link><guid>http://jo.shpigford.com/post/272753910</guid><pubDate>Sun, 06 Dec 2009 21:58:38 -0700</pubDate></item><item><title>The myth of the page fold: evidence from user testing</title><description>&lt;a href="http://www.cxpartners.co.uk/thoughts/the_myth_of_the_page_fold_evidence_from_user_testing.htm"&gt;The myth of the page fold: evidence from user testing&lt;/a&gt;: &lt;p&gt;Great bit on why having content below the fold is NOT the worst thing on earth. Country music is.&lt;/p&gt;</description><link>http://jo.shpigford.com/post/248021067</link><guid>http://jo.shpigford.com/post/248021067</guid><pubDate>Tue, 17 Nov 2009 20:58:49 -0700</pubDate></item><item><title>Eat Me: The Food and Philosophy of Kenny Shopsin</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_kt0no0nbLD1qz4kkpo1_400.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://jasonfulford.com/eat_3a.html"&gt;Eat Me: The Food and Philosophy of Kenny Shopsin&lt;/a&gt;&lt;/p&gt;</description><link>http://jo.shpigford.com/post/241840197</link><guid>http://jo.shpigford.com/post/241840197</guid><pubDate>Thu, 12 Nov 2009 14:57:36 -0700</pubDate></item><item><title>Ummmm WHATTT?!?!?!
Digital Tattoo Interface</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_kt0a4uggPR1qz4kkpo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Ummmm WHATTT?!?!?!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.core77.com/competitions/GreenerGadgets/projects/4673/"&gt;Digital Tattoo Interface&lt;/a&gt;&lt;/p&gt;</description><link>http://jo.shpigford.com/post/241617919</link><guid>http://jo.shpigford.com/post/241617919</guid><pubDate>Thu, 12 Nov 2009 10:05:17 -0700</pubDate></item><item><title>My favorite is the scenery in the background :)
SNS: Balancing...</title><description>&lt;img src="http://30.media.tumblr.com/tumblr_kt09t3LGtK1qz4kkpo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;My favorite is the scenery in the background :)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://awkwardfamilyphotos.com/2009/10/24/balancing-act/"&gt;SNS: Balancing Act at AwkwardFamilyPhotos.com&lt;/a&gt;&lt;/p&gt;</description><link>http://jo.shpigford.com/post/241612753</link><guid>http://jo.shpigford.com/post/241612753</guid><pubDate>Thu, 12 Nov 2009 09:58:15 -0700</pubDate></item><item><title>pie0:

World’s Tallest Dog and World’s Smallest Dog meet.
Old...</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_ksymb9vQiO1qz4f43o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://pie0.tumblr.com/post/240559447/worlds-tallest-dog-and-worlds-smallest-dog"&gt;pie0&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://www.dailymail.co.uk/news/article-492264/Its-dogs-life-worlds-tallest-pooch-meets-smallest.html"&gt;World’s Tallest Dog and World’s Smallest Dog meet.&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;Old news, but cute news.&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://jo.shpigford.com/post/240563914</link><guid>http://jo.shpigford.com/post/240563914</guid><pubDate>Wed, 11 Nov 2009 12:38:11 -0700</pubDate></item><item><title>mrgan:

A refreshingly wholesome (and entertaining) look at...</title><description>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/fYzv-AVi78E&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/fYzv-AVi78E&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://mrgan.tumblr.com/post/240525950/a-refreshingly-wholesome-and-entertaining-look"&gt;mrgan&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A refreshingly wholesome (and entertaining) look at auto-tune.&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://jo.shpigford.com/post/240544813</link><guid>http://jo.shpigford.com/post/240544813</guid><pubDate>Wed, 11 Nov 2009 12:16:07 -0700</pubDate></item><item><title>"I like an escalator because an escalator can never break, it can only become stairs. There would..."</title><description>“I like an escalator because an escalator can never break, it can only become stairs. There would never be an escalator temporarily out of order sign, only an escalator temporarily stairs. Sorry for the convenience.&lt;br/&gt;
— Mitch Hedburg”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;(via &lt;a href="http://loganleger.com/mitch-hedburg-quote-111009"&gt;Logan Leger&lt;/a&gt;)&lt;/em&gt;</description><link>http://jo.shpigford.com/post/240467922</link><guid>http://jo.shpigford.com/post/240467922</guid><pubDate>Wed, 11 Nov 2009 10:47:16 -0700</pubDate></item><item><title>It’s a bushel ‘o pugs!</title><description>&lt;img src="http://30.media.tumblr.com/tumblr_ksyh65hkxI1qz4kkpo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;It’s a bushel ‘o pugs!&lt;/p&gt;</description><link>http://jo.shpigford.com/post/240463612</link><guid>http://jo.shpigford.com/post/240463612</guid><pubDate>Wed, 11 Nov 2009 10:42:00 -0700</pubDate><category>pugs</category></item><item><title>TrackThePack: From PHP to Rails</title><description>&lt;p&gt;Recently I pushed an update live for &lt;a href="http://trackthepack.com"&gt;TrackThePack&lt;/a&gt; that was probably a little bigger than “just” an update.&lt;/p&gt;
&lt;p&gt;The feature set for the web app didn’t change very much (though there were certainly a few much needed things that were added). But the biggest change was that I scrapped every bit of the PHP code and rewrote the entire thing in Ruby/Rails.&lt;/p&gt;
&lt;h3&gt;El History&lt;/h3&gt;
&lt;p&gt;I built TrackThePack as an “internal” tool back in 2006 when my wife and I ran a little &lt;a href="http://fugitivetoys.com"&gt;toy store&lt;/a&gt;. We were constantly ordering new toys from suppliers and my OCD self wanted to know where they are. Plus, who doesn’t love tracking packages? The problem was that I was getting really annoyed with trying to juggle half a dozen tracking numbers and going to four different carrier sites to track them.&lt;/p&gt;
&lt;p&gt;So, to solve my little problem, I decided to build something. It was running strictly on my dev server and I had no intention of it seeing the light of day. But a few months after I built it, I had mentioned it to a few friends and they prodded me to make the thing public so others could use it.&lt;/p&gt;
&lt;p&gt;So I whipped up a little user authentication class for it and pushed it live. Still not thinking anybody would use it. But sure enough, within a few weeks there were a few hundred new users (no idea how…I told maybe 3 people about the thing).&lt;/p&gt;
&lt;p&gt;I rarely made updates to the code, just fixed a few bugs here and there, but the site really started picking up steam with Lifehacker &lt;a href="http://lifehacker.com/332836/track-packages-across-delivery-companies-with-trackthepack"&gt;did a bit&lt;/a&gt; about it. At that point I didn’t have much of a choice…the site started taking on a life of its own.&lt;/p&gt;
&lt;h3&gt;Egyptian Script Kiddie&lt;/h3&gt;
&lt;p&gt;Then, in May 2007, some script kiddie in Egypt hacked in to my server and ganked everything…databases and all. Thankfully I was doing nightly backups, but unthankfully I had not encrypted any of the user passwords in the database. (DOH!!!!) Total amateur move, for sure, but it was what it was. I quickly built in some encryption and then emailed all the users telling them the bad news and that they’d need to change their passwords ASAP.&lt;/p&gt;
&lt;p&gt;Obviously stuff like that could be a major blow to a web app as you’ve broken the user’s trust, but thankfully people stuck around and helped the site continue to grow.&lt;/p&gt;
&lt;h3&gt;The Decision to Get Switchy&lt;/h3&gt;
&lt;p&gt;So, after all of that, I happened to start picking up Ruby/Rails dev and had started developing my stuff exclusively in Rails. I first ported &lt;a href="http://tutorialoutpost.com"&gt;TutorialOutpost&lt;/a&gt;, and then &lt;a href="http://pugspot.com"&gt;PugSpot&lt;/a&gt; from PHP to Rails. So TrackThePack was my last “major” app that needed porting.&lt;/p&gt;
&lt;p&gt;I say “needed”…it’s not like PHP is some awful language that isn’t capable of doing the job, it just ultimately comes down to preference. Coding in PHP is a chore for me, while Ruby is actually fun. I enjoy doing it.&lt;/p&gt;
&lt;p&gt;Anywho, I wasn’t in any big hurry to port TrackThePack. It doesn’t make any money (yet…that’s changing soon) and since we sold the toy store, I wasn’t tracking near as many packages as I was before. But around 5 months ago TrackThePack really started picking up steam again. A few major retailers started using using TrackThePack as a place to send their customers to track their orders and I figured I needed to get down to business and start looking at this thing in the long term.&lt;/p&gt;
&lt;p&gt;In the long term, as in a few years, I didn’t want to still be pushing PHP around. So now was as good a time as any to convert the thing to Rails.&lt;/p&gt;
&lt;h3&gt;Thus the Process Begins&lt;/h3&gt;
&lt;p&gt;When you’ve got an app like TrackThePack, the core functionality of the app revolves around connecting to third-party APIs. In this case: UPS, FedEx, DHL, and USPS. So the very first thing I had to do was connect to these web services.&lt;/p&gt;
&lt;p&gt;Obviously it’s slow as christmas to poll these web services every time a user loads the page, and it gets even hairier when you’ve got half a dozen tracking numbers all doing that at the same time.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Retrieving Yo Data&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;So what we do is when we retrieve the data from the web services, we parse the XML into individual “events” and store them in the database. Then, we save the last time the feed was updated and won’t refresh the data for 30-120 minutes (depends on various factors). That way we aren’t polling the APIs too much and it speeds up the loading of tracking data exponentially. Not to mention, most of the carriers don’t update their data very often…so no more than once a day. So refreshing the data a dozen times a day doesn’t do anybody any good.&lt;/p&gt;
&lt;p&gt;We’re using &lt;a href="http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/index.html"&gt;net/http&lt;/a&gt; to request the data and &lt;a href="http://github.com/whymirror/hpricot"&gt;Hpricot&lt;/a&gt; to parse the XML.&lt;/p&gt;
&lt;h3&gt;Scrapin’&lt;/h3&gt;
&lt;p&gt;Which brings me to the next thing. Smartpost, UPS Mail Innovations, and DHL Global Mail are all services that each carrier uses to partner with USPS to deliver your package. So FedEx will start the shipment, but will hand it over to USPS to do the final delivery. None of the the carriers provide tracking data in their APIs for those, so what we have to do is scrape the data from their actual websites. It’s a major pain because if they do even minor changes to the HTML on the page (specifically the HTML that lists the tracking data) it breaks junk on our end. So…that’s a constant battle but it is what it is.&lt;/p&gt;
&lt;p&gt;For the scraping we’re just using &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/open-uri/rdoc/"&gt;open-uri&lt;/a&gt; and Hpricot. Hpricot is seriously a lifesaver and makes the whole process amazingly simple.&lt;/p&gt;
&lt;h3&gt;Auto-Detection&lt;/h3&gt;
&lt;p&gt;One of the major differences between TrackThePack and some of the other tracking services is that we auto-detect the type of number you entered. The bit of code that determines the type of tracking number is all sorts of nasty (a conglomerate of regex and if/else and case statements). Unfortunately many of the carriers like to use numbers with the same format. So, in those cases what we have to do is poll all the possible services and see who responds with valid tracking data. It slows down the process, but until the carriers decide to use unique identifiers, it is what it is.&lt;/p&gt;
&lt;h3&gt;Googley Maps&lt;/h3&gt;
&lt;p&gt;With each tracking number we include a map with icons of the progress. Since many times there are 3-4 status updates for a single location (Arrival, Processing, Departure, etc), we select the unique cities/states/countries from that number’s events and then plot them on a Google Map. We use &lt;a href="http://github.com/andre/geokit-rails"&gt;Geokit Rails&lt;/a&gt; to convert city/state/country names into lat/long plots.&lt;/p&gt;
&lt;h3&gt;Mobile/Email Notification&lt;/h3&gt;
&lt;p&gt;This feature is still a little buggy, but it’s getting better. Right now, if you enter in your mobile number and an email address that you want to be notified, we’ll send you a notification when your package is both out for delivery and delivered. We just check for the the string “deliver” on status updates and if it’s new, we’ll send you a notification.&lt;/p&gt;
&lt;p&gt;The mobile stuff is a text message, but every phone has it’s own email address (5558037475@txt.att.net) so we just collect the user’s number and network if they want to be notified and send the text message as an email.&lt;/p&gt;
&lt;h3&gt;iPhone Version&lt;/h3&gt;
&lt;p&gt;I’ve had dozens of people ask for a native iPhone app, but I’m still not convinced that’s really necessary. So for now I’m focusing on really making the iPhone version of the site itself pretty solid.&lt;/p&gt;
&lt;p&gt;If you visit TrackThePack on your iPhone, the app (using request.user_agent data) forwards you to specific iPhone controller. I had initially just planned on using CSS to style the current site, but the more I worked on it, the more it made sense to use a completely stripped down version with only the absolute necessary HTML/CSS so it’d load faster.&lt;/p&gt;
&lt;h3&gt;Plugins/Gems&lt;/h3&gt;
&lt;p&gt;Overall it’s a really simple app, but here are some of the plugins/gems we’re using to make life easier.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://github.com/sbecker/asset_packager"&gt;AssetPackager&lt;/a&gt; - For compressing/minifying Javascript/CSS on deploy&lt;br/&gt;&lt;a href="http://getexceptional.com"&gt;Exceptional&lt;/a&gt; - For error monitoring.&lt;br/&gt;&lt;a href="http://github.com/andre/geokit-rails"&gt;Geokit Rails&lt;/a&gt; -  For map plotting on the Google Maps in each listing&lt;br/&gt;&lt;a href="http://github.com/railsgarden/message_block"&gt;Message Block&lt;/a&gt; -  For unifying/simplifying error messages and notices.&lt;br/&gt;&lt;a href="http://github.com/technoweenie/permalink_fu"&gt;PermalinkFu&lt;/a&gt; - For creating permalinks on the usernames. &lt;br/&gt;&lt;a href="http://github.com/technoweenie/restful-authentication"&gt;Restful Authentication&lt;/a&gt; - For managing user authentication. &lt;br/&gt;&lt;a href="http://github.com/cheald/site_config"&gt;site_config&lt;/a&gt; - We’re juggling probably a dozen different API keys and settings for all the carriers…so this makes that a lot easier. &lt;br/&gt;&lt;a href="http://github.com/mislav/will_paginate"&gt;WillPaginate&lt;/a&gt; - To a paginate the listing of numbers &lt;br/&gt;&lt;a href="http://github.com/javan/whenever"&gt;Whenever&lt;/a&gt; - For setting up cron jobs&lt;/p&gt;
&lt;h3&gt;Server Setup&lt;/h3&gt;
&lt;p&gt;When the app was built with PHP it was on a server with MediaTemple…and it was awful. I can’t count the number of times our database server was down or the server was just plain slow.&lt;/p&gt;
&lt;p&gt;Thankfully we’re now using &lt;a href="http://slicehost.com"&gt;Slicehost&lt;/a&gt; and we’re able to run the whole app on a 512MB slice there (though we’ll probably up that shortly to help things speed up even more).&lt;/p&gt;
&lt;h3&gt;Commercial: The Future&lt;/h3&gt;
&lt;p&gt;Above I mentioned that TrackThePack is currently not making a dime, but that actually is something that will be changing shortly.&lt;/p&gt;
&lt;p&gt;While I’ve been building out the “Personal” version of the site, I’ve also been building out the “Commercial” version.&lt;/p&gt;
&lt;p&gt;Right now, a the large majority of online stores (large and small) send customers a tracking number and tell them to go to the carrier site to track it. So what we’ll be doing is offering online store owners the ability to embed tracking data and maps into their own sites so they can keep their customers at their site instead of sending them elsewhere. I won’t go into to many more details, but this service will be ready in the next week or two.&lt;/p&gt;
&lt;p&gt;The Personal version will always remain free…no plans on changing that. So, please continue &lt;a href="http://trackthepack.com"&gt;enjoying that&lt;/a&gt;. :)&lt;/p&gt;</description><link>http://jo.shpigford.com/post/240458100</link><guid>http://jo.shpigford.com/post/240458100</guid><pubDate>Wed, 11 Nov 2009 10:35:48 -0700</pubDate><category>rails</category><category>php</category><category>development</category><category>trackthepack</category></item></channel></rss>
