<?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 MacKerron: code blog &#187; Web design</title>
	<atom:link href="http://blog.mackerron.com/category/web-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mackerron.com</link>
	<description>GIS, software development, and other snippets</description>
	<lastBuildDate>Mon, 09 Aug 2010 08:29:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Signing Amazon Product Advertising API calls in Ruby</title>
		<link>http://blog.mackerron.com/2009/08/sign-aws-api-in-ruby/</link>
		<comments>http://blog.mackerron.com/2009/08/sign-aws-api-in-ruby/#comments</comments>
		<pubDate>Sat, 22 Aug 2009 11:04:23 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=182</guid>
		<description><![CDATA[I have a simple site that generates covers for CDs I burn from iTunes purchases and so on (it pre-dates widespread use of JS libraries, and is in much need of prettifying). The site uses Amazon Product Advertising API calls to search and retrieve album cover art and track listings. Since earlier this month, such [...]]]></description>
			<content:encoded><![CDATA[<p>I have <a href="http://mackerron.com/cdcovers/">a simple site</a> that generates covers for CDs I burn from iTunes purchases and so on (it pre-dates widespread use of JS libraries, and is in much need of prettifying). The site uses <a href="https://affiliate-program.amazon.com/gp/advertising/api/detail/main.html">Amazon Product Advertising <span class="caps">API</span></a> calls to search and retrieve album cover art and track listings. Since earlier this month, such <span class="caps">API </span>calls have to be cryptographically signed.</p>

<p>This is somewhat annoying &#8212; the site&#8217;s original design has it communicating independently with Amazon (using Amazon&#8217;s <span class="caps">XSLT API </span>feature to transform their <span class="caps">XML </span>data into <span class="caps">JSON</span>), and that&#8217;s no longer possible with the use of a private key. But it&#8217;s not unfixable. The site now sends its <span class="caps">API </span>call first to my server, which returns a signed version, and then forwards the signed call on to Amazon.</p>

<p>I found most of what I needed for this on <a href="http://chrisroos.co.uk/blog/2009-01-31-implementing-version-2-of-the-amazon-aws-http-request-signature-in-ruby">Chris Roos&#8217; blog</a>, but his version still wasn&#8217;t quite working for me (the two problems I recall are that Ruby&#8217;s <span class="caps">CGI.</span>escape doesn&#8217;t quite follow Amazon&#8217;s requirements, and that times need converting to <span class="caps">GMT</span>).</p>

<p><span id="more-182"></span></p>

<p>Anyway, in case you&#8217;re looking to do the same, here&#8217;s what I ended up with:</p>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Note: You need hmac.rb and hmac-sha2.rb from http://deisui.org/~ueno/ruby/hmac.html </span>
<span style="color:#008000; font-style:italic;"># somewhere in your require paths. ruby-hmac is currently broken under Ruby 1.9.</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>rubygems cgi time hmac<span style="color:#006600; font-weight:bold;">-</span>sha2 base64<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>lib<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC0066; font-weight:bold;">require</span> lib <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
ACCESS_IDENTIFIER = <span style="color:#996600;">'YOUR_PUBLIC_ID'</span>
SECRET_IDENTIFIER = <span style="color:#996600;">'YOUR_PRIVATE_ID'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>s<span style="color:#006600; font-weight:bold;">&#41;</span>
  s.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#91;</span>^A<span style="color:#006600; font-weight:bold;">-</span>Za<span style="color:#006600; font-weight:bold;">-</span>z0<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">9</span>_.~<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">'%'</span> <span style="color:#006600; font-weight:bold;">+</span> c<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">16</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">upcase</span> <span style="color:#006600; font-weight:bold;">&#125;</span>  
  <span style="color:#008000; font-style:italic;"># for 1.9, you'd replace [0] with .ord -- but ruby-hmac seems broken under 1.9</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
cgi = <span style="color:#CC00FF; font-weight:bold;">CGI</span>.<span style="color:#9900CC;">new</span>
params = cgi.<span style="color:#9900CC;">params</span>.<span style="color:#9900CC;">dup</span>
&nbsp;
amazon_endpoint = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'amazon_endpoint'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
amazon_path = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'amazon_path'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
js_callback = params.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'js_callback'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
signing_params = <span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#996600;">'AWSAccessKeyId'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ACCESS_IDENTIFIER,
  <span style="color:#996600;">'Timestamp'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>.<span style="color:#9900CC;">gmtime</span>.<span style="color:#9900CC;">iso8601</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
params.<span style="color:#9900CC;">merge</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>signing_params<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
canonical_querystring = params.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> 
  <span style="color:#006600; font-weight:bold;">&#91;</span>aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>key.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>, aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'='</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
<span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&amp;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
string_to_sign = <span style="color:#996600;">&quot;GET<span style="color:#000099;">\n</span>#{amazon_endpoint}<span style="color:#000099;">\n</span>#{amazon_path}<span style="color:#000099;">\n</span>#{canonical_querystring}&quot;</span>
&nbsp;
hmac = <span style="color:#6666ff; font-weight:bold;">HMAC::SHA256</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>SECRET_IDENTIFIER<span style="color:#006600; font-weight:bold;">&#41;</span>
hmac.<span style="color:#9900CC;">update</span><span style="color:#006600; font-weight:bold;">&#40;</span>string_to_sign<span style="color:#006600; font-weight:bold;">&#41;</span>
signature = <span style="color:#CC00FF; font-weight:bold;">Base64</span>.<span style="color:#9900CC;">encode64</span><span style="color:#006600; font-weight:bold;">&#40;</span>hmac.<span style="color:#9900CC;">digest</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span>
&nbsp;
params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Signature'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = signature
querystring = params.<span style="color:#9900CC;">sort</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>key, value<span style="color:#006600; font-weight:bold;">|</span> 
  <span style="color:#006600; font-weight:bold;">&#91;</span>aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>key.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span>, aws_escape<span style="color:#006600; font-weight:bold;">&#40;</span>value.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'='</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
<span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&amp;'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
signed_url = <span style="color:#996600;">&quot;http://#{amazon_endpoint}#{amazon_path}?#{querystring}&quot;</span>
&nbsp;
cgi.<span style="color:#9900CC;">out</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'type'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'text/javascript'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">&quot;#{js_callback}('#{signed_url}');&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>




<p>You can test this locally by feeding key/value parameters to <span class="caps">CGI, </span>followed by Ctrl-D. These, for example:</p>



<pre>amazon_endpoint=ecs.amazonaws.com
amazon_path=/onca/xml
js_callback=do_stuff
Service=AWSECommerceService
Version=2009-03-31
Operation=ItemSearch
SearchIndex=Books
Keywords=george+monbiot</pre>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/08/sign-aws-api-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Free Adobe fonts</title>
		<link>http://blog.mackerron.com/2009/05/free-adobe-fonts/</link>
		<comments>http://blog.mackerron.com/2009/05/free-adobe-fonts/#comments</comments>
		<pubDate>Thu, 28 May 2009 12:17:47 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=25</guid>
		<description><![CDATA[Quick tip: you can get hold of some of Adobe&#8217;s very nice professional fonts for free when you download the InDesign CS4 trial (and possibly other CS4 apps too). These include: Caslon Pro Chaparral Pro Garamond Pro Minion Pro Myriad Pro If you don&#8217;t want to actually install InDesign, you can get to the fonts [...]]]></description>
			<content:encoded><![CDATA[<p>Quick tip: you can get hold of some of Adobe&#8217;s very nice professional fonts for free when you download the InDesign <span class="caps">CS4 </span>trial (and possibly other <span class="caps">CS4 </span>apps too).</p>

<p>These include:</p>


<ul>
<li>Caslon Pro</li>
<li>Chaparral Pro</li>
<li>Garamond Pro</li>
<li>Minion Pro</li>
<li>Myriad Pro</li>
</ul>



<p>If you don&#8217;t want to actually install InDesign, you can get to the fonts like so (if you&#8217;re a Mac user):</p>


<ul>
<li>Mount (double-click) the downloaded disk image</li>
<li>Mount another disk image found on the newly mounted disk, at Adobe InDesign <span class="caps">CS4</span>/payloads/AdobeFontsAll/AdobeFontsAll.dmg</li>
<li>The fonts are inside /Assets/contents on this second disk</li>
</ul>



<p><strong>Note that these fonts may well be covered by a very restrictive licence: I haven&#8217;t checked.</strong></p>]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/05/free-adobe-fonts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing in Internet Explorer for VMWare Fusion users</title>
		<link>http://blog.mackerron.com/2009/05/testing-in-ie-for-fusion-users/</link>
		<comments>http://blog.mackerron.com/2009/05/testing-in-ie-for-fusion-users/#comments</comments>
		<pubDate>Thu, 28 May 2009 09:25:43 +0000</pubDate>
		<dc:creator>George</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[Web design]]></category>

		<guid isPermaLink="false">http://blog.mackerron.com/?p=39</guid>
		<description><![CDATA[You might have noticed that Microsoft has lately started making available time-limited Virtual PC images of Windows installations with (separately) Internet Explorer versions 6, 7 and 8. This is brilliant for Mac users who need to test websites in IE, because you get a real installation of each browser in its home environment, with the [...]]]></description>
			<content:encoded><![CDATA[<p>You might have noticed that Microsoft has lately started making available time-limited Virtual PC images of Windows installations with (separately) Internet Explorer versions 6, 7 and 8. </p>

<p>This is brilliant for Mac users who need to test websites in <span class="caps">IE, </span>because you get a real installation of each browser in its home environment, with the right JavaScript engine and working conditional comments, plug-ins, Windows Media Player, and so on. With the alternatives, such as running under Wine or using <a href="http://tredosoft.com/Multiple_IE">Multiple IEs</a> in a single Windows virtual machine, one or more of these things tends to be missing.</p>

<p><span id="more-39"></span></p>

<p>Unfortunately, the images are supplied as self-extracting .exe files, which of course are Windows programs. But happily, the Mac ports of Wine, the open-source Windows emulation software, can run them.</p>


<ul>
<li>Get hold of <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;displaylang=en">the self-extracting archives from Microsoft</a>. I find XP+IE6 and XP+IE8 a useful combination.</li>
<li>Install <a href="http://www.kronenberg.org/darwine/">Darwine</a>.</li>
<li>Open /Applications/Darwine/WineHelper, choose File &gt; Open&#8230; and pick one of the .exe files you downloaded in the last step.</li>
<li>Ignore any Darwine messages about needing to install Mozilla, and click Next/Agree/etc. as necessary in the installer to extract the .vhd file. (I understand the free <a href="http://www.virtualbox.org/">VirtualBox</a> will take such a .vhd directly, but I&#8217;ve not tried this myself).</li>
<li>Download <a href="http://www.kju-app.org/">Q</a>. This is a largely useless program for Intel Mac users, since its purpose is to emulate the <span class="caps">CPU </span>you already have. But bear with me: it includes a very handy utility.</li>
<li>Open /Applications/Utilities/Terminal, and paste in the following command, substituting in the correct path to your .vhd file and a path of your choice for the .vmdk file it will be converted to:</li>
</ul>




<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Q.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<span style="color: #000000; font-weight: bold;">/</span>qemu-img convert \
  <span style="color: #660033;">-f</span> vpc <span style="color: #660033;">-O</span> vmdk path_to_old.vhd path_to_new.vmdk</pre></div></div>





<ul>
<li>Nothing will appear to be happening for a few minutes, but don&#8217;t worry. Wait for the prompt to reappear.</li>
<li>Create a new Virtual Machine in Fusion, based on the new .vmdk you just created. Agree to Fusion&#8217;s request to convert the format of the disk.</li>
<li>Before starting up the new machine, remove its <span class="caps">USB </span>controller, sound card and serial port, and disable 3D graphics (this is all optional, but it reduces the number of requests for drivers you&#8217;ll have to deny later).</li>
<li>Start the virtual machine, canceling any requests for driver disks or Windows Update attempts.</li>
<li>Install <span class="caps">VMW</span>are Tools. I find everything works except the mouse, so at this point I choose the custom installation and deselect the mouse driver.</li>
<li>Reboot and you&#8217;re done.</li>
<li>Don&#8217;t forget to move the original .exe and .vhd files to the Trash: they&#8217;re big and completely useless now.</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.mackerron.com/2009/05/testing-in-ie-for-fusion-users/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
