<?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>George Brocklehurst's weblog</title>
	<atom:link href="http://blog.georgebrock.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.georgebrock.com</link>
	<description>Because some things are too long for Twitter</description>
	<lastBuildDate>Fri, 19 Feb 2010 00:15:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Managing Heroku deployments</title>
		<link>http://blog.georgebrock.com/code/managing-heroku-deployments</link>
		<comments>http://blog.georgebrock.com/code/managing-heroku-deployments#comments</comments>
		<pubDate>Thu, 18 Feb 2010 23:59:13 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=221</guid>
		<description><![CDATA[Heroku is a fantastic service for hosting Ruby applications. It&#8217;s wonderfully simple to use: You just add Heroku as a Git remote and whenever you want to deploy some changes, you push them to that remote&#8217;s master branch. Heroku even provide a handy gem that does everything from adding the remote to running tasks on [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://heroku.com/">Heroku</a> is a fantastic service for hosting Ruby applications. It&#8217;s wonderfully simple to use: You just add Heroku as a <a href="http://www.kernel.org/pub/software/scm/git/docs/git-remote.html">Git remote</a> and whenever you want to deploy some changes, you push them to that remote&#8217;s master branch. Heroku even provide a handy <a href="http://docs.rubygems.org/">gem</a> that does everything from adding the remote to running tasks on the remote version of your application, all via the <tt>heroku</tt> command.</p>
<p>If you&#8217;re already using Git, getting a Rails app set up on Heroku is as simple as running these commands:</p>
<pre><tt>gem install heroku
cd myapp
heroku create
git push heroku master
heroku rake db:migrate
</tt></pre>
<p>This standard workflow is great for the early stages of development or for simple applications, but with a large application you&#8217;ll probably want to put a few more safeguards in place. <span class="vcard"><a class="fn url" rel="friend co-worker met" href="http://tomlea.co.uk/">Tom Lea</a></span> and I have recently found ourseveles in exactly that situation, so we&#8217;ve written a few <a href="http://rake.rubyforge.org/">Rake</a> tasks to make sure we don&#8217;t mess anything up when we&#8217;re deploying changes.</p>
<p>What we wanted was:</p>
<ol>
<li>Multiple Heroku remotes: One for staging and one for production.</li>
<li>Backups as part of the deploy process, so its easy to roll back mistakes.</li>
<li>Automatic tagging of deployments.</li>
</ol>
<p>I&#8217;ll explain how and why we did all of this shortly, but first things first…</p>
<h2>The code</h2>
<p><script src="http://gist.github.com/308224.js?file=Rakefile" type="text/javascript"></script><noscript><a href="http://gist.github.com/308224">The code is on GitHub</a></noscript></p>
<h2>Multiple Heroku remotes</h2>
<p>The first thing we wanted to do was set up a second Heroku remote where we could preview and demonstrate changes without endangering the production app.</p>
<p>The <tt>heroku</tt> command usually figures out which application to send commands to by looking at the Git remotes of the current directory and picking the first one it find that points to heroku.com.  This isn&#8217;t too helpful if you have multiple Heroku remotes, but fortunately there&#8217;s an optional <tt>--app</tt> argument which lets you explicity specify which remote you&#8217;re referring to.</p>
<p>To make sure we don&#8217;t accidentally run commands against the wrong remote app, we&#8217;ve removed the Heroku git remotes altogether.</p>
<p>Now instead of this:</p>
<pre><tt>git push heroku master
heroku rake db:migrate
</tt></pre>
<p>We use this:</p>
<pre><tt>git push git@heroku.com:myapp.git master
heroku rake db:migrate --app myapp
</tt></pre>
<h2>Backup before deployment</h2>
<p>The second thing we wanted was to be able to roll back quickly if we messed up a deploy.  Heroku has a helpful <a href="http://docs.heroku.com/backups">backup feature</a> that allows you to capture, download and most importantly restore a tarball containing the app&#8217;s code and database using the <tt>heroku bundle</tt> command.  We capture a bundle immediately before deploying and download a copy of it:</p>
<pre><tt>heroku bundles:destroy deploybackup --app myapp
heroku bundles:capture deploybackup --app myapp
heroku bundles:download deploybackup --app myapp
</tt></pre>
<p>The first command (<tt>heroku bundles:destroy</tt>) will delete the bundle named &#8220;deploybackup&#8221; from Heroku. If you are using the <a href="http://addons.heroku.com/bundles">unlimited bundles</a> add-on you could skip this step and use a unique bundle name each time instead.</p>
<p>Capturing a bundle takes some time, so you can&#8217;t just run these commands one after another in a script but it is possible to see the current state of your app&#8217;s bundles using the <tt>heroku bundle</tt> command, so it&#8217;s easy enough to wait while Heroku creates the bundle using a <code>while</code> loop and a <code>sleep</code>.</p>
<h2>Tagging deployments</h2>
<p>Our final aim was to track what we had deployed and when we had deployed it using <a href="http://www.kernel.org/pub/software/scm/git-core/docs/git-tag.html">Git tags</a>.  Exactly how you tag and deploy will depend on how you use Git.</p>
<p>For our project, we have a production branch which we merge our changes into when we&#8217;re ready to deploy them, so our deploy tasks are set up to push the head of that branch. For example, if we were deploying on 1st February 2010, the commands we would use would look something like this:</p>
<pre><tt>git tag heroku-2010-02-01 production
git push git@heroku.com:myapp.git heroku-2010-02-01:master
</tt></pre>
<p>If you do something different it should be easy enough to change the scripts to suit.</p>
<h2>Fork me</h2>
<p>I&#8217;ve put the <a href="http://gist.github.com/308224">code on GitHub</a> in a gist, feel free to fork and improve it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/code/managing-heroku-deployments/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Spriter: Easy CSS sprites</title>
		<link>http://blog.georgebrock.com/projects/spriter</link>
		<comments>http://blog.georgebrock.com/projects/spriter#comments</comments>
		<pubDate>Thu, 04 Feb 2010 17:26:13 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[reevoo]]></category>
		<category><![CDATA[sprites]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=210</guid>
		<description><![CDATA[CSS Sprites are really useful but tricky to maintain, so Craig Smith and I wrote a little Ruby gem to make it much easier to manage them.
Our CSS is now in .spriter files, and using a sprite is as easy as a normal CSS background image:
span.icon {
  -spriter-background: 'icon.png';
}

There&#8217;s a Rack middleware that converts [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.alistapart.com/articles/sprites/">CSS Sprites</a> are really useful but tricky to maintain, so <span class="vcard"><a class="fn url" rel="friend co-worker met" href="http://craigmarksmith.co.uk/">Craig Smith</a></span> and I wrote a little Ruby gem to make it much easier to manage them.</p>
<p>Our CSS is now in <tt>.spriter</tt> files, and using a sprite is as easy as a normal CSS background image:</p>
<pre><code>span.icon {
  -spriter-background: 'icon.png';
}
</code></pre>
<p>There&#8217;s a Rack middleware that converts <tt>.spriter</tt> files to CSS and generates the sprite images on request which we use in development, and a few simple methods to create static assets that we use when deploying to production.</p>
<p>If you&#8217;re interested you can read more on the <a href="http://www.reevoo.com/labs/2010/02/spriter/">Reevoo blog</a> and <a href="http://github.com/reevoo/spriter">get the code from GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/projects/spriter/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing microformats in Rails applications with assert-microformats</title>
		<link>http://blog.georgebrock.com/projects/testing-microformats-in-rails-applications-with-assert-microformats</link>
		<comments>http://blog.georgebrock.com/projects/testing-microformats-in-rails-applications-with-assert-microformats#comments</comments>
		<pubDate>Mon, 01 Jun 2009 02:00:55 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[test-driven development]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=195</guid>
		<description><![CDATA[I&#8217;ve recently been doing a few things using Ruby on Rails. Being a proponent of microformats and increasingly a fan of test-driven development I wanted to write some tests to make sure that the microformats being produced by the Rails app I&#8217;m working on were all in the right places and contained the right information, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently been doing a few things using <a href="http://rubyonrails.org/">Ruby on Rails</a>. Being a proponent of <a href="http://microformats.org/">microformats</a> and increasingly a fan of <a href="http://en.wikipedia.org/wiki/Test-driven_development">test-driven development</a> I wanted to write some tests to make sure that the microformats being produced by the Rails app I&#8217;m working on were all in the right places and contained the right information,  so a couple of days ago I wrote a little <a href="http://rubyonrails.org/">Gem</a> called <strong>assert-microformats</strong>.</p>
<p>You can include it in your Rails app by adding this line to your test environment config file (<tt>config/environments/test.rb</tt>):</p>
<pre><code>config.gem "georgebrock-assert-microformats", :source => "http://gems.github.com/", :lib => false</code></pre>
<p>Now you can test your microformats using some shiny new assertions.</p>
<p>By default these assertions will look for microformats in Rails&#8217; <code>@response</code>:</p>
<pre><code>test "show view should contain an hcard" do
  get :show
  assert_mf_hcard
end</code></pre>
<p>You can also test the values of microformat attributes:</p>
<pre><code>assert_mf_hcard :fn => 'George Brocklehurst', :url => 'http://georgebrock.com/'</code></pre>
<p>And you can pass in some HTML, which comes in handy when you&#8217;re testing view helpers or not using Rails at all:</p>
<pre><code>assert_mf_hcalendar my_html, :summary => 'Birthday party'</code></pre>
<p>The microformat parsing is done using <a href="http://mofo.rubyforge.org/">Mofo</a>, so assert-microformats supports all the microformats that Mofo supports.</p>
<p>If you&#8217;re interested in how it works, or you want to make any changes, <a href="http://github.com/georgebrock/assert-microformats">the code is all on GitHub</a>.</p>
<p>I&#8217;d also like to thank <span class="vcard"><a href="http://tomlea.co.uk" class="fn url" rel="friend met">Tom Lea</a></span> for looking over the code and making some improvements.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/projects/testing-microformats-in-rails-applications-with-assert-microformats/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>XFN and the rev attribute</title>
		<link>http://blog.georgebrock.com/code/xfn-and-the-rev-attribute</link>
		<comments>http://blog.georgebrock.com/code/xfn-and-the-rev-attribute#comments</comments>
		<pubDate>Thu, 14 May 2009 09:13:20 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[markup]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[rel]]></category>
		<category><![CDATA[rev]]></category>
		<category><![CDATA[semantics]]></category>
		<category><![CDATA[xfn]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=155</guid>
		<description><![CDATA[Background: XFN and rel
XFN is a microformat that expresses relationships.  If a page represents you (for example your blog or your profile on a social network site) you can annotate the links on that page to indicate whether you are linking to another of your own profiles or to a friend, colleague or contact&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<h3>Background: <acronym title="XHTML Friends Network">XFN</acronym> and <code>rel</code></h3>
<p><a href="http://microformats.org/wiki/xfn"><acronym title="XHTML Friends Network">XFN</acronym></a> is a <a href="http://microformats.org">microformat</a> that expresses relationships.  If a page represents you (for example your blog or your profile on a social network site) you can annotate the links on that page to indicate whether you are linking to another of your own profiles or to a friend, colleague or contact&#8217;s page.</p>
<p>The annotations are made using the <abbr title="Extensible Hypertext Markup Language or Hypertext Markup Language">(X)HTML</abbr> <code>rel</code> attribute.  The HTML 4 specification provides several <a title="Link types in the HTML 4 specification" href="http://www.w3.org/TR/REC-html40/types.html#type-links">standard values for the <code>rel</code> attribute</a> include <code>next</code>, <code>prev</code> and <code>contents</code>.  In an age of social networks, where URLs often represent people, XFN is a logical extension of this attribute.</p>
<p>Of course, this is open to abuse.  I could add a link to this page that points to someone else&#8217;s site and uses XFN to claim that it is also my site.  This is why the claims made by XFN are generally not trusted unless they are reciprocal.  For example, this blog links to <a href="http://georgebrock.com">georgebrock.com</a> and <a href="http://georgebrock.com">georgebrock.com</a> links back to this blog.  Both pages claim that the other site is about the same person, and because the claim is reciprocal it can be considered trustworthy.</p>
<h3>XFN and <code>rev</code></h3>
<p>I&#8217;ve recently been building a social networking site, and marking up the user profiles and contact lists using a combination of <a href="http://microformats.org/wii/hcard">hCard</a> and XFN.  While I was marking this up I found myself reaching not only for the <code>rel</code> attribute, but also the less common <code>rev</code> attribute.  The <code>rev</code> attribute specifies the reverse relationship described by the link, for example <code>rel="prev"</code> is equivalent to <code>rev="next"</code>.</p>
<p>This is the markup that I came up with:</p>
<pre><code> &lt;h3&gt;<strong>1 user wants to be your friend</strong>&lt;/h3&gt;
 &lt;ul&gt;
   &lt;li class="vcard"&gt;
     &lt;a <strong>rev="friend"</strong> class="fn url" href="…"&gt;
       Tom Smith
     &lt;/a&gt;
   &lt;/li&gt;
 &lt;/ul&gt;

 &lt;h3&gt;<strong>Waiting for confirmation from 1 user</strong>&lt;/h3&gt;
 &lt;ul&gt;
   &lt;li class="vcard"&gt;
     &lt;a <strong>rel="friend"</strong> class="fn url" href="…"&gt;
       Dick Jones
     &lt;/a&gt;
   &lt;/li&gt;
 &lt;/ul&gt;

 &lt;h3&gt;<strong>Friends with 1 user</strong>&lt;/h3&gt;
 &lt;ul&gt;
   &lt;li class="vcard"&gt;
     &lt;a <strong>rel="friend" rev="friend"</strong> class="fn url" href="…"&gt;
       Harry Taylor
     &lt;/a&gt;
   &lt;/li&gt;
 &lt;/ul&gt;</code></pre>
<p>I&#8217;ve also considered using some of my own link types (with an accompanying <a href="http://microformats.org/wiki/xmdp"><acronym title="XHTML Meta Data Profile">XMDP</acronym> document</a>, of course).  For example, if you have asked to be friends with someone and they haven&#8217;t yet confirmed the relationship that could be made more explicit using <code>rel="friend" rev="unconfirmed"</code> on your profile and inverse on their profile: <code>rel="unconfirmed" rev="friend"</code>.</p>
<h3>Pros and cons</h3>
<p>There are a few things about this that I really like:</p>
<ol>
<li>The markup is more semantically rich that it would be if only using <code>rel</code>.  It expresses not only all the claims that a user has made, but also all the claims that have been made about that user, even if they are not (or not yet) reciprocal.</li>
<li>Having all the relationship information about a given user in one place makes it incredibly easy to extract very specific information with a tool like <a href="http://developer.yahoo.com/yql"><acronym title="Yahoo Query Langauge">YQL</acronym></a> or <a href="http://www.w3.org/2004/01/rdxh/spec"><acronym title="Gleaning Resource Descriptions from Dialects of Languages">GRDDL</acronym></a> without having to rely on specific knowledge of the page structure.</li>
</ol>
<p>There are also a few things that I don&#8217;t like:</p>
<ol>
<li>The <code>rev</code> attribute isn&#8217;t often used and is commonly misunderstood (although I&#8217;m not sure why, <a title="HTML 4 specifiction: Forward and reverse links" href="http://www.w3.org/TR/REC-html40/struct/links.html#h-12.3.1">the specification is very clear</a> on what it means). Because of the lack of understanding the microformats wiki <a title="Microformats wiki, rel attribute FAQ: Should rev even be used?" href="http://microformats.org/wiki/rel-faq#Should_rev_even_be_used">strongly discourages the use of <code>rev</code></a>.</li>
<li>It has been suggested that <a title="Microformats wiki, XFN brainstorming: Discussion of rel-fan proposal" href="http://microformats.org/wiki/xfn-brainstorming#rejected_fan_follower_terms">using <code>rev</code> instead of <code>rel</code> for XFN link types is tantamount to creating a whole new microformat</a>.</li>
<li>The reason reciprocal claims are trustworthy is that they are made by both of the pages involved. This markup claims reciprocation without involving the other page.  While this makes sense in this specific case (the links are between profiles in the same site and are being automatically generated based on the same set of data) it would not be good in the general case to assume that just because a link has both <code>rel</code> and <code>rev</code> it is reciprocal and therefore trustworthy.</li>
</ol>
<h3>What do you think?</h3>
<p>I&#8217;ve not previously seen the link types defined in  XFN used with the <code>rev</code> attribute, so I&#8217;m curious what other developers, and particularly those in the microformats community think of this?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/code/xfn-and-the-rev-attribute/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Open Hack London: XFN Profile Discovery</title>
		<link>http://blog.georgebrock.com/events/open-hack-london-xfn-profile-discovery</link>
		<comments>http://blog.georgebrock.com/events/open-hack-london-xfn-profile-discovery#comments</comments>
		<pubDate>Wed, 13 May 2009 16:52:49 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[events]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hack day]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[openhacklondon]]></category>
		<category><![CDATA[social graph]]></category>
		<category><![CDATA[xfn]]></category>
		<category><![CDATA[yql]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=162</guid>
		<description><![CDATA[Yahoo hosted another of their Open Hack events in London  this weekend.  I took the opportunity to play around with YQL, the Google Social Graph API and the XFN microformat and built a Greasemonkey script that recognises when you&#8217;re on a social network profile and finds other social network profiles belonging to the [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_163" class="wp-caption alignright" style="width: 213px"><a href="http://blog.georgebrock.com/wp-content/uploads/2009/05/openhack_profile_discovery.png"><img class="size-full wp-image-163" title="XFN profile discovery" src="http://blog.georgebrock.com/wp-content/uploads/2009/05/openhack_profile_discovery.png" alt="Screenshot of XFN profile discovery" width="203" height="512" /></a><p class="wp-caption-text">Screenshot of XFN profile discovery</p></div>
<p><span class="vevent">Yahoo hosted another of their <a class="url summary" href="http://openhacklondon.pbworks.com/">Open Hack</a> events in <span class="location">London</span> <span class="dtstart"><span class="value-title" title="2009-05-09"> </span>this weekend</span></span>.  I took the opportunity to play around with <a href="http://developer.yahoo.com/yql/"><acronym title="Yahoo! Query Language">YQL</acronym></a>, the <a href="http://code.google.com/apis/socialgraph/">Google Social Graph <acronym title="Application Programming Interface">API</acronym></a> and the <a href="http://microformats.org/wiki/xfn"><acronym title="XHTML Friends Network">XFN</acronym> microformat</a> and built a <a href="http://www.greasespot.net/">Greasemonkey</a> script that recognises when you&#8217;re on a social network profile and finds other social network profiles belonging to the same person.</p>
<p>If you want to try it out, just follow these simple steps:</p>
<ol>
<li>Get <a href="http://getfirefox.com">Firefox</a> and <a href="https://addons.mozilla.org/en-US/firefox/addon/748" title="Greasemonkey installation page">Greasemonkey</a>.</li>
<li>Visit this page to install the plugin: <a href="http://georgebrock.com/openhack2009/xfndiscovery.user.js">georgebrock.com/openhack2009/xfndiscovery.user.js</a></li>
<li>Go to a profile page (like a <a href="http://twitter.com/georgebrock" rel="me">Twitter page</a>, or even this blog) and you&#8217;ll see a &ldquo;more user profiles&rdquo; link in the rop right corner of the page</li>
</ol>
<p>If you&#8217;re more interested in how it works, you can find the <a href="http://github.com/georgebrock/XFN-Profile-Detection">source code on GitHub</a>.</p>
<p>It starts by looking for links that use <code>rel="me"</code> (XFN&#8217;s way of saying &#8220;this link points to another page about the same person as this page&#8221;).  If it find any it uses YQL (and <a href="http://www.xml.com/pub/a/2007/09/04/parsing-microformats.html?page=2">a clever bit of XPath magic</a> from <span class="vcard"><a class="fn url" href="http://suda.co.uk">Brian Suda</a></span>) to find more <code>rel="me"</code> links on those page and so on until it runs out of profile links. To make sure nothing&#8217;s been missed it&#8217;ll bundle together all of the URLs that it&#8217;s found and pass them to the Google Social Graph API.  If the <acronym title="Social Graph">SG</acronym> API finds any new unique URLs they are parsed with YQL too.  The combination of YQL and the SG API means that the script gets good coverage for most people, whether or not they have deliberately made use of <code>rel="me"</code>.</p>
<p>One fun thing about building this hack was finding my own profiles on sites that I&#8217;d forgotten about (it turns out I have a <a rel="me" href="http://georgebrock.soup.io">soup.io</a> account).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/events/open-hack-london-xfn-profile-discovery/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lastify: More Last.fm/Spotify hacking</title>
		<link>http://blog.georgebrock.com/projects/lastify-more-lastfm-and-spotify-hacking</link>
		<comments>http://blog.georgebrock.com/projects/lastify-more-lastfm-and-spotify-hacking#comments</comments>
		<pubDate>Sun, 18 Jan 2009 00:18:42 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[SIMBL]]></category>
		<category><![CDATA[spotify]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=55</guid>
		<description><![CDATA[Mere days after I built my Spotify Scrobbler, the wonderful people who make Spotify added native scrobbling support.  As you&#8217;d expect, it was a lot more stable and easier to use than my SIMBL hack, and it&#8217;s made me even more of a Spotify fan.  The only problem with the Last.fm integration now is the [...]]]></description>
			<content:encoded><![CDATA[<p>Mere days after I built <a href="http://blog.georgebrock.com/events/lastfm-hack-day-scrobbling-spotify">my Spotify Scrobbler</a>, the wonderful people who make <a href="https://www.spotify.com/">Spotify</a> added native scrobbling support.  As you&#8217;d expect, it was a lot more stable and easier to use than my <a href="http://www.culater.net/software/SIMBL/SIMBL.php"><abbr title="Smart Input Manager Bundle Loader">SIMBL</abbr></a> hack, and it&#8217;s made me even more of a Spotify fan.  The only problem with the <a href="http://last.fm">Last.fm</a> integration now is the lack of “Love” and “Ban” buttons.  Which got me thinking, why not write another SIMBL plugin? After all, it wouldn&#8217;t be that different from what I&#8217;d already done.</p>
<p>So here it is, Lastify in all its glory:</p>
<div id="attachment_56" class="wp-caption alignnone" style="width: 310px"><a href="http://blog.georgebrock.com/wp-content/uploads/2009/01/lastify.png"><img class="size-medium wp-image-56" title="Lastify" src="http://blog.georgebrock.com/wp-content/uploads/2009/01/lastify-300x252.png" alt="Lastify adds a drawer to the bottom of the Spotify window" width="300" height="252" /></a><p class="wp-caption-text">Lastify adds a drawer to the bottom of the Spotify window</p></div>
<p><ins datetime="2009-03-10T16:41:26+00:00"><strong>Update:</strong> Lastify now supports <a href="http://www.last.fm/help/faq?category=Artist+Pages#230">tagging</a> and has a <a href="http://georgebrock.com/misc/lastify-screenshot.png">much prettier user interface</a>.</ins></p>
<p>If you want to try Lastify you&#8217;ll need to install <a href="http://www.culater.net/software/SIMBL/SIMBL.php">SIMBL</a> first and everything else you need is <a title="Lastify repository on GitHub" href="http://github.com/georgebrock/lastify">hosted over on GitHub</a>.</p>
<p>It&#8217;s a quick-and-dirty hack, and so all the usual caveats apply.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/projects/lastify-more-lastfm-and-spotify-hacking/feed</wfw:commentRss>
		<slash:comments>37</slash:comments>
		</item>
		<item>
		<title>Last.fm Hack Day: Scrobbling Spotify</title>
		<link>http://blog.georgebrock.com/events/lastfm-hack-day-scrobbling-spotify</link>
		<comments>http://blog.georgebrock.com/events/lastfm-hack-day-scrobbling-spotify#comments</comments>
		<pubDate>Mon, 15 Dec 2008 06:13:02 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[events]]></category>
		<category><![CDATA[cocoa]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hack day]]></category>
		<category><![CDATA[last.fm]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[SIMBL]]></category>
		<category><![CDATA[spotify]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=10</guid>
		<description><![CDATA[Sunday was Last.fm&#8217;s first Hack Day (and my first Hack Day too) a great opportunity to get together with a bunch of other developers, enjoy a steady supply of free food, coffee and beer and spend the day hacking away at whatever Last.fm-related projects we could dream up. I particularly liked Neil Crosby&#8217;s Last Genius [...]]]></description>
			<content:encoded><![CDATA[<p>Sunday was <a href="http://www.last.fm/group/Hack+Day">Last.fm&#8217;s first Hack Day</a> (and my first Hack Day too) a great opportunity to get together with a bunch of other developers, enjoy a steady supply of free food, coffee and beer and spend the day hacking away at whatever Last.fm-related projects we could dream up. I particularly liked <span class="vcard"><a class="fn url" rel="friend met" href="http://neilcrosby.com/">Neil Crosby</a></span>&#8217;s <a href="http://github.com/NeilCrosby/last-genius/tree">Last Genius</a> which builds a playlist of simiar music based on a single starting track and <span class="vcard"><a class="fn url" rel="acquaintance met" href="http://www.last.fm/user/flaneur/">Matt Ogle</a>&#8217;s</span> <a href="http://playground.audioscrobbler.com/matt/hackday/">Songcolours</a> which draws pretty graphs based the most common words in the lyrics of your favourite songs.</p>
<p>I spent the day playing around with <a href="http://www.culater.net/software/SIMBL/SIMBL.php"><abbr title="Smart InputManager Bundle Loader">SIMBL</abbr></a>, <a href="http://www.spotify.com">Spotify</a> and, of course, the <a href="http://www.last.fm/api">Last.fm <acronym title="Application Programming Interface">API</acronym></a> trying to build a Spotify <a title="Last.fm FAQ: What is scrobbling?" href="http://www.last.fm/help/faq?category=Scrobbling">Scrobbler</a>.  Progress was slower than I would have liked and I spent most of the day trying to figure out Spotify&#8217;s internal APIs and following various dead-ends (reverse engineering compiled software is tricky), but it was good to learn how to write SIMBL bundles and by the end of the day I&#8217;d managed to hack together a working plugin that was aware of when a new track started and what the track and artist names were. It seemed a shame to leave it half done, so I spent some time when I got home adding scrobbling capabilities, and you can now find a <a href="http://github.com/georgebrock/spotify-scrobbler/tree/master">working Spotify Scrobbler over on GitHub</a> (if you want to use it you&#8217;ll find instructions in the <a href="http://github.com/georgebrock/spotify-scrobbler/tree/master/README.Markdown">read-me file</a>).  It&#8217;s not particularly polished, but I&#8217;m pretty pleased with how it turned out. All in all, a good first Hack Day.</p>
<p><strong>Update:</strong> As of 18th December 2008 <a href="http://www.spotify.com/blog/archives/2008/12/18/spotify-scrobbles/">Spotify has built-in scrobbling support</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/events/lastfm-hack-day-scrobbling-spotify/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Brand new blog</title>
		<link>http://blog.georgebrock.com/blog/brand-new-blog</link>
		<comments>http://blog.georgebrock.com/blog/brand-new-blog#comments</comments>
		<pubDate>Fri, 12 Dec 2008 23:09:46 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[blog]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[motiviation]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=4</guid>
		<description><![CDATA[Whoever thought this would happen, I&#8217;m blogging again. Anyone who followed my previous blogging efforts will know I&#8217;m not very good at it, but I need a place to talk about projects, software releases and anything else that&#8217;s too long for Twitter and throwing up random HTML files ever few weeks isn&#8217;t very sustainable.  [...]]]></description>
			<content:encoded><![CDATA[<p>Whoever thought this would happen, I&#8217;m blogging again. Anyone who followed my previous blogging efforts will know I&#8217;m not very good at it, but I need a place to talk about projects, software releases and anything else that&#8217;s too long for Twitter and throwing up random <abbr title="Hypertext Markup Language">HTML</abbr> files ever few weeks isn&#8217;t very sustainable.  So here it is.  This is part of a more general overhaul of <a href="http://georgebrock.com">georgebrock.com</a> which includes a shiny new activity stream (hacked together remarkably quickly with <a href="http://pipes.yahoo.com/pipes/pipe.info?_id=4e797fb26afe0dae65d3eef0ae977152">Yahoo! Pipes</a>).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/blog/brand-new-blog/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Enhanced hCalendar download links</title>
		<link>http://blog.georgebrock.com/projects/enhanced-hcalendar-downloads</link>
		<comments>http://blog.georgebrock.com/projects/enhanced-hcalendar-downloads#comments</comments>
		<pubDate>Fri, 21 Nov 2008 13:00:44 +0000</pubDate>
		<dc:creator>George Brocklehurst</dc:creator>
				<category><![CDATA[projects]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[hcalendar]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[microformats]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[sumo]]></category>

		<guid isPermaLink="false">http://blog.georgebrock.com/?p=20</guid>
		<description><![CDATA[Introduction
A script that automatically transforms links to Technorati&#8217;s events service into a useful little menu allowing events to be downloaded or added to various online calendar services. If you want to see it action check out this live demo.
It&#8217;s a bit rough around the edges (there&#8217;s a list of issues below). It uses Dan Webb&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<h3>Introduction</h3>
<p>A script that automatically transforms links to <a href="http://technorati.com/events">Technorati&#8217;s events service</a> into a useful little menu allowing events to be downloaded or added to various online calendar services. If you want to see it action check out this <a href="http://blog.georgebrock.com/supporting/enhanced-hcalendar-download-links/demo.html">live demo</a>.</p>
<p>It&#8217;s a bit rough around the edges (there&#8217;s a <a href="#ehcdl-notes">list of issues</a> below). It uses <span class="vcard"><span class="fn">Dan Webb</span>&#8217;s <a class="url" href="http://www.danwebb.net/2007/2/9/sumo-a-generic-microformats-parser-for-javascript">Sumo microformats parser</a></span> to extract event details (some online calendar services don&#8217;t support iCalendar import, so the details need to be passed directly) and <a href="http://jquery.com/">JQuery</a> to manipulate the page.</p>
<h3>Files</h3>
<p>The latest version of the script is kept in a <a href="http://github.com/georgebrock/enhanced-hcalendar-downloads/">public repository on GitHub</a></p>
<h3>How to use</h3>
<ol>
<li>Mark up your events using <a href="http://microformats.org/wiki/hcalendar">hCalendar</a></li>
<li>Add a link to Technorati&#8217;s events parsing service. For example, the link for this page would be <a href="http://technorati.com/events/http://blog.georgebrock.com/projects/enhanced-hcalendar-downloads">http://technorati.com/events/http://blog.georgebrock.com/projects/enhanced-hcalendar-downloads</a></li>
<li>Add all the relevant Javascript files to your page (Sumo&#8217;s <a type="text/javascript" href="http://svn.danwebb.net/external/microformat/microformat.js">microformat.js</a> and <a type="text/javascript" href="http://svn.danwebb.net/external/microformat/hcalendar.js">hcalendar.js</a>, <a href="http://docs.jquery.com/Downloading_jQuery">JQuery</a> and <a type="text/javascript" href="http://github.com/georgebrock/enhanced-hcalendar-downloads/tree/master/enhanced-hcalendar-downloads.js">enhanced-hcalendar-downloads.js</a>)</li>
<li>That&#8217;s all you need to do, but you might want to add some <abbr title="Cascading Style Sheets">CSS</abbr> rules to make the menu prettier (start here: <a type="text/css" href="http://github.com/georgebrock/enhanced-hcalendar-downloads/tree/master/enhanced-hcalendar-downloads.css">enhanced-hcalendar-downloads.css</a>)</li>
</ol>
<div id="ehcdl-notes">
<h3>Issues</h3>
<ul>
<li>The current version only supports <var>duration</var> in the format <code>PT<var>minutes</var>M</code>. If a <var>dtend</var> is provided it will be used in preference to <var>duration</var>.</li>
<li>Sumo and Technorati both have some quirks about which variations of the ISO 8601 date format they support.</li>
<li>If you include a fragment in the URL you pass to Technorati, the script will use the first event found in that container to generate the Google and Yahoo! calendar links.  Unfortunately the Technorati service will ignore the fragment and parse all the hCalendar instances on the page, I&#8217;ve asked them if this can be changed.</li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.georgebrock.com/projects/enhanced-hcalendar-downloads/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
