<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>MyOwnPirateRadio</title>
	<atom:link href="http://myownpirateradio.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://myownpirateradio.com</link>
	<description>musings on makers making things</description>
	<lastBuildDate>Fri, 27 Jan 2012 20:36:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='myownpirateradio.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>MyOwnPirateRadio</title>
		<link>http://myownpirateradio.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://myownpirateradio.com/osd.xml" title="MyOwnPirateRadio" />
	<atom:link rel='hub' href='http://myownpirateradio.com/?pushpress=hub'/>
		<item>
		<title>Startup Fever</title>
		<link>http://myownpirateradio.com/2012/01/27/startup-fever/</link>
		<comments>http://myownpirateradio.com/2012/01/27/startup-fever/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 20:33:09 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[makers]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=481</guid>
		<description><![CDATA[It&#8217;s time for a new chapter. I&#8217;ve been a terribly inconsistent writer on MyOwnPirateRadio over the years. I&#8217;ve written sporadically. I&#8217;ve written snotty rants, mind-numbing trivia, and esoteric technology crib notes. I&#8217;ve written about completely random and unrelated topics. In short, I&#8217;ve written so poorly that only my most patient, masochistic, and excitement-starved readers are &#8230; <a href="http://myownpirateradio.com/2012/01/27/startup-fever/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=481&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s time for a new chapter.</p>
<p>I&#8217;ve been a terribly inconsistent writer on MyOwnPirateRadio over the years. I&#8217;ve written sporadically. I&#8217;ve written snotty rants, mind-numbing trivia, and esoteric technology crib notes. I&#8217;ve written about completely random and unrelated topics. In short, I&#8217;ve written so poorly that only my most patient, masochistic, and excitement-starved readers are still around. (Hi, mom! Oh, wait, she doesn&#8217;t have an internet connection.) So, dear reader(s), I&#8217;m sorry. I apologize. I&#8217;ve been a shit.</p>
<p>But I do want to write &#8212; it makes me happy &#8212; and so I&#8217;m going to start again.</p>
<p>I will write about one topic:</p>
<blockquote><p>Life trying to get startups off the ground.</p></blockquote>
<p>This will not be &#8220;How I succeeded at getting my startup off the ground&#8221;, or &#8220;My genius recipe for gobsmacking success in startup life&#8221;, or, &#8221;How I built and sold my company for $10M in just 3 months with only 8 toothpicks, a pair of tweezers, and a tenth of my staggeringly massive brainpower, bitch&#8221;. This is not one of those blogs. Gloating will be kept to an absolute minimum. I intend to write more in the vein of &#8220;How I&#8217;ve worked like crazy on too many projects at once for 5+ years with little to show for it except a much smaller bank account, a bunch of hard-earned lessons, and a smug sense of satisfaction. Please send help.&#8221;.</p>
<p>I will write as openly and honestly as I can.</p>
<p>I will try really hard to write regularly, at least once a week.</p>
<p>I will spend no more than 30 minutes writing a post.</p>
<p>I will avoid the temptation to portray this lifestyle as glamorous. &#8216;Cuz it ain&#8217;t. Read me?</p>
<p>And I want to feel good about doing this. I have a lot of &#8220;priority guilt&#8221;&#8230; why write blog posts when I should be writing code, helping out at home, doing some exercise, or becoming a better husband and dad? I also fear the embarassment of screwing up in public. But I&#8217;ve come to grips with a few realities: I need to write; my privacy is largely an illusion anyway; and I&#8217;m much less interesting to everyone else than I like to think.</p>
<p>I&#8217;ve put off starting this for a very long time now, so I&#8217;d better post this before I manage to stop myself again.</p>
<p>So here goes: Startup Fever. Wish me luck.</p>
<p>P.S. How Canadian of me, to start off with an apology. Represent!</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/makers/'>makers</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/481/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/481/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/481/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=481&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2012/01/27/startup-fever/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>Getting Heroku Cedar and Rails 3.1 Asset Pipeline to Play Nicely Together</title>
		<link>http://myownpirateradio.com/2012/01/01/getting-heroku-cedar-and-rails-3-1-asset-pipeline-to-play-nicely-together/</link>
		<comments>http://myownpirateradio.com/2012/01/01/getting-heroku-cedar-and-rails-3-1-asset-pipeline-to-play-nicely-together/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 03:09:47 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[asset pipeline]]></category>
		<category><![CDATA[cedar]]></category>
		<category><![CDATA[dalli]]></category>
		<category><![CDATA[heroku]]></category>
		<category><![CDATA[memcached]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=474</guid>
		<description><![CDATA[I recently migrated a Ruby on Rails 3.1 app from the Heroku Bamboo stack to Heroku Cedar. If you&#8217;re doing the same, here are a few notes to help avoid snags on getting the Rails Asset Pipeline working efficiently. Unlike Bamboo, Cedar does not offer Varnish as a reverse proxy cache, nor does it automatically &#8230; <a href="http://myownpirateradio.com/2012/01/01/getting-heroku-cedar-and-rails-3-1-asset-pipeline-to-play-nicely-together/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=474&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently migrated a Ruby on Rails 3.1 app from the <a href="http://devcenter.heroku.com/articles/bamboo">Heroku Bamboo stack</a> to <a href="http://devcenter.heroku.com/articles/cedar">Heroku Cedar</a>. If you&#8217;re doing the same, here are a few notes to help avoid snags on getting the Rails Asset Pipeline working efficiently.</p>
<p>Unlike Bamboo, Cedar does not offer Varnish as a reverse proxy cache, nor does it automatically gzip content. You need to do it yourself. Heroku recommends:</p>
<ol>
<li>Use memcached, with <a href="http://devcenter.heroku.com/articles/memcache#deploying_to_heroku">Dalli as the memcached client</a>. Make sure to follow the Rails 3 section.</li>
<li><a href="http://devcenter.heroku.com/articles/http-routing">Use Rack::Cache</a> as a substitute for Varnish. Heroku links to <a href="http://www.saturnflyer.com/blog/jim/2010/06/24/rack-cache-on-heroku-with-memcached/">this article which explains how to integrate Heroku with Rack::Cache.</a> I couldn&#8217;t get it to work, so I hunted around and pieced together the folllowing riff.</li>
</ol>
<div>In your runtime environment file (e.g. production.rb), add this:</div>
<pre>require 'rack-cache'
My::Application.configure do
...
  # Enable Rack::Cache
  config.middleware.use Rack::Cache,
   :metastore =&gt; "memcached://#{ENV['MEMCACHE_SERVERS']}/meta",
   :entitystore =&gt; "memcached://#{ENV['MEMCACHE_SERVERS']}/body"</pre>
<p>You can also set HTTP headers in production.rb as follows. (3600 is an example value, make this whatever you want.)</p>
<pre># Add HTTP headers to cache static assets for an hour
config.static_cache_control = "public, max-age=3600"</pre>
<p>And you may want to add this to your config.ru to get gzip working:</p>
<pre>use Rack::Deflater</pre>
<p>References:</p>
<div>
<ul>
<li><a href="http://devcenter.heroku.com/articles/rails3">Getting Started with Rails 3.0 on Heroku/Cedar</a></li>
<li><a href="http://blog.marc-seeger.de/2010/12/09/added-caching-to-my-blog/">Added Caching to My Blog</a></li>
<li><a href="http://jackchu.com/rails-31-asset-pipeline-content-delivery-netw">Rails 3.1 Asset Pipeline, Content Delivery Networks and Rack::Cache</a></li>
<li><a href="http://snippets.aktagon.com/snippets/302-How-to-setup-and-use-Rack-Cache-with-Rails-2-3-0-RC-1">How to Setup and Use Rack::Cache with Rails 2.3.0 RC1</a></li>
<li><a href="http://www.randomhacks.net/articles/2011/06/03/heroku-celadon-cedar-review">Heroku Celadon Cedar Review</a></li>
</ul>
</div>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a>, <a href='http://myownpirateradio.com/category/uncategorized/'>Uncategorized</a> Tagged: <a href='http://myownpirateradio.com/tag/asset-pipeline/'>asset pipeline</a>, <a href='http://myownpirateradio.com/tag/cedar/'>cedar</a>, <a href='http://myownpirateradio.com/tag/dalli/'>dalli</a>, <a href='http://myownpirateradio.com/tag/heroku/'>heroku</a>, <a href='http://myownpirateradio.com/tag/memcached/'>memcached</a>, <a href='http://myownpirateradio.com/tag/rails/'>rails</a>, <a href='http://myownpirateradio.com/tag/ruby-on-rails/'>ruby on rails</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/474/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/474/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/474/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=474&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2012/01/01/getting-heroku-cedar-and-rails-3-1-asset-pipeline-to-play-nicely-together/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>Pressly Makes Sense</title>
		<link>http://myownpirateradio.com/2011/09/13/pressly-makes-sense/</link>
		<comments>http://myownpirateradio.com/2011/09/13/pressly-makes-sense/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 02:27:54 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[Jeff Brenner]]></category>
		<category><![CDATA[NuLayer]]></category>
		<category><![CDATA[Peter Kieltyka]]></category>
		<category><![CDATA[Pressly]]></category>
		<category><![CDATA[startups]]></category>
		<category><![CDATA[Toronto]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=464</guid>
		<description><![CDATA[Hey Jeff and Peter, I just finished watching the videos of you launching Pressly at TechCrunch Disrupt. Well done. You and your team should be really proud of what you&#8217;ve achieved. I wish you&#8217;d been given more opportunity to elaborate on your strategy to win. Instead you had to spend most of the Q&#38;A time defending Pressly&#8217;s raison &#8230; <a href="http://myownpirateradio.com/2011/09/13/pressly-makes-sense/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=464&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Hey <a title="@jeffbrenner" href="http://twitter.com/jeffbrenner">Jeff</a> and <a title="@PeterK" href="http://twitter.com/peterk">Peter</a>,</p>
<p>I just finished watching the <a href="http://techcrunch.com/2011/09/12/pressly-turns-websites-into-tablet-friendly-html5-web-apps/">videos</a> of you launching <a href="http://pressly.com">Pressly</a> at TechCrunch Disrupt. Well done. You and your team should be really proud of what you&#8217;ve achieved.</p>
<p>I wish you&#8217;d been given more opportunity to elaborate on your strategy to win. Instead you had to spend most of the Q&amp;A time defending Pressly&#8217;s raison d&#8217;etre to Dustin Moskovitz et. al. That was unfortunate; deck stacked against you. But you did a nice job staying the high road and giving solid answers to the skeptical questions.</p>
<p>Jeff, I loved your comment about publishers being great at telling stories, and not so great at building technology innovations to deliver those stories (in compelling new ways, with compelling profitability). It&#8217;s true. And it&#8217;s good, I think, that Pressly is joining a cadre of other players in this same space. Existence of multiple players is proof that the market is ready. And publishers need lots of options right now, especially ones that let them do fast, cheap experiments. Pressly can help them do that.</p>
<p>I suppose controversy-seekers could frame this as &#8220;walled garden versus open web, round 2&#8243;. That was my very first thought after watching the video. But that isn&#8217;t really the case, is it? Neither the iPad/App Store ecosystem nor HTML is going away anytime soon. There will be multiple winners in this market, with multiple technology bets. Consumers will buy many different kinds of devices, and consume content in many different places and ways. It&#8217;s probably more accurate to compare Pressly&#8217;s space to the blogging services market back when it was just getting going: Blogger, WordPress, Movable Type, and so on. Lots of experimentation and diversity, with consolidation down the road.</p>
<p>My biggest takeaway on all this is that Pressly makes a lot of sense from a publisher&#8217;s point of view. Publishers are losing sleep over how to follow their audiences to digital devices without abandoning all the assets they hold dear: their brand, destination websites, exclusive content, and UX. And with limited capital and time/runway remaining for technology investment (or investment of any kind) they have to be brutally frugal and thoughtful about what bets they make. Pressly has good answers on the economics (very little cash up front), the technology (more open), the user experience (niiice), and control issues. Clearly The Economist and Toronto Star think so, and I bet many others will reach the same conclusion.</p>
<p>I hope Pressly does really well.</p>
<p>Let me know when I can buy some shares.</p>
<p>osh</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a> Tagged: <a href='http://myownpirateradio.com/tag/jeff-brenner/'>Jeff Brenner</a>, <a href='http://myownpirateradio.com/tag/nulayer/'>NuLayer</a>, <a href='http://myownpirateradio.com/tag/peter-kieltyka/'>Peter Kieltyka</a>, <a href='http://myownpirateradio.com/tag/pressly/'>Pressly</a>, <a href='http://myownpirateradio.com/tag/startups/'>startups</a>, <a href='http://myownpirateradio.com/tag/toronto/'>Toronto</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/464/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/464/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/464/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=464&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/09/13/pressly-makes-sense/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>How to query for count of Facebook Likes and Shares on a specific URL</title>
		<link>http://myownpirateradio.com/2011/09/13/how-to-query-for-count-of-facebook-likes-and-shares-on-a-specific-url/</link>
		<comments>http://myownpirateradio.com/2011/09/13/how-to-query-for-count-of-facebook-likes-and-shares-on-a-specific-url/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 13:54:59 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[facebook API]]></category>
		<category><![CDATA[fql]]></category>
		<category><![CDATA[likes]]></category>
		<category><![CDATA[query]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=460</guid>
		<description><![CDATA[If you have a site hosting the Facebook Like button you may at times want to query Facebook for the number of Likes displayed within the button. Here&#8217;s how. I couldn&#8217;t find a way to do it with Facebook&#8217;s Graph API, but there&#8217;s good support for it in the FQL API. You can craft up &#8230; <a href="http://myownpirateradio.com/2011/09/13/how-to-query-for-count-of-facebook-likes-and-shares-on-a-specific-url/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=460&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you have a site hosting the Facebook Like button you may at times want to query Facebook for the number of Likes displayed within the button. Here&#8217;s how.</p>
<p>I couldn&#8217;t find a way to do it with <a href="http://www.google.ca/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBcQFjAA&amp;url=http%3A%2F%2Fdevelopers.facebook.com%2Fdocs%2Freference%2Fapi%2F&amp;ei=aF9vTuq5DbOisQLst8zxCQ&amp;usg=AFQjCNEP4xtTFxgkUvbpIhYIIYpvTo9VLg">Facebook&#8217;s Graph API</a>, but there&#8217;s good support for it in the <a href="http://www.google.ca/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CBcQFjAA&amp;url=http%3A%2F%2Fdevelopers.facebook.com%2Fdocs%2Freference%2Ffql%2F&amp;ei=dl9vToDVLaumsQL6ueyDCg&amp;usg=AFQjCNEZrVRlfmxmhZK27Arm-u9-XOHMaw">FQL API</a>. You can craft up queries by hand, as shown below, and issue them right from your web browser. The response is an XML document with the statistics for the URLs you want to know about. There are also FQL wrapper libraries in several languages&#8230; for Ruby I had some success with the <a href="https://github.com/nov/fb_graph">fb_graph gem</a>.</p>
<p>Multiple URLs example:</p>
<p style="padding-left:30px;"><a href="https://api.facebook.com/method/fql.query?query=select  url,like_count, total_count, share_count, click_count from link_stat where url in(&quot;http://bing.com&quot;, &quot;http://google.com&quot;, &quot;http://facebook.com&quot;, &quot;http://twitter.com&quot;)">https://api.facebook.com/method/fql.query?query=select  url,like_count, total_count, share_count, click_count from link_stat where url in(&#8220;http://bing.com&#8221;, &#8220;http://google.com&#8221;, &#8220;http://facebook.com&#8221;, &#8220;http://twitter.com&#8221;)</a></p>
<p>Single URL example:</p>
<p style="padding-left:30px;"><a href="https://api.facebook.com/method/fql.query?query=select  url,like_count, total_count, share_count, click_count from link_stat where url = &quot;http://bing.com&quot;">https://api.facebook.com/method/fql.query?query=select  url,like_count, total_count, share_count, click_count from link_stat where url = &#8220;http://bing.com&#8221;</a></p>
<p>Within the XML results, the &#8220;total_count&#8221; attribute is the number shown within the Facebook Like widget.</p>
<p>Docs:<br />
<a href="http://developers.facebook.com/docs/reference/fql/link_stat/">http://developers.facebook.com/docs/reference/fql/link_stat/<br />
</a> <a href="http://developers.facebook.com/docs/reference/fql/" target="_blank">http://developers.facebook.com/docs/reference/fql/</a></p>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a> Tagged: <a href='http://myownpirateradio.com/tag/facebook/'>facebook</a>, <a href='http://myownpirateradio.com/tag/facebook-api/'>facebook API</a>, <a href='http://myownpirateradio.com/tag/fql/'>fql</a>, <a href='http://myownpirateradio.com/tag/likes/'>likes</a>, <a href='http://myownpirateradio.com/tag/query/'>query</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/460/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/460/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/460/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=460&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/09/13/how-to-query-for-count-of-facebook-likes-and-shares-on-a-specific-url/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>Heroku, MongoHQ, and Amazon S3 Backups</title>
		<link>http://myownpirateradio.com/2011/08/04/heroku-mongohq-and-amazon-s3-backups/</link>
		<comments>http://myownpirateradio.com/2011/08/04/heroku-mongohq-and-amazon-s3-backups/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 14:24:54 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[amazon s3]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[heroku]]></category>
		<category><![CDATA[IAM]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[mongohq]]></category>
		<category><![CDATA[permissions]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=454</guid>
		<description><![CDATA[I spent a few hours yesterday convincing MongoHQ to back up a Mongo database to an Amazon S3 bucket via an Amazon &#8220;IAM&#8221; account. Here&#8217;s the secret recipe. Hopefully it saves someone time. Context: MongoHQ, which I&#8217;m using with one of my work projects right now, is a service that hosts MongoDB databases. It integrates &#8230; <a href="http://myownpirateradio.com/2011/08/04/heroku-mongohq-and-amazon-s3-backups/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=454&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I spent a few hours yesterday convincing <a href="http://mongohq.com">MongoHQ</a> to back up a <a href="http://mongodb.org">Mongo database</a> to an <a href="http://aws.amazon.com/s3/">Amazon S3 bucket</a> via an Amazon &#8220;IAM&#8221; account. Here&#8217;s the secret recipe. Hopefully it saves someone time.</p>
<p>Context: MongoHQ, which I&#8217;m using with one of my work projects right now, is a service that hosts MongoDB databases. It integrates with <a href="http://heroku.com">Heroku</a>, allowing you to get started on a Heroku app using MongoDB very quickly. <a href="http://support.mongohq.com/kb/how-tos/using-s3-backups">MongoHQ supports hourly and daily backup of their databases to Amazon S3 buckets</a>, but alas, <a href="http://support.mongohq.com/discussions/questions/131-do-you-offer-backup-for-mongohq-databases-provisioned-by-heroku">not yet for databases provisioned automatically via Heroku</a>. So if you want to step up to a backed-up database you&#8217;ll have to set up your own. Here are the steps I followed to do it.</p>
<p><strong>Secret decoder ring:</strong><br />
S3 = <a href="https://console.aws.amazon.com/s3/home">Amazon Web Services Management Console, S3 tab</a>.<br />
IAM = <a href="https://console.aws.amazon.com/iam">Amazon Web Services Management Console, IAM tab</a>.<br />
MHQ = <a href="https://mongohq.com/databases">Mongo HQ console</a>.<br />
HKU = <a href="http://heroku.com">Heroku</a>.</p>
<p><strong>Recipe:</strong></p>
<ol>
<li>S3 : Create a bucket for your app&#8217;s backups, e.g. &#8220;my-app-backups&#8221;.</li>
<li>IAM: Create an IAM User account for MongoHQ to use, e.g. &#8220;mongohq&#8221;. Download the credentials and store them safely.</li>
<li>IAM: Create an IAM Group to contain all users with backup permission, e.g. &#8220;myapp-backup-writers&#8221;.</li>
<li>IAM: Add the mongohq User account to the newly created Group.</li>
<li>IAM: Using the Permissions tab of the Group&#8217;s properties attach a new security policy, granting permission to write to the myapp-backups bucket. See below for a sample policy.</li>
<li>MHQ: Sign up for your own MongoHQ account.</li>
<li>MHQ: Create the database you wish to use with Heroku.</li>
<li>MHQ: Select the &#8220;Backups&#8221; tab and enter the IAM User credentials from step 2.</li>
<li>MHQ: Click &#8220;Save Settings&#8221;. If all is well you&#8217;ll see a message, &#8220;Setting Updated&#8221;.*</li>
<li>MHQ: Create a new user on the Database Users tab.</li>
<li>MHQ: Copy down the Mongo URI string from the Database Info tab, substituting your user name and password from step 10.</li>
<li>HKU: In the root directory of your Heroku app do &#8220;heroku config:add MONGOHQ_URL=&#8217;URI&#8217;&#8221;. URI is the Mongo URI from step 11. (Normally Heroku sets this variable for you when it provisions a MongoHQ database. You&#8217;re overriding it with a link to your own database.)</li>
</ol>
<p>* Step 9 is where I got stuck. It worked fine with my own personal security credentials, but not with the IAM account I created specifically for MongoHQ to use. (I wanted more security&#8230; giving your main account credentials to a 3rd party site isn&#8217;t smart.) I fiddled around with the security policy for quite a while, and eventually discovered I needed the &#8220;ListAllMyBuckets&#8221; permission. Here&#8217;s the security policy that worked for me:</p>
<pre>    {
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [ "s3:ListAllMyBuckets" ],
          "Resource": "arn:aws:s3:::*"
        },
        {
          "Effect": "Allow",
          "Action": [
            "s3:PutObject",
            "s3:PutObjectAcl"
          ],
          "Resource": [
            "arn:aws:s3:::MY-APP-BACKUPS/*"
          ]
        }
      ]
    }</pre>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a>, <a href='http://myownpirateradio.com/category/uncategorized/'>Uncategorized</a> Tagged: <a href='http://myownpirateradio.com/tag/amazon-s3/'>amazon s3</a>, <a href='http://myownpirateradio.com/tag/backup/'>backup</a>, <a href='http://myownpirateradio.com/tag/heroku/'>heroku</a>, <a href='http://myownpirateradio.com/tag/iam/'>IAM</a>, <a href='http://myownpirateradio.com/tag/mongodb/'>mongodb</a>, <a href='http://myownpirateradio.com/tag/mongohq/'>mongohq</a>, <a href='http://myownpirateradio.com/tag/permissions/'>permissions</a>, <a href='http://myownpirateradio.com/tag/policy/'>policy</a>, <a href='http://myownpirateradio.com/tag/security/'>security</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/454/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/454/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/454/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=454&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/08/04/heroku-mongohq-and-amazon-s3-backups/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>Notes from Howard Lindzon&#8217;s DemoCamp Toronto 29 Talk</title>
		<link>http://myownpirateradio.com/2011/06/10/notes-from-howard-lindzons-democamp-toronto-29-talk/</link>
		<comments>http://myownpirateradio.com/2011/06/10/notes-from-howard-lindzons-democamp-toronto-29-talk/#comments</comments>
		<pubDate>Fri, 10 Jun 2011 14:39:54 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[dct29]]></category>
		<category><![CDATA[democamp]]></category>
		<category><![CDATA[entrepreneur]]></category>
		<category><![CDATA[startup]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=449</guid>
		<description><![CDATA[Howard Lindzon spoke last night at DemoCamp 29 (on twitter; democamp site). It was a fun ramblin&#8217; jamblin&#8217; talk. Here are a few takeaways that stood out for me: Treat the world as flat, and find a defensible niche to start in. E.g. think of the world as the Risk game board, and pick an &#8230; <a href="http://myownpirateradio.com/2011/06/10/notes-from-howard-lindzons-democamp-toronto-29-talk/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=449&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://twitter.com/howardlindzon">Howard Lindzon</a> spoke last night at DemoCamp 29 (<a href="http://twitter.com/#!/search/dct29">on twitter</a>; <a href="http://democamp.com">democamp site</a>). It was a fun ramblin&#8217; jamblin&#8217; talk. Here are a few takeaways that stood out for me:</p>
<p><strong>Treat the world as flat, and find a defensible niche to start in.</strong> E.g. think of the world as the Risk game board, and pick an initial territory where your chances of getting established are high. If you start in Europe, you have lots of borders and the battle is much harder than, say, starting in Australia. (Or Kamchatka. Remember Kamchatka? I think I learned more geography in Risk than in school.)</p>
<p><strong>Follow your own rules.</strong> In response to an audience question about mistakes he has made in his career, Howard explained that many of them stemmed from breaking his own rules when investing, e.g. (1) investing in the market when all signs still clearly pointed to down, (2) investing in companies whose CEOs did not have deep domain experience. (Howard likes such companies best, as a rule, for his investments.)</p>
<p><strong>Have a sense of humor, especially about yourself.</strong> Howard&#8217;s self-deprecating humor made him a real pleasure to listen to, and he explained that his habit of poking fun at himself is part of why people like to follow him in social media. &#8220;I make fun of my own mistakes first, before anyone else has a chance to.&#8221;  He talked openly about passing on a few investments that would have been incredibly profitable, e.g. a chance to invest $25K in Twitter when it was valued at only $20M.</p>
<p><strong>Spot and leverage the big waves.</strong> He spoke to only one slide during the 30-or-so minutes, and it showed two graphs depicting the meteoric rise in Twitter and Facebook usage. His main point was that when you can get in front of a huge market-changing trend (like social media) you are maximizing your business opportunities to do well. &#8220;You don&#8217;t need to catch every wave. Just one amazingly great wave in your lifetime is all you really need&#8221;. Also, fighting a paradigm-changing trend is futile. So, in this specific example, which Howard calls &#8220;the social leverage trend&#8221;, figure out which of Facebook and Twitter it makes best sense to align your business with first, then integrate and try to ride the wave.</p>
<p><strong>Use your dashboards.</strong> He talked about dashboards and his view that they&#8217;re essential to business success. From memory, &#8220;What&#8217;s your dashboard? It&#8217;s never too early to start building your dashboard. &#8230; Figure out the one or two pages you need to look at every day to understand both the macro market picture and the micro [i.e. the key signals/metrics from your own business]. For me it&#8217;s http://techmeme.com, http://angellist.com, and market all time highs.&#8221; These dashboards give him &#8220;the very early market signals [from AngelList] and the loudest public market signals [from all-time highs]&#8220;.</p>
<p>Thanks Howard for a fun and frank talk.</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/uncategorized/'>Uncategorized</a> Tagged: <a href='http://myownpirateradio.com/tag/dct29/'>dct29</a>, <a href='http://myownpirateradio.com/tag/democamp/'>democamp</a>, <a href='http://myownpirateradio.com/tag/entrepreneur/'>entrepreneur</a>, <a href='http://myownpirateradio.com/tag/startup/'>startup</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/449/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/449/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/449/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=449&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/06/10/notes-from-howard-lindzons-democamp-toronto-29-talk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>ActionController::RoutingError (undefined method &#8216;sub&#8217; for nil:NilClass)</title>
		<link>http://myownpirateradio.com/2011/03/08/actioncontrollerroutingerror-undefined-method-sub-for-nilnilclass/</link>
		<comments>http://myownpirateradio.com/2011/03/08/actioncontrollerroutingerror-undefined-method-sub-for-nilnilclass/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 21:40:43 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[stupid stupid stupid]]></category>
		<category><![CDATA[technology]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[RoutingError]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=435</guid>
		<description><![CDATA[Or, &#8220;Man I&#8217;m glad Ruby on Rails is an open source framework&#8221;. Ruby on Rails normally provides pretty good debugging information for dealing with errors, but I ran into an odd error today that had no debug info other than the exception itself. Here&#8217;s what I did to find and fix the problem. Symptoms: &#8220;So, tell &#8230; <a href="http://myownpirateradio.com/2011/03/08/actioncontrollerroutingerror-undefined-method-sub-for-nilnilclass/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=435&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Or, <em>&#8220;Man I&#8217;m glad Ruby on Rails is an open source framew</em>ork&#8221;.</p>
<p>Ruby on Rails normally provides pretty good debugging information for dealing with errors, but I ran into an odd error today that had no debug info other than the exception itself. Here&#8217;s what I did to find and fix the problem.</p>
<p><strong>Symptoms: &#8220;So, tell me, how long have you been feeling this way?&#8221; </strong>I had just added a new controller, model, views, and helpers to my app. Requesting a route to any of the new controller&#8217;s actions caused Rails to die with the exception &#8220;ActionController::RoutingError (undefined method `sub&#8217; for nil:NilClass)&#8221;. No stack trace. No filename / line numbers. I knew one of the 20-odd new files I had just created must be causing the problem, but I didn&#8217;t know which one.</p>
<p><strong>Diagnosis: &#8220;Breathe in. Breathe again. Again. OK, now cough. Ah, yes, now I see the problem.&#8221;</strong>: The only way I know of to diagnose these kind of problems is brute force. I added a debugger statement to the top of application_controller.rb and restarted the app. Then I requested a URL that was causing crashes, and from the breakpoint, stepped forward in the debugger (next, next, next&#8230;) until the app died. Studying the code that executed just before the app died didn&#8217;t yield an obvious result, but about 10 frames up the stack I could see a call to ActiveSupport::Inflector#constantize. I edited that method to print (puts) the parameters it was being called with, then restarted the server and tried again. Voila: the last parameter spit out by #constantize before the server died was the culprit.</p>
<pre>#constantize PlaceLinksHelper for name PlaceLinksHelper</pre>
<p><strong>The Cure: &#8220;Take three of these and call me in the morning.&#8221; </strong>: It turns out I had created a helper module with the file name &#8220;places_helper.rb&#8221;, but within that file I mistakenly defined &#8220;module Place<strong>Links</strong>Helper&#8221;. For some reason that shall remain a mystery to me, this caused things to fall-down-go-boom. The fix was simply to give the module the name Rails expected to find: &#8220;PlacesHelper&#8221;.</p>
<p><strong>Upon Reflection&#8230; &#8220;I sure hope that doesn&#8217;t happen to me again. But it probably will.&#8221;</strong> I don&#8217;t know how you do this sort of diagnosis efficiently in a closed-source or compiled environment.  This is about the 5th time I&#8217;ve edited Rails source code to find and fix an oddball problem. I guess you could try attaching a debugger to binaries and then study the gobbledy-gook, but&#8230; no thanks. The only other thing I  could have done in a compiled/closed source setup is study each of my own files line by line. That would have worked, but it would have taken far more time.</p>
<p>Source code good.</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/stupid-stupid-stupid/'>stupid stupid stupid</a>, <a href='http://myownpirateradio.com/category/technology/'>technology</a> Tagged: <a href='http://myownpirateradio.com/tag/debugging/'>debugging</a>, <a href='http://myownpirateradio.com/tag/rails/'>rails</a>, <a href='http://myownpirateradio.com/tag/routingerror/'>RoutingError</a>, <a href='http://myownpirateradio.com/tag/ruby/'>ruby</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/435/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/435/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/435/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=435&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/03/08/actioncontrollerroutingerror-undefined-method-sub-for-nilnilclass/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>Tips on dealing with identity theft</title>
		<link>http://myownpirateradio.com/2011/02/24/tips-on-dealing-with-identity-theft/</link>
		<comments>http://myownpirateradio.com/2011/02/24/tips-on-dealing-with-identity-theft/#comments</comments>
		<pubDate>Thu, 24 Feb 2011 15:27:22 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[email account recovery]]></category>
		<category><![CDATA[identity fraud]]></category>
		<category><![CDATA[identity theft]]></category>
		<category><![CDATA[phishing]]></category>
		<category><![CDATA[strong passwords]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=430</guid>
		<description><![CDATA[Two relatives of mine have had trouble with identity theft in the past month, and it has cost them a great deal of time and anguish. I&#8217;m reposting here a brief account of what happened to them and, more importantly, tips on how you can avoid this problem and/or deal with the consequences. First, an &#8230; <a href="http://myownpirateradio.com/2011/02/24/tips-on-dealing-with-identity-theft/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=430&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Two relatives of mine have had trouble with identity theft in the past month, and it has cost them a great deal of time and anguish. I&#8217;m reposting here a brief account of what happened to them and, more importantly, tips on how you can avoid this problem and/or deal with the consequences.</p>
<h4><strong>First, an account of the nefarious deeds</strong></h4>
<p><strong>Case #1: Sally got phished</strong>. Sally received a <a href="http://en.wikipedia.org/wiki/Phishing">phishing</a> email claiming to be from &#8220;Google Account Management&#8221;, asking to reconfirm her password.* She gave them the password, only to discover a few hours later, that (a) her password had been changed, locking her out of her gmail account; (b) the phishers had sent email to all of her contacts with a &#8220;Help, I need cash fast, send me money via Western Union&#8221; scam; (c) she couldn&#8217;t get back into her gmail account because she hadn&#8217;t set the password recovery information. It took her days to get everything back to normal.</p>
<p><strong>Case #2: Jane dated a creep</strong>. Jane dated a guy who turned out not to be a good fit for her. Unfortunately they moved in together before she figured it out. She had to force a breakup, eventually kicking him out. A few days later she realized he was logging on to her email account and reading her email, and in some cases deleting emails. She changed her password, but to no avail: it seems he had installed spyware on her home computer that monitored what she was typing and informed him of password changes. Yikes.</p>
<h4><strong>Second, some advice</strong></h4>
<p>For starters, both the Canadian and US government offer comprehensive web sites that tell you what to do to protect yourself against identity theft. Here&#8217;s the <a href="http://www.priv.gc.ca/fs-fi/02_05_d_10_e.cfm">Canadian site</a>, and here&#8217;s the <a href="http://www.ftc.gov/bcp/edu/microsites/idtheft/">US site</a>. Check them out. They say roughly the same thing. I find the Canadian one a little easier to read.</p>
<p>I gave Sally and Jane some advice specific to their scenarios, as follows:</p>
<p>1.  Never reply to an email request for a password. No legitimate business will ever ask you for a password via email. If you&#8217;re wondering whether an email is &#8220;real&#8221; or not, you might try searching on <a href="http://snopes.com">Snopes</a> to see if someone else has reported the same thing.</p>
<p>2. Call Transunion, Experian, and Equifax (the credit reporting agencies) and (a) ask for a copy of your credit reports, and (b) have them flag your file with a &#8220;fraud alert&#8221; so that nobody can open an account under your name without confirmation. See the US identity theft web page for <a href="http://www.ftc.gov/bcp/edu/microsites/idtheft/consumers/defend.html">phone numbers for the credit reporting agencies</a> and a  <a href="http://www.ftc.gov/bcp/edu/microsites/idtheft/consumers/defend.html#Whatisafraudalert">description of how fraud alerts work</a>.</p>
<p>3. From a <em>secure</em> network, log in to your email provider (gmail, hotmail, whatever) and do two things:</p>
<p>(a) Change the password you use to login to email. Here&#8217;s <a href="http://www.microsoft.com/security/online-privacy/passwords-create.aspx">good advice on how to create a strong password that&#8217;s also easy to remember</a>.</p>
<p>(b) Fill in the &#8220;Password Recovery&#8221; information in your account settings. This is they info they use to confirm your identity when you click &#8220;I forgot my password&#8221;&#8230; typically, a secondary email address and/or phone number. This step is really vital because if you get hacked without filling in the recovery information you may not be able to get your account back at all.</p>
<p>Notice I suggest doing this from a <em>secure</em> network. In Jane&#8217;s case, she couldn&#8217;t safely change her password from home because her ex-boyfriend put spyware on her machine. She went to a friend&#8217;s house to do this step.</p>
<p>4. Protect your computer and home network.</p>
<p>(a) If you suspect your computer has spyware or a virus on it then install and run a virus scanner. For this I recommend <a href="http://www.avast.com/index">Avast</a>. I&#8217;ve had several experiences with Norton products crippling computers that were otherwise fine.</p>
<p>(b) If you think your home network has been compromised (like Jane&#8217;s), change the password on your home network router and cable modem / DSL modem.</p>
<p>It&#8217;s best to do 4a and 4b in unison. Get a computer-savvy person to help you if you haven&#8217;t done this before.</p>
<p>5. Report what&#8217;s happening to the police. Tell them you are concerned you&#8217;ve been or may become a victim of identity theft. Collect any evidence you can and give it to them.</p>
<p>Since identity theft is still relatively new, you may find it difficult to get police to pay attention to you. In Sally&#8217;s case, the local authorities refused to help. The US identity theft site has <a href="http://www.ftc.gov/bcp/edu/microsites/idtheft/consumers/defend.html#WhatdoIdoifthelocalpolicewonttakeareport">suggestions on what to do if local police won&#8217;t handle your report</a>, and it&#8217;s applicable to Canada (and probably other places) as well.</p>
<p>That&#8217;s it. There&#8217;s heaps more you can do, but these basic steps will help you protect yourself and recover if you run into similar problems. Here&#8217;s hoping you manage to stay problem-free.</p>
<p>* I&#8217;ve changed names to protect my peeps. They don&#8217;t need any more hassles.</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a> Tagged: <a href='http://myownpirateradio.com/tag/email-account-recovery/'>email account recovery</a>, <a href='http://myownpirateradio.com/tag/identity-fraud/'>identity fraud</a>, <a href='http://myownpirateradio.com/tag/identity-theft/'>identity theft</a>, <a href='http://myownpirateradio.com/tag/phishing/'>phishing</a>, <a href='http://myownpirateradio.com/tag/strong-passwords/'>strong passwords</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/430/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/430/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/430/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=430&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/02/24/tips-on-dealing-with-identity-theft/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>On replacing a Macbook fan</title>
		<link>http://myownpirateradio.com/2011/02/14/on-replacing-a-macbook-fan/</link>
		<comments>http://myownpirateradio.com/2011/02/14/on-replacing-a-macbook-fan/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 16:21:34 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[technology]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[laptop repair]]></category>
		<category><![CDATA[macbook pro]]></category>
		<category><![CDATA[replacement fan]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=423</guid>
		<description><![CDATA[Wherein I discover a 17&#8243; Macbook Pro needs a replacement fan, endeavour to replace said fan at a modest price, and encounter unexpected resistance along the way. We use Macs almost exclusively as our work machines these days, and we don&#8217;t have a lot of spare hardware lying around. Going without a machine for even &#8230; <a href="http://myownpirateradio.com/2011/02/14/on-replacing-a-macbook-fan/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=423&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><em>Wherein I discover a 17&#8243; Macbook Pro needs a replacement fan, endeavour to replace said fan at a modest price, and encounter unexpected resistance along the way.</em></p>
<p>We use Macs almost exclusively as our work machines these days, and we don&#8217;t have a lot of spare hardware lying around. Going without a machine for even a few hours is a big productivity hit. So the awful grinding noise that began emanating from Katrin&#8217;s Macbook last week was not a welcome sound. Luckily it was clearly coming from the fan, not the hard drive.</p>
<p>We were having an extremely busy week, and having waited days in the past for support at the local Apple store my first instinct was to find a local repair shop that could do it quickly. After all, it&#8217;s just a fan, so it should be fast and cheap, right?</p>
<p>Silly me.</p>
<p>After calling several repair shops I realized that the fix was going to run between $150 and $200. Pretty steep for a simple part swap &#8212; I can get parts in my car fixed for less than that &#8212; so I decided to do it myself.</p>
<p>Here&#8217;s what I discovered:</p>
<ol>
<li>I couldn&#8217;t find any stores in Toronto who were willing to sell me the part. They all want to do full repairs.</li>
<li>More generally, it seems Apple doesn&#8217;t allow local service providers to resell parts. They are full-service only.</li>
<li>Laptop fans are commodity even in Macs, according to one of the folks at laptopexpert.ca, so you&#8217;re better off shopping for the fan by its physical dimensions rather than an Apple part number. (I.e. you pay more for an &#8220;Apple fan&#8221; than a &#8220;laptop fan&#8221;, but they&#8217;re the same thing.) This may help in the future, but in my case I didn&#8217;t know the fan size and couldn&#8217;t find it online.</li>
<li>Darryl at <a href="http://irepair.ca">iRepair.ca</a> was most helpful on the phone and pointed me at several web sites for finding the part. He also had the most reasonable repair prices, about $50 less than everyone else I called.</li>
<li>I couldn&#8217;t find any Canadian wholesalers who had the part. Perhaps I didn&#8217;t search hard enough, but I was surprised, nevertheless.</li>
<li><a href="http://www.ifixit.com/">IFixIt.com</a> and <a href="http://www.powerbookmedic.com/">PowerBookMedic.com</a> are two US-based businesses that sell parts online. Their shipping options are slightly different, and the part prices in this case were about the same. It&#8217;s worth checking both and deciding how important delivery speed is to you.</li>
<li>There are fans for sale on eBay, but when I searched I only found used parts. A used fan is a pretty silly thing to buy, in my opinion, so&#8230; no joy there.</li>
</ol>
<p>End result: I bought a fan from IFixIt for $40, they shipped it overnight (FedEx: $40), and I paid another $5 and change in HST. I used the excellent <a href="http://www.ifixit.com/Guide/Repair/Installing-MacBook-Pro-17-Inch-Models-A1151-A1212-A1229-and-A1261-Left-Fan/332/2">IFixIt repair guide</a> and had the repair complete in under an hour. If I wasn&#8217;t in such a rush I could have chosen a $4.00 delivery option instead, and waited for US Post.</p>
<p>Thank you, IFixIt, and Darryl at iRepair.ca. Darryl, you&#8217;re first on my list the next time I need repair help.</p>
<p>P.S. I did also try an app called smcFanControl, to no avail. Worth a try.</p>
<br />Filed under: <a href='http://myownpirateradio.com/category/technology/'>technology</a> Tagged: <a href='http://myownpirateradio.com/tag/apple/'>Apple</a>, <a href='http://myownpirateradio.com/tag/laptop-repair/'>laptop repair</a>, <a href='http://myownpirateradio.com/tag/macbook-pro/'>macbook pro</a>, <a href='http://myownpirateradio.com/tag/replacement-fan/'>replacement fan</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/423/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/423/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/423/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=423&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2011/02/14/on-replacing-a-macbook-fan/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
		<item>
		<title>The case of the phantom 404s</title>
		<link>http://myownpirateradio.com/2010/12/14/the-case-of-the-phantom-404s/</link>
		<comments>http://myownpirateradio.com/2010/12/14/the-case-of-the-phantom-404s/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 16:51:46 +0000</pubDate>
		<dc:creator>Oshoma</dc:creator>
				<category><![CDATA[stupid stupid stupid]]></category>
		<category><![CDATA[crawl errors]]></category>
		<category><![CDATA[debug 404 errors]]></category>
		<category><![CDATA[magic pixie dust]]></category>
		<category><![CDATA[Rails authentication token]]></category>
		<category><![CDATA[search engine caches]]></category>

		<guid isPermaLink="false">http://myownpirateradio.com/?p=402</guid>
		<description><![CDATA[Sometimes tracking down 404 errors (HTTP &#8220;Resource not found&#8221;) on a web site is easy to do, but I ran into a tricky case yesterday that took me the better part of the afternoon to resolve. I want to share the steps I walked through in the hopes it saves someone else some time. If &#8230; <a href="http://myownpirateradio.com/2010/12/14/the-case-of-the-phantom-404s/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=402&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes tracking down 404 errors (HTTP &#8220;Resource not found&#8221;) on a web site is easy to do, but I ran into a tricky case yesterday that took me the better part of the afternoon to resolve. I want to share the steps I walked through in the hopes it saves someone else some time.</p>
<p>If you run a web site you&#8217;ll want to periodically verify that your site is being crawled properly by search engines. Both <a href="http://www.google.com/webmasters/tools">Google Webmaster tools</a> and <a href="http://www.bing.com/webmaster">Bing Webmaster</a> give you a handy &#8220;crawl errors&#8221; list which shows URLs the search engine fails to index, and the corresponding &#8220;origin&#8221; pages that link to the problem URLs.</p>
<p>This weekend I checked on Google Webmaster and was surprised to find a few hundred 404 errors in recent crawls of 5 Blocks Out. (There were no matching errors on Bing, and I&#8217;m still not sure why.)</p>
<p><strong>Warning</strong>: from here on, this blog post gets ugly. Skip to &#8220;Lessons Learned&#8221; below if you just want the punchline.</p>
<p>All the URLs looked similar to this:</p>
<blockquote>
<pre><em>5blocksout.com/q5E3Q1Db7SpV45DINIfRr28pnGRt5G/ujfe3SPV36M=</em></pre>
</blockquote>
<p>In other words, each URL had a path consisting of a long string of alphanumeric characters, and ending with an equals sign.</p>
<p>We don&#8217;t support URLs like this on 5 Blocks Out, hence all the 404 errors. But where were they coming from?</p>
<p>The crawl errors report listed many different 5 Blocks Out web pages as the origins for these problem URLs. The next step was obvious, then: look at the source code for each origin page containing a problem URL, and then fix the problem. Well, it turned out that none of the origin pages actually contained any of these problem URLs. Googlebot had discovered these URLs at crawl time, but I couldn&#8217;t find any them myself. Phantom URLs.</p>
<p>I cleared my browser cache and tried again, with the same results. Then I tried <em>wget</em>, to more closely mimic what Googlebot would see. Again, same results: I couldn&#8217;t find any of these supposed 404 URLs on the origin pages.</p>
<p>My hypotheses at this point were not pretty:</p>
<ul>
<li>A bug in the application is intermittently generating bad URLs.</li>
<li>The pages contain poorly formed HTML, which is causing Googlebot (but not Bing) to parse them incorrectly.</li>
<li>A virus or some sort of malware is corrupting the web pages.</li>
<li>A bug in our web server software or Rails is corrupting the pages.</li>
</ul>
<p>Not an appealing list to investigate, especially without a way to reproduce the problem. The &#8220;bad HTML&#8221; one was easy to eliminate by running the page through the <a href="http://validator.w3.org/">W3C Validator</a>, so that left only gnarly possibilities.</p>
<p>After a while of casting about for clues I eventually returned to looking at the URLs themselves, hoping to find patterns in their structure, the crawl dates, the origin pages&#8230; anything. And a few things struck me:</p>
<p>1. The 404 errors all began around Nov 26, which is the date I upgraded our web server to the latest versions of <a href="http://nginx.net/">nginx</a> and <a href="http://www.modrails.com/">Phusion Passenger</a>. This later turned out to be a false lead, but it seemed useful at the time.</p>
<p>2. The strings of alphanumeric characters in these phantom URLs looked similar to the <a href="http://guides.rubyonrails.org/security.html#csrf-countermeasures">authentication tokens that Rails generates</a> as a countermeasure against cross-site request forgery. Rails inserts these tokens into every page that contains an HTML form.</p>
<p>A little voice reminded me, &#8220;Hey smartypants, we have some javascript that appends authentication tokens to AJAX requests made from our web pages.&#8221; Now, that code shouldn&#8217;t have affected search engines, because it was specific to POST requests, and everyone knows that well-behaved search engine crawlers only do GET request. But still&#8230; new hypothesis: &#8220;Our javascript is mistakenly appending authentication tokens to Googlebot GET requests.&#8221;</p>
<p>How to prove it? Well, search engines have caches of crawled pages. I checked Google&#8217;s page cache and found <a href="http://webcache.googleusercontent.com/search?client=safari&amp;rls=en&amp;q=cache:5blocksout.com/tips/1419&amp;ie=UTF-8&amp;oe=UTF-8&amp;redir_esc=&amp;ei=LEsGTeG5Eo3DnAfO7szlDQ">a cached version of an origin page</a> that supposedly contained a 404 URL. The HTML source showed&#8230; drum roll&#8230; no such URL. But the HTML <em>did</em> contain javascript with an authentication code that exactly matched the path portion of the 404 URL. Bingo!</p>
<p>From there, the fix was easy. I did indeed have a bug in my javascript. The code was screening out AJAX requests with a type of &#8220;GET&#8221;, but it didn&#8217;t check for the lowercase &#8220;get&#8221;, and so it appended auth tokens in cases where it shouldn&#8217;t have.</p>
<p>Why did this start happening all of a sudden, you might ask? I don&#8217;t know. Perhaps something changed in the way Googlebot issues its HTTP requests. Maybe we&#8217;d always had this problem, and Googlebot just hadn&#8217;t yet crawled pages that exhibited it. Maybe web fairies temporarily stopped sprinkling magic pixie dust on our site. Who knows.</p>
<p><strong>Lessons learned:</strong></p>
<ul id="#lessons">
<li>Check webmaster tools and web server logs once in a while for unexplained crawl errors.</li>
<li>Remember that search engines allow you to search for cached versions of web pages. This can help with diagnosing crawl problems. (In fact, crawl error reports really ought to link directly to the cached versions of crawled pages.)</li>
<li>String comparisons don&#8217;t work very well if you don&#8217;t make them case-insensitive.</li>
</ul>
<div>For reference, here&#8217;s the diff for the problem code (in our application.js file, bound to the ajaxSend event):</div>
<pre>// Insert authenticity token into all non-GET AJAX requests
function insertAuthToken(elm, xhr, s) {
-    if (s.type == "GET") {
-        return;
-    }
+    if (s.type == 'GET' || s.type == 'get' || typeof(window.auth_token) == "undefined") return;</pre>
<br />Filed under: <a href='http://myownpirateradio.com/category/stupid-stupid-stupid/'>stupid stupid stupid</a> Tagged: <a href='http://myownpirateradio.com/tag/crawl-errors/'>crawl errors</a>, <a href='http://myownpirateradio.com/tag/debug-404-errors/'>debug 404 errors</a>, <a href='http://myownpirateradio.com/tag/magic-pixie-dust/'>magic pixie dust</a>, <a href='http://myownpirateradio.com/tag/rails-authentication-token/'>Rails authentication token</a>, <a href='http://myownpirateradio.com/tag/search-engine-caches/'>search engine caches</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/oshoma.wordpress.com/402/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/oshoma.wordpress.com/402/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/oshoma.wordpress.com/402/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=myownpirateradio.com&amp;blog=146841&amp;post=402&amp;subd=oshoma&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://myownpirateradio.com/2010/12/14/the-case-of-the-phantom-404s/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">oshoma</media:title>
		</media:content>
	</item>
	</channel>
</rss>
