<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>john.keyes.ie</title>
	<atom:link href="http://john.keyes.ie/feed/" rel="self" type="application/rss+xml" />
	<link>http://john.keyes.ie</link>
	<description>Just another Keyes Blogs weblog</description>
	<lastBuildDate>Sun, 25 Jul 2010 21:23:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Django: Changing auth backend on a live system</title>
		<link>http://john.keyes.ie/django-changing-auth-backend-on-a-live-system/</link>
		<comments>http://john.keyes.ie/django-changing-auth-backend-on-a-live-system/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 21:23:03 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[auth]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3356</guid>
		<description><![CDATA[While doing some refactoring I noticed a package that I was only using for an auth backend. I moved the module to the main application package, ran the test-suite and then deployed the changes to the live server. I then noticed that all responses from the server were error 500s. The trace included in the [...]]]></description>
			<content:encoded><![CDATA[<p>
While doing some refactoring I noticed a package that I was only using for an auth backend. I moved the module to the main application package, ran the test-suite and then deployed the changes to the live server.
</p>
<p>
I then noticed that all responses from the server were error 500s. The trace included in the email alert referred to the package name of the old auth backend. Did I miss something? Did the deploy fail?
</p>
<p>
I SSHed into the server and a quick check suggested that the deployment was successful, and that there were no references to the old auth backend.
</p>
<p>
The problem was that the auth backend my user had authenticated with was <a href="http://docs.djangoproject.com/en/dev/topics/auth/#specifying-authentication-backends">stored in the session</a>. Once I had cleared the session table, the site was operational again.
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/django-changing-auth-backend-on-a-live-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SAME FOR YOU?</title>
		<link>http://john.keyes.ie/same-for-you/</link>
		<comments>http://john.keyes.ie/same-for-you/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 15:29:09 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[same for you]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3352</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://sameforyou.com/"><img src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/07/SAME-FOR-YOU.png" alt="" title="SAME FOR YOU" width="510" height="191" class="alignnone size-full wp-image-3353" /></a>
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/same-for-you/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>the dot conf</title>
		<link>http://john.keyes.ie/the-dot-conf/</link>
		<comments>http://john.keyes.ie/the-dot-conf/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 12:38:26 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[general]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3340</guid>
		<description><![CDATA[When Thursday July 22nd. With registration starting at 10am and the first speaker at 10.30. Where National College of Ireland, Mayor St, IFSC, Dublin 1. How much FREE. More details Watch and listen to the expert: by the dot conf]]></description>
			<content:encoded><![CDATA[<h3>When</h3>
<p>
Thursday July 22nd. With registration starting at 10am and the first speaker at 10.30.
</p>
<h3>Where</h3>
<p>
<a href="http://maps.google.co.uk/maps?f=q&#038;source=s_q&#038;hl=en&#038;geocode=&#038;q=National+College+of+Ireland,+Mayor+St,+IFSC,+Dublin+1.&#038;sll=53.800651,-4.064941&#038;sspn=14.327693,39.506836&#038;ie=UTF8&#038;hq=National+College+Of+Ireland&#038;hnear=National+College+Of+Ireland,+Mayor+St,+Dublin,+Ireland&#038;t=h&#038;z=14">National College of Ireland</a>, Mayor St, IFSC, Dublin 1. 
</p>
<h3>How much</h3>
<p>
FREE.
</p>
<h3>More details</h3>
<p>
Watch and listen to the expert:
</p>
<object width="640" height="385"><param name="movie" value="http://www.youtube.com/v/Zsni1woHPOI&amp;hl=en_US&amp;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Zsni1woHPOI&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"></embed></object>

<p>
by <a href="http://thedotconf.wordpress.com/">the dot conf</a>
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/the-dot-conf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>configpy 0.5</title>
		<link>http://john.keyes.ie/configpy-0-5/</link>
		<comments>http://john.keyes.ie/configpy-0-5/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 09:17:50 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[configpy]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3334</guid>
		<description><![CDATA[While investigating support for compound keys I came to the conclusion that the best way to support them was to rewrite. I&#8217;m not a fan of the impulsive &#8220;it&#8217;s broken we have to rewrite it&#8221; clan, but sometimes it&#8217;s a necessary thing to do. The previous code didn&#8217;t handle dependency cycles gracefully, and the type [...]]]></description>
			<content:encoded><![CDATA[<p>
While investigating support for <em>compound keys</em> I came to the conclusion that the best way to support them was to rewrite.  I&#8217;m not a fan of the impulsive &#8220;it&#8217;s broken we have to rewrite it&#8221; clan, but sometimes it&#8217;s a necessary thing to do.
</p>
<p>
The previous code didn&#8217;t handle dependency cycles gracefully, and the type handling was verbose. I believe I&#8217;ve fixed these issues now, and <em>0.5</em> will be the baseline for future work.
</p>
<p>
<em>0.5</em> wasn&#8217;t just about better implementation of the existing features. It also introduces some new features like the <em>compound keys</em> mentioned earlier.
</p>
<p>
One of the features I&#8217;ve added is proper support for <strong>__getattr__</strong >. The previous support was limited to top-level keys, but the keys can now descend the configuration to any level.
</p>
<pre>
config_json = """
{
    "person": {
        "name": "John",
        "address": {
            "town": "Dublin"
        }
    }
}
"""
config = Config(config_json, restricted=False)

# in 0.4 you could do config.person['name']
"John" == config.person.name

# you can also use __getitem__
"Dublin" == config['person']['address']['town']
</pre>
<p>
<em>0.5</em> supports the use of <strong>compound variable keys</strong> to reflect the <code>__getattr__</code> functionality.
</p>
<pre>
...
    "nick": "${person.name} - ${person.address.town}"
...
"John - Dublin" == config.nick
</pre>
<p>
<strong>Expression support</strong> is now explicit, to give more control to the configuration author.  Expressions can be nested.
</p>
<pre>
config_json = """ 
{
    "a": 10,
    "b": 20,
    "c": "{{ {{ ${a} * 5 }} + ${b} }}"
}
"""
config = Config(config_json)
10 == config['a']
20 == config['b']
70 == config['c']
</pre>
<p>
Detection of <strong>variable dependency cycles</strong> is more complete, and I haven&#8217;t managed to sneak anything past it yet (I haven&#8217;t been trying any harder than the unit tests though). The check is performed up-front when parsing the configuration.
</p>
<pre>
config_json = """
{
    "a": "${c}",
    "b": {
        "d": {
            "e": "${a}"
        }
    },
    "c": "${b}"
}
"""
try:
    config = Config(config_json)
except KeyError:
    """Cycle detected"""
</pre>
<p>
That&#8217;s about it I think. The release is available on <a href="http://pypi.python.org/pypi/configpy/">PyPI</a> and <a href="http://github.com/jkeyes/configpy/downloads">GitHub</a>.
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/configpy-0-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>configpy 0.3</title>
		<link>http://john.keyes.ie/configpy-0-3/</link>
		<comments>http://john.keyes.ie/configpy-0-3/#comments</comments>
		<pubDate>Thu, 13 May 2010 11:54:33 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[configpy]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3329</guid>
		<description><![CDATA[Comments are not part of the JSON specification, but it is very useful (and sometimes necessary) to have well commented configuration files. I have added support for comments (multi-line and in-line) to configpy, therefore if a configuration has comments it is not JSON. Internally, configpy just strips the comments before parsing. Here&#8217;s a brief example: [...]]]></description>
			<content:encoded><![CDATA[<p>
Comments are not part of the <a href="http://json.org">JSON</a> specification, but it is very useful (and sometimes necessary) to have well commented configuration files.
</p>
<p>
I have added support for comments (multi-line and in-line) to <a href="http://jkeyes.github.com/configpy/">configpy</a>, therefore if a configuration has comments it is not JSON. Internally, <code>configpy</code> just strips the comments before parsing.
</p>
<p>
Here&#8217;s a brief example:
</p>
<pre>
config_str = """
/* We can use single line */
/* and multi-line
   Javascript like comments */
{
    "var_a": "AAAA", // or simple in-line comments too
    /* we can mix comments everywhere */
    "var_b": "You must escape \/* slashes in name or value strings *\/",
    "var_c": "A longer string \/\/ like this one"
}
"""

config = Config(config_str)
assert "AAAA" == config.var_a
assert "You must escape /* slashes in name or value strings */" == config.var_b
assert "A longer string // like this one" == config.var_c
</pre>
<p>
You can grab this release from <a href="http://pypi.python.org/pypi/configpy/">PyPI</a>.
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/configpy-0-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two Releases (pathfinder &amp; configpy)</title>
		<link>http://john.keyes.ie/two-releases-pathfinder-configpy/</link>
		<comments>http://john.keyes.ie/two-releases-pathfinder-configpy/#comments</comments>
		<pubDate>Thu, 13 May 2010 00:41:24 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[configpy]]></category>
		<category><![CDATA[pathfinder]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3323</guid>
		<description><![CDATA[pathfinder-0.2 fixes a bug in the NotFilter and the project is now registered on PyPI. configpy-0.2 (PyPI) has seen some big changes, the biggest of which is a change to JSON for the configuration format. There is also new expression support, with an unrestricted mode (full access to globals()).]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://jkeyes.github.com/pathfinder/">pathfinder-0.2</a> fixes a bug in the <code>NotFilter</code> and the project is now registered on <a href="http://pypi.python.org/pypi/pathfinder/">PyPI</a>.
</p>
<p>
<a href="http://jkeyes.github.com/configpy/">configpy-0.2</a> (<a href="http://pypi.python.org/pypi/configpy/">PyPI</a>) has seen some big changes, the biggest of which is a change to JSON for the configuration format.  There is also new expression support, with an unrestricted mode (full access to <code>globals()</code>).
</p>
]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/two-releases-pathfinder-configpy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shutdown and restart (automated dev env setup)</title>
		<link>http://john.keyes.ie/shutdown-and-restart/</link>
		<comments>http://john.keyes.ie/shutdown-and-restart/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 23:43:18 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[app]]></category>
		<category><![CDATA[launcher]]></category>
		<category><![CDATA[osx]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3306</guid>
		<description><![CDATA[A laptop had been my main development computer for the past four or five years, until January. Since then, I&#8217;ve been using a Mac Mini and it&#8217;s taken me some time to develop a habit for turning it off at night. The reason I dislike shutting the machine down is the time it takes to [...]]]></description>
			<content:encoded><![CDATA[<p>
A laptop had been my main development computer for the past four or five years, until January. Since then, I&#8217;ve been using a Mac Mini and it&#8217;s taken me some time to develop a habit for turning it off at night.
</p>
<p>
The reason I dislike shutting the machine down is the time it takes to setup my development environment each morning. This dislike is nothing compared to the grief I give myself for wasting electricity.
</p>
<p>
The decision was simple, I needed to automate the setup of my development environment. 
</p>
<p>
First on the agenda was to launch Terminal.app and open tabs from a shell script. I found <a href="http://blog.tlrobinson.net/post/336826012/open-new-terminal-tab-in-current-directory-updated">this script</a> which can do that for me:
</p>
<pre>#!/bin/sh -

# newtab

if [ $# -ne 1 ]; then
    PATHDIR=`pwd`
else
    PATHDIR=$1
fi

/usr/bin/osascript > /dev/null <<-EOF
activate application "Terminal"
tell application "System Events"
    keystroke "t" using {command down}
end tell
tell application "Terminal"
    repeat with win in windows
        try
            if get frontmost of win is true then
                do script "cd $PATHDIR; clear" in (selected tab of win)
            end if
        end try
    end repeat
end tell
EOF
</pre>
<p>
Next up was to be able to launch programs from these tabs. For example, I start PostgreSQL in one tab, and Apache in another.
</p>
<p>
I used the script above as a basis for this and created <code>termexec</code>:
<pre>#!/bin/sh -

/usr/bin/osascript > /dev/null <<-EOF
activate application "Terminal"
tell application "Terminal"
    repeat with win in windows
        try
            if get frontmost of win is true then
                do script "$*" in (selected tab of win)
            end if
        end try
    end repeat
end tell
EOF
</pre>
<p>
And last but not least was to launch Firefox and have it open the webapp automatically:
</p>
<pre>open $FIREFOX --args $APP_URL
</pre>
<p>
Putting all these pieces together I created a shell script called <code>devapps</code>:
</p>
<pre>#!/bin/sh -

if [ $# -ne 1 ]; then
    PATHDIR=`pwd`
else
    PATHDIR=$1
fi

# get the directory this script was launched from
bindir=`dirname $0`

# open TextMate
$bindir/termexec "cd $PATHDIR"
$bindir/termexec "mate ."

$bindir/newtab $PATHDIR # for svn, git, etc.

# start Apache
$bindir/newtab $PATHDIR 
$bindir/termexec "httpd -k restart -f $PATHDIR/dev_conf/localhost.conf"

# start PostgreSQL
$bindir/newtab $PATHDIR # for postgres
$bindir/termexec "$PATHDIR/bin/postgresql start"

# open Firefox
open $FIREFOX --args $APP_URL
</pre>
<p>
Next, I created a project specific shell script. In this case <code>demodev</code>:
</p>
<pre>#!/bin/sh

FIREFOX="/Applications/Johns/Firefox.app"
APP_URL="http://localhost:12001"

export FIREFOX APP_URL

bindir=`dirname $0`

$bindir/devapps "/Users/john/Workspace/demo/jobs"
</pre>
<p>
Almost there, but not quite. I use <a href="http://www.alfredapp.com/">Alfred App</a> to launch applications. I thought it would be nifty if I could get it to launch my <code>demodev</code> script.
</p>
<p>
I created a new workflow in <a href="http://www.apple.com/macosx/what-is-macosx/apps-and-utilities.html#automator">Automator</a> and added a <code>Run AppleScript</code> action, and inserted the following AppleScript:
</p>
<pre>on run {input, parameters}
	
	do shell script "/Users/john/bin/demodev"
	
	return input
end run
</pre>
<p>
I saved this workflow as an Application (in my case I called it Demo Development) and hey presto I was in business. To make sure this runs each time you login, you could add the app to your <em>Login Items</em>. Check out the short video below to see me launching the app from Alfred.
</p>
<object id="scPlayer" width="600" height="375"> <param name="movie" value="http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/mp4h264player.swf"></param> <param name="quality" value="high"></param> <param name="bgcolor" value="#FFFFFF"></param> <param name="flashVars" value="thumb=http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/FirstFrame.jpg&amp;containerwidth=600&amp;containerheight=375&amp;content=http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/DemoDevelopment.mp4"></param> <param name="allowFullScreen" value="true"></param> <param name="scale" value="showall"></param> <param name="allowScriptAccess" value="always"></param> <param name="base" value="http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/"></param>  <embed src="http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/mp4h264player.swf" quality="high" bgcolor="#FFFFFF" width="600" height="375" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/FirstFrame.jpg&amp;containerwidth=600&amp;containerheight=375&amp;content=http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/DemoDevelopment.mp4" allowFullScreen="true" base="http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/" scale="showall"></embed> </object>
]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/shutdown-and-restart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://content.screencast.com/users/jkeyes/folders/General/media/4de8cebe-75b7-4d37-bab7-dbce65ee99b0/DemoDevelopment.mp4" length="1557139" type="video/mp4" />
		</item>
		<item>
		<title>GitHub Gists</title>
		<link>http://john.keyes.ie/github-gists/</link>
		<comments>http://john.keyes.ie/github-gists/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 23:58:02 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[gist]]></category>
		<category><![CDATA[github]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3302</guid>
		<description><![CDATA[I discovered GitHub Gists today, so I decided to share a tiny function (Python) I wrote today to get the latest revision identifier for a git or svn sourcepool. A zero tests, zero edge cases, suck it and see approach to releasing little bits of code.]]></description>
			<content:encoded><![CDATA[<p>
I discovered <a href="http://gist.github.com/">GitHub Gists</a> today, so I decided to share <a href="http://gist.github.com/367811">a tiny function</a>  (Python) I wrote today to get the latest revision identifier for a git or svn sourcepool.
</p>
<p>
A zero tests, zero edge cases, suck it and see approach to releasing little bits of code.
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/github-gists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Follow Finder</title>
		<link>http://john.keyes.ie/google-follow-finder/</link>
		<comments>http://john.keyes.ie/google-follow-finder/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 00:15:29 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[general]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3281</guid>
		<description><![CDATA[While reading the Google Blog today I followed their link to Google Follow Finder to kick it&#8217;s tyres. It&#8217;s a simple service, you type in your Twitter username, and it returns lists of people you may like to follow based on a follower-following graph. Of the 10 people (or accounts) returned for me (see below) [...]]]></description>
			<content:encoded><![CDATA[<p>
While reading the <a href="http://googleblog.blogspot.com/2010/04/google-follow-finder-find-some-sweet.html">Google Blog</a> today I followed their link to <a href="http://followfinder.googlelabs.com">Google Follow Finder</a> to kick it&#8217;s tyres. It&#8217;s a simple service, you type in your <a href="http://twitter.com/jkeyes">Twitter</a> username, and it returns lists of people you may like to follow based on a follower-following graph.
</p>
<p>
Of the 10 people (or accounts) returned for me (see below) I am already following 9 of them. I could be wrong, but this seems to counter purpose the app.
</p>
<p>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/Follow-Finder-by-Google-jkeyes1.png"><img src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/Follow-Finder-by-Google-jkeyes1.png" alt="Follow Finder by Google" title="Follow Finder by Google" width="600" height="661" class="alignnone size-full wp-image-3299" /></a></p><p>
I clicked on the follow button to see how that functionality was integrated and I was presented with the authorisation approval screen, which I notice now uses the same &#8216;Connect&#8217; terminology as <a href="http://developers.facebook.com/connect.php">Facebook</a>.
</p>
<p>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0031.png"><img src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0031.png" alt="OAuth Screen" title="OAuth Screen" width="500" height="355" class="alignnone size-full wp-image-3296" /></a>
</p>
<p>
I am not a fan of new browser windows that hide the address bar (which happened in Safari 4.0.4, but Firefox 3.6.3 was fine), as it reduces my confidence in the process.  But I was so dizzy with curiosity, I threw caution to the wind and clicked the Connect button anyway. My hasty yet not totally irrational action resulted in the following error message:
</p>
<p>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0021.png"><img src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0021.png" alt="OAuth Error" title="OAuth Error" width="500" height="201" class="alignnone size-full wp-image-3294" /></a>
</p>
<p>
This is because the callback API supplied is different to the one registered with the Twitter API. The problem stems from the fact that the link in the original blog post contains the &#8216;www&#8217; subdomain. If you remove that and try again everything works as expected.
</p>
<p>
Once I authorised Google Follow Finder it recognised the people I was already following. I am still at a loss as to why I am presented with this list though. More confirming than finding is going on.
</p>
<p>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0041.png"><img src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/SafariScreenSnapz0041.png" alt="Already Following" title="Already Following" width="600" height="351" class="alignnone size-full wp-image-3298" /></a>
</p>
<p>
I wonder has anyone found some sweet new followers with Follow Friend? Why have Google released this I wonder?
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/google-follow-finder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Football updates on the mobile web</title>
		<link>http://john.keyes.ie/football-updates-on-the-mobile-web/</link>
		<comments>http://john.keyes.ie/football-updates-on-the-mobile-web/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 09:19:46 +0000</pubDate>
		<dc:creator>John Keyes</dc:creator>
				<category><![CDATA[general]]></category>

		<guid isPermaLink="false">http://john.keyes.ie/?p=3252</guid>
		<description><![CDATA[I don&#8217;t get to watch many football matches nowadays, so my iPhone is essential for feeding me the latest updates. The two sites I frequent most often to get live updates are The Guardian and the BBC. While keeping an eye on the Blackburn Rovers versus Manchester United game last weekend, I was annoyed by [...]]]></description>
			<content:encoded><![CDATA[<p>
I don&#8217;t get to watch many football matches nowadays, so my iPhone is essential for feeding me the latest updates.  The two sites I frequent most often to get live updates are <a href="http://www.guardian.co.uk/sport">The Guardian</a> and the <a href="http://news.bbc.co.uk/sport/">BBC</a>.
</p>
<p>
While keeping an eye on the Blackburn Rovers versus Manchester United game last weekend, I was annoyed by all the cruft at the top of the page.  As you can see in the following screenshots (click for larger size), there is no mention of the current score on either site. The only relevant match information on The Guardian page is what teams are playing.
</p>
<p>
On desktop browsers the live update pages are automatically refreshed.  Unfortunately this is not the case on mobile Safari. It doesn&#8217;t take long to get frustrated by this as you have to scroll past it twice (up to top of page, press refresh, back to content) every time you refresh.
</p>
<p>
<a style="margin-right: 10px;" href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518263099_fe4b6908e3_o.jpg"><img style="padding: 3px; background-color: #DDD;" src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518263099_fe4b6908e3_o-200x300.jpg" alt="" title="4518263099_fe4b6908e3_o" width="200" height="300" class="alignnone size-medium wp-image-3253" /></a>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518262583_40557e3804_o.jpg"><img style="padding: 3px; background-color: #DDD;" src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518262583_40557e3804_o-200x300.jpg" alt="" title="4518262583_40557e3804_o" width="200" height="300" class="alignnone size-medium wp-image-3254" /></a>
</p>
<p>
After scrolling past the images I could see the updates. As you can see both sites take a slightly different approach here. The BBC site prefixes updates with the time of day, while The Guardian prefixes with the time elapsed in the game.   The Guardian also include some rather unhelpful information about refreshing with the F5.
</p>
<p>
<a style="margin-right: 10px;" href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518895638_8c33f74fb8_o.jpg"><img style="padding: 3px; background-color: #DDD;" src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518895638_8c33f74fb8_o-200x300.jpg" alt="" title="4518895638_8c33f74fb8_o" width="200" height="300" class="alignnone size-medium wp-image-3257" /></a>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518261749_0339652e10_o.jpg"><img style="padding: 3px; background-color: #DDD;" src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/4518261749_0339652e10_o-200x300.jpg" alt="" title="4518261749_0339652e10_o" width="200" height="300" class="alignnone size-medium wp-image-3256" /></a>
</p>
<p>
I mocked up what I would like to see on one of these sites. For no particular reason I picked The Guardian for the example.
</p>
<p>
In the spirit of maximizing the amount of information relevant to the match I decided to eliminate navigation elements (I can use the back functionality of the browser for that), reduce the size of the branding graphic, have the latest score fixed to the top of the screen, and use match time prefixes like The Guardian already use.
</p>
<p>
<a href="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/football_update2.png"><img style="padding: 3px; background-color: #DDD;" src="http://c1935242.cdn.cloudfiles.rackspacecloud.com/2010/04/football_update2-200x300.png" alt="" title="football_update" width="200" height="300" class="alignnone size-medium wp-image-3279" /></a>
</p>
<p>
 In the words of King Kev &#8220;I would love it&#8221; if The Guardian page was like this.
</p>]]></content:encoded>
			<wfw:commentRss>http://john.keyes.ie/football-updates-on-the-mobile-web/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
