<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CE4MSHw_fCp7ImA9WxBWE0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953</id><updated>2010-02-05T09:43:09.244Z</updated><title>codesimple</title><subtitle type="html">Simple solutions to complex problems</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.codesimple.net/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>26</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><feedburner:info uri="codesimple" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>52.47</geo:lat><geo:long>-0.92</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://codesimple.net/feed/" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry gd:etag="W/&quot;A0YAQns_cCp7ImA9WxNQFk4.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-5767574622033830691</id><published>2009-09-22T17:51:00.003+01:00</published><updated>2009-09-22T18:05:43.548+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T18:05:43.548+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cappuccino" /><category scheme="http://www.blogger.com/atom/ns#" term="that big shop" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><title>That Big Shop</title><content type="html">&lt;div style="float: left"&gt;&lt;a href="http://www.thatbigshop.com/"&gt;&lt;img src="http://4.bp.blogspot.com/_1r8HCRxu89A/Srj87QpAkyI/AAAAAAAAADc/eFsfRn3Rc6I/s320/logo_100.png" style="padding: 0; border: 0px none;" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I've always found shopping at Amazon a bit of a cumbersome experience. The pages seem a little cluttered and when choosing between products there's lots of back-and-forth as you switch between search results and product detail.&lt;br /&gt;&lt;br /&gt;So I thought I'd make use of the Amazon Product Advertising API and write my own interface. The result is &lt;a href="http://www.thatbigshop.com/"&gt;That Big Shop&lt;/a&gt;. It's not old browser or search engine friendly but it does, I think, have a more responsive feel to it than the standard Amazon interface.&lt;br /&gt;&lt;br /&gt;To create the site, I choose to use the &lt;a href="http://cappuccino.org/"&gt;Cappuccino&lt;/a&gt; framework and I'm glad I did. The painful part of writing web applications is getting them to look and work the same across browsers. With Cappuccino I didn't need to worry about that; as long as I coded to the framework API, Cappuccino would take care of rendering what I wanted consistently across browsers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-5767574622033830691?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/5767574622033830691/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5767574622033830691" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5767574622033830691?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5767574622033830691?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2009/09/that-big-shop.html" title="That Big Shop" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_1r8HCRxu89A/Srj87QpAkyI/AAAAAAAAADc/eFsfRn3Rc6I/s72-c/logo_100.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUcASXg9eip7ImA9WxdbFUk.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-5875410658978849850</id><published>2008-08-12T12:36:00.001+01:00</published><updated>2008-08-12T13:10:48.662+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-08-12T13:10:48.662+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="qr code" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><title>QR codes for cogteeth.com</title><content type="html">&lt;a href="http://cogteeth.com"&gt;&lt;img src="http://3.bp.blogspot.com/_1r8HCRxu89A/SKF5vNP_x6I/AAAAAAAAADU/dz2Lbt3sOJA/s320-R/chart.png" style="border: 0pt none ; float: left;" /&gt;&lt;/a&gt;&lt;br /&gt;With a little help from the &lt;a href="http://code.google.com/apis/chart/"&gt;Google Chart API&lt;/a&gt;, I've added the ability to create &lt;a href="http://en.wikipedia.org/wiki/QR_Code"&gt;QR code&lt;/a&gt; t-shirt, mugs and cards over at &lt;a href="http://cogteeth.com/"&gt;cogteeth.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;QR codes are quite nifty little two-dimensional barcodes which can store a surpising amount of data in a small space. There are numerous readers available to decode them including mobile phone apps which enable you to decode them using your phone camera.&lt;br /&gt;&lt;br /&gt;Any data can be stored in these codes but there are a number of standards or conventions recognised by the readers. For example, many will detect an encoded URL and automatically pull up the referenced web page. The &lt;a href="http://code.google.com/p/zxing/wiki/BarcodeContents"&gt;documentation&lt;/a&gt; for the zxing reader gives a good summary of these conventions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-5875410658978849850?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/5875410658978849850/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5875410658978849850" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5875410658978849850?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5875410658978849850?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2008/08/qr-codes-for-cogteethcom.html" title="QR codes for cogteeth.com" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_1r8HCRxu89A/SKF5vNP_x6I/AAAAAAAAADU/dz2Lbt3sOJA/s72-Rc/chart.png" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;AkYBRHs4eSp7ImA9WxZbEko.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-5739631995324729797</id><published>2008-04-15T17:12:00.003+01:00</published><updated>2008-04-15T17:49:15.531+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-15T17:49:15.531+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="app engine" /><category scheme="http://www.blogger.com/atom/ns#" term="django" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Google App Engine</title><content type="html">It took less than two hours to convert &lt;a href="http://cogteeth.com/"&gt;cogteeth.com&lt;/a&gt; to run with the &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. Admittedly this is a pretty simple example since cogteeth doesn't use a database and Django is supplied with the App Engine environment.&lt;br /&gt;&lt;br /&gt;All that was necessary was:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a &lt;code&gt;main.py&lt;/code&gt;: Since the app is Django based this was just a modified copy of the version on &lt;a href="http://code.google.com/appengine/articles/django.html"&gt;this page&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Create an &lt;code&gt;app.yaml&lt;/code&gt; to pass all URLs onto &lt;code&gt;main.py&lt;/code&gt; and serve the static files directly.&lt;/li&gt;&lt;li&gt;Modify some URL fetching code that previously used &lt;code&gt;urllib2&lt;/code&gt; to use &lt;code&gt;urlfetch&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;When I say it's running with the App Engine that's not strictly true. It runs locally with the SDK, now I just have to hope they work through the wait list quickly and send me an invite...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-5739631995324729797?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/5739631995324729797/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5739631995324729797" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5739631995324729797?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5739631995324729797?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2008/04/google-app-engine.html" title="Google App Engine" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0MASXsyeip7ImA9WB9REU8.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-8489092292891747163</id><published>2007-10-11T17:34:00.000+01:00</published><updated>2007-10-11T17:50:48.592+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-11T17:50:48.592+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="google apps" /><title>Blogger custom domains</title><content type="html">This blog is currently hosted at http://www.codesimple.net. This is a pity since the more succinct http://codesimple.net would be preferable. Unfortunately if I try and set the custom domain in Blogger to just "codesimple.net" it complains with a somewhat dubious "Another blog is already hosted at this address" message.&lt;br /&gt;&lt;br /&gt;I think perhaps this is related to also having Google Apps active on this domain. Both services  require you to point your DNS at ghs.google.com.&lt;br /&gt;&lt;br /&gt;Also slightly odd is that Google do an HTTP redirect for any requests to http://codesimple.net to http://www.codesimple.net. I can't find any setting in Google Apps to control this "feature".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-8489092292891747163?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/8489092292891747163/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=8489092292891747163" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8489092292891747163?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8489092292891747163?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2007/10/blogger-custom-domains.html" title="Blogger custom domains" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;A0ACRXczfip7ImA9WB9UGUo.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-5433798081074846960</id><published>2007-10-11T16:25:00.000+01:00</published><updated>2007-12-18T12:09:24.986Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-18T12:09:24.986Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wordpress" /><category scheme="http://www.blogger.com/atom/ns#" term="blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="gdata" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>WordPress to Blogger</title><content type="html">I recently decided to switch my blog from Wordpress to Blogger. Not because I think Blogger is better but because I wanted to avoid maintaining my own instance of Wordpress and Blogger would host my blog on my domain for free.&lt;br /&gt;&lt;br /&gt;To copy the posts across I wrote a small Python script which takes a file of exported Wordpress posts and uses the &lt;a href="http://code.google.com/apis/blogger/overview.html"&gt;Blogger Data API&lt;/a&gt; to upload them to Blogger.&lt;br /&gt;&lt;br /&gt;If you want to do this yourself, you will need to:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download the script &lt;a href="http://www.codesimple.net-a.googlepages.com/wptoblogger.py"&gt;wptoblogger.py&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;Ensure you have &lt;a href="http://python.org/"&gt;Python 2.5&lt;/a&gt;, &lt;a href="http://www.crummy.com/software/BeautifulSoup/"&gt;BeautifulSoup&lt;/a&gt; and &lt;a href="http://code.google.com/p/gdata-python-client/"&gt;Google's GData Python Client&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;Create your target Blogger blog and note its ID.&lt;/li&gt;  &lt;li&gt;Export your Wordpress blog to an XML file (I think this is only available in version 2 and above of Wordpress).&lt;/li&gt;&lt;li&gt;Run &lt;span style="font-style: italic;"&gt;wptoblogger&lt;/span&gt;:&lt;blockquote&gt;&lt;/blockquote&gt;python wptoblogger.py -u your_blogger_username -b your_blog_id -a author_for_posts wordpress_xml_file&lt;/li&gt;&lt;/ol&gt;There are a few limitations though...&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It doesn't support multiple blog authors - all posts will be marked with the &lt;span style="font-style: italic;"&gt;author_for_posts&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;A limitation with the Blogger API means that comment authors can't be set (they always appear as the blog author). As a workaround, I prefix each comment with a "Comment from..." line (see the existing comments on this blog).&lt;/li&gt;&lt;li&gt;Blogger impose a limit on the number of posts you can create via the API in a certain time period. So if you have a lot of posts to transfer you may need to modify the script to post them in batches over a number of days.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-5433798081074846960?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/5433798081074846960/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5433798081074846960" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5433798081074846960?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5433798081074846960?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2007/10/wordpress-to-blogger.html" title="WordPress to Blogger" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total></entry><entry gd:etag="W/&quot;D0UGRHwzeip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-8109416419120593027</id><published>2007-06-21T11:39:00.004+01:00</published><updated>2007-10-07T14:53:45.282+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:45.282+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="erlang" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Join and split</title><content type="html">It always amazes me when I try out a new programming language and find that the standard library doesn't include &lt;em&gt;join&lt;/em&gt; and &lt;em&gt;split&lt;/em&gt; functions. &lt;em&gt;join&lt;/em&gt; is used to combine a list of strings into a single string with each item separated by a delimiter. &lt;em&gt;split&lt;/em&gt; takes a delimited string and divides it into sub-strings.  &lt;em&gt;Python&lt;/em&gt;, thankfully, does provide these functions:&lt;br /&gt;&lt;blockquote&gt;&gt;&gt;&gt; ':'.join(['a','b','c'])&lt;br /&gt;'a:b:c'&lt;br /&gt;&gt;&gt;&gt; 'a:b:c'.split(':')&lt;br /&gt;['a', 'b', 'c']&lt;/blockquote&gt;&lt;br /&gt;Erlang provides regexp:split but it looks like I have to add my own &lt;em&gt;join&lt;/em&gt; function. Not sure this is the most efficient implementation but it will do the job:&lt;br /&gt;&lt;blockquote&gt;intersperse(_, []) -&gt; [];&lt;br /&gt;intersperse(Element, List) -&gt;&lt;br /&gt;tl(lists:reverse(lists:foldl(fun(X, A) -&gt; [X,Element|A] end, [], List))).&lt;br /&gt;&lt;br /&gt;join(List, ListOfLists) -&gt; lists:append(intersperse(List, ListOfLists)).&lt;/blockquote&gt;&lt;br /&gt;&lt;blockquote&gt;&gt; intersperse(":", ["a","b","c"]).&lt;br /&gt;["a",":","b",":","c"]&lt;br /&gt;&gt; join(":", ["a","b","c"]).&lt;br /&gt;"a:b:c"&lt;/blockquote&gt;&lt;br /&gt;And since strings in Erlang are just lists of integers this can be applied to other lists as well.&lt;br /&gt;&lt;blockquote  /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-8109416419120593027?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/8109416419120593027/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=8109416419120593027" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8109416419120593027?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8109416419120593027?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2007/06/join-and-split_5767.html" title="Join and split" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total></entry><entry gd:etag="W/&quot;D0UGRXs8fyp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-8503757987473119977</id><published>2006-11-16T18:54:00.004Z</published><updated>2007-10-07T14:53:44.577+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:44.577+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flickr" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><title>Flickr bookmarklet</title><content type="html">I've just added Flickr support to the &lt;a href="http://cogteeth.com/bookmarklet/"&gt;Cogteeth Bookmarklet&lt;/a&gt;. Obviously it worked with Flickr before (since it works with most web pages) but now it will automatically detect Flickr images and provide the following additional features:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;	&lt;li&gt;It will retrieve the largest available version of the selected image from Flickr to ensure the best quality product is produced.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Make the image clickable so that the user can easily go to the Flickr photo page.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Provide links to any other available sizes of the image.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Show the license that the image poster has attached to it.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-8503757987473119977?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/8503757987473119977/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=8503757987473119977" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8503757987473119977?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/8503757987473119977?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/11/flickr-bookmarklet_8444.html" title="Flickr bookmarklet" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UGQnc_fyp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-4054740461544771456</id><published>2006-10-17T13:15:00.005+01:00</published><updated>2007-10-07T14:53:43.947+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:43.947+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="zazzle" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Create products from worldinpictures.org</title><content type="html">Integration of &lt;a href="http://cogteeth.com"&gt;Cogteeth.com&lt;/a&gt; and &lt;a href="http://worldinpictures.org/"&gt;worldinpictures.org&lt;/a&gt; now means that you can create &lt;a href="http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home"&gt;Zazzle&lt;/a&gt; products from any images you see on worldinpictures.org. Just click the "Make product..." links.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-4054740461544771456?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/4054740461544771456/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=4054740461544771456" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4054740461544771456?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4054740461544771456?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/10/create-products-from-worldinpicturesorg_979.html" title="Create products from worldinpictures.org" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UGQn88fCp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-5905225554460225256</id><published>2006-10-17T09:54:00.005+01:00</published><updated>2007-10-07T14:53:43.174+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:43.174+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="zazzle" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><title>Cogteeth Bookmarklet</title><content type="html">Just added a new feature at &lt;a href="http://cogteeth.com/"&gt;Cogteeth&lt;/a&gt;: the Cogteeth Bookmarklet.  Once installed, this allows you to create a &lt;a href="http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home"&gt;Zazzle&lt;/a&gt; product from any image on the web.&lt;br /&gt;&lt;br /&gt;Probably half the development time on this was spent getting it to work with Internet Explorer. In the end I had to produce a slightly different version specifically for IE which may not look so pretty when used on some sites. But of course there's an easy solution to this - switch to a decent browser.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-5905225554460225256?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/5905225554460225256/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5905225554460225256" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5905225554460225256?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/5905225554460225256?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/10/cogteeth-bookmarklet_8339.html" title="Cogteeth Bookmarklet" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UGQ3g6cSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-7803110097709028161</id><published>2006-10-10T17:37:00.005+01:00</published><updated>2007-10-07T14:53:42.619+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:42.619+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><title>Cogteeth decoder added</title><content type="html">I've added a message decoder to &lt;a href="http://cogteeth.com"&gt;Cogteeth.com&lt;/a&gt; so if you don't want to buy a t-shirt you can use it as a general UTF-8 coder/decoder!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-7803110097709028161?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/7803110097709028161/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=7803110097709028161" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7803110097709028161?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7803110097709028161?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/10/cogteeth-decoder-added_3195.html" title="Cogteeth decoder added" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UGQHs-fCp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-35596466998919601</id><published>2006-10-06T11:09:00.005+01:00</published><updated>2007-10-07T14:53:41.554+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:41.554+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="zazzle" /><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth" /><title>Cogteeth.com - personalized T-Shirts</title><content type="html">Partly as an experiment with the new &lt;a title="Zazzle home page" href="http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home"&gt;Zazzle&lt;/a&gt; API, I've created a new site &lt;a title="Cogteeth.com" href="http://cogteeth.com"&gt;Cogteeth.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;At Cogteeth you can create customized T-Shirts by entering messages for the back and front of the shirt. The text of the messages is converted to UTF-8  and the resulting codes displayed in hex. The result is a T-Shirt with a coded mesage that only those with too much time on their hands can read.&lt;br /&gt;&lt;br /&gt;Here's what I've learnt from this exercise:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;	&lt;li&gt;Passing an empty field to http://www.zazzle.com/api/create is the same as not including it in the request (i.e. the text in the template will be used). So If you want to leave a text field blank, you must pass in a SPACE (e.g.  http://www.zazzle.com/api/create?frontText=%20&amp;blah=...).&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;The Zazzle API does not yet support non-ASCII characters. Passing a UTF-8 encoded character sequence (e.g.  http://www.zazzle.com/api/create?frontText=%C2%B7) will NOT result in the UTF-8 C2:B7 character. Zazzle say this may be supported in future.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Javascript uses UTF-16 strings, so if you want to use Javascript to convert form field values to UTF-8 (and ensure Unicode characters above 0x10000 are handled correctly) you must first decode from UTF-16. Javascript appears to have no built in support for this kind of thing so I ended up writing &lt;a title="Javascript source code" href="http://cogteeth.com/res/mpsupport.js"&gt;my own functions&lt;/a&gt; to decode from UTF-16 and encode to UTF-8.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Although the HTML 4 spec suggests that only ASCII values can be used in HTTP GET form submissions, most browsers will sensibly encode non-ASCII characters in UTF-8 and then URL encode them before submission. (This assumes the page containing the form was sent as UTF-8 encoded).&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Why isn't there an "onFieldValueChange" event for form fields?  I currently use the "keyup" event but I'm not interested whether the change was due to a keystroke, I just want to know if a change occured. The onChange event is no use here - it only fires when the field loses focus.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;blockquote&gt;54:68:61:6E:6B:73&lt;br /&gt;20:66:6F:72:20:72&lt;br /&gt;65:61:64:69:6E:67&lt;br /&gt;2C:20:6E:6F:77:20&lt;br /&gt;67:6F:20:62:75:79&lt;br /&gt;20:61:20:54:2D:53&lt;br /&gt;68:69:72:74:21:00&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-35596466998919601?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/35596466998919601/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=35596466998919601" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/35596466998919601?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/35596466998919601?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/10/cogteethcom-personalized-t-shirts_1345.html" title="Cogteeth.com - personalized T-Shirts" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;D0UGQX09fip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-4749493794984343693</id><published>2006-09-26T09:32:00.005+01:00</published><updated>2007-10-07T14:53:40.366+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:40.366+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="geocoding" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>UK place name support for worldinpictures.org</title><content type="html">Thanks to the excellent &lt;a href="http://www.geonames.org/export/"&gt;Geo-Names webservices&lt;/a&gt; you can now enter UK place names at &lt;a href="http://worldinpictures.org/"&gt;worldinpictures.org&lt;/a&gt; to see photos from that location.&lt;br /&gt;&lt;br /&gt;Previously I'd been relying on the Google geocoder which doesn't (yet) support the UK or a number of other countries, so photos from unsuppoted countries could only be viewed by entering a latitude/longitude (or post code for the UK). Now Geo-Names fills in the gaps so many more locations are supported.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-4749493794984343693?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/4749493794984343693/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=4749493794984343693" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4749493794984343693?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4749493794984343693?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/09/uk-place-name-support-for_4169.html" title="UK place name support for worldinpictures.org" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFSHkyeip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-7703182214110026614</id><published>2006-09-08T15:54:00.005+01:00</published><updated>2007-10-07T14:53:39.792+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:39.792+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="geocoding" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Geocoded YouTube videos</title><content type="html">I had a look at adding videos to &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; this morning. &lt;a href="http://www.youtube.com"&gt;YouTube&lt;/a&gt; looked like a good source for these and offers a limited API to get hold of them.&lt;br /&gt;&lt;br /&gt;Unfortunately the grand total of &lt;em&gt;geotagged&lt;/em&gt; videos at present on YouTube is... 38. Admitedly it wouldn't make a lot of sense to geocode many of the videos on there, but I thought there might be a few more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-7703182214110026614?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/7703182214110026614/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=7703182214110026614" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7703182214110026614?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7703182214110026614?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/09/geocoded-youtube-videos_1842.html" title="Geocoded YouTube videos" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;D0UFSH8_fip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-7032792970304233203</id><published>2006-09-07T18:48:00.005+01:00</published><updated>2007-10-07T14:53:39.146+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:39.146+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="flickr" /><category scheme="http://www.blogger.com/atom/ns#" term="geocoding" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Retrieving officially geocoded flickr photos</title><content type="html">I've been updating &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; to use the new flickr geocoding API. Unfortunately it doesn't provide a "find all photos near to a point ordered by distance" function, so I still need to keep a database of photo locations.&lt;br /&gt;&lt;br /&gt;To keep my database up-to-date, I now to need to find the latest photos that have been "officially" geocoded, as well as those using the old unofficial &lt;em&gt;geo:lon/geo:lat&lt;/em&gt; tags.&lt;br /&gt;&lt;br /&gt;Turns out you can retrieve just the flickr photos that have been "officially" geocoded by setting the &lt;em&gt;bbox&lt;/em&gt; parameter to cover the whole globe:&lt;br /&gt;&lt;blockquote&gt;flickr.photos.search(bbox=-180,-90,180,90)&lt;/blockquote&gt;&lt;br /&gt;This is different to leaving out the &lt;em&gt;bbox&lt;/em&gt; parameter (which would return all photos). Instead it essentially applies a filter which returns only those photos with official geocode information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-7032792970304233203?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/7032792970304233203/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=7032792970304233203" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7032792970304233203?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/7032792970304233203?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/09/retrieving-officially-geocoded-flickr_383.html" title="Retrieving officially geocoded flickr photos" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFSXo7eCp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-551606810026774437</id><published>2006-09-06T10:27:00.005+01:00</published><updated>2007-10-07T14:53:38.400+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:38.400+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Firefox trounces IE</title><content type="html">&lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; made it on to the front page of &lt;a href="http://digg.com"&gt;digg&lt;/a&gt; yesterday and as a result got rather popular. My poor server was stuggling in the morning so I invested in an extra 128Mb. The nice guys at &lt;a href="http://www.memset.com?source=porteab"&gt;memset&lt;/a&gt; got this upgraded promptly and it survived the rest of the day admirably.&lt;br /&gt;&lt;br /&gt;Looking at the stats, it's interesting to see which browsers visitors were using:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;	&lt;li&gt;Firefox: 66%&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Internet Explorer: 21%&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Safari: 9%&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Opera: 2%&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;This is probably not representative of general users since &lt;em&gt;digg&lt;/em&gt; visitors are probably more technically savvy than most but encouraging nevertheless.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-551606810026774437?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/551606810026774437/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=551606810026774437" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/551606810026774437?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/551606810026774437?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/09/firefox-trounces-ie_4859.html" title="Firefox trounces IE" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFRnY4fip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-1632905230678803645</id><published>2006-09-04T11:06:00.005+01:00</published><updated>2007-10-07T14:53:37.836+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:37.836+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><category scheme="http://www.blogger.com/atom/ns#" term="google maps" /><title>Google maps tabbed windows</title><content type="html">For the new map view at &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt;, I needed to support the situation where the search results contain several images taken at the same point. The obvious soltuion was to take advantage of the tabbed info windows provided by Google Maps ("info windows" are the pop-ups that display when you click on a map marker).&lt;br /&gt;&lt;br /&gt;Unfortunately the tabs are quite wide so if you want a lot of tabs (and I could need 12) you need to have a very wide info window. So I had to implement my own "tabbing" system using simple numbered links. This seems to work well though and keeps the window to a reasonable size.&lt;br /&gt;&lt;br /&gt;Now I need to change the title that appears when you hover over a marker to indicate the number of photos at that point. That can wait for another day though...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-1632905230678803645?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/1632905230678803645/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=1632905230678803645" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/1632905230678803645?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/1632905230678803645?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/09/google-maps-tabbed-windows_3420.html" title="Google maps tabbed windows" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFRn4yfSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-3190254499120041719</id><published>2006-08-30T17:01:00.005+01:00</published><updated>2007-10-07T14:53:37.095+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:37.095+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><category scheme="http://www.blogger.com/atom/ns#" term="google maps" /><title>Maps added to worldinpictures.org</title><content type="html">I've just added a "map view" to &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt;. There's now a couple of links below the search results to switch between "gallery view" and "map view". Select "map view" to see the location of the photos on a Google Map. Hover over a marker to see the photo title, click the marker to see the image.&lt;br /&gt;&lt;br /&gt;There's a couple of things I need to improve but I thought it was useful enough to release as is. It needs to cope better when several photos have the same location - at present only one of the photos will be available on the map view. I might have a look at using tabbed info windows to cope with this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-3190254499120041719?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/3190254499120041719/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=3190254499120041719" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/3190254499120041719?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/3190254499120041719?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/maps-added-to-worldinpicturesorg_3513.html" title="Maps added to worldinpictures.org" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFR3s7cSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-1782708711266442420</id><published>2006-08-30T11:02:00.005+01:00</published><updated>2007-10-07T14:53:36.509+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:36.509+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><title>Python unicode function weirdness</title><content type="html">Python has a built-in function called &lt;em&gt;unicode&lt;/em&gt; which is intended to convert strings to unicode.&lt;br /&gt;&lt;br /&gt;When called with only one argument (the string to convert) it will assume the string is encoded in the &lt;em&gt;default encoding&lt;/em&gt;. This is normally ASCII but can be overridden in &lt;em&gt;site.py&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;I would normally want to write code that would work regardless of the default encoding. Thankfully &lt;em&gt;unicode&lt;/em&gt; can take an additional argument to allow you to specify an encoding rather than using the default. Unfortunately, and for no reason I can think of, supplying this argument causes the function to behave differently when given a unicode string as input:&lt;br /&gt;&lt;blockquote&gt;&gt;&gt;&gt; unicode(u"abc")&lt;br /&gt;u'abc'&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; unicode(u"abc", "ascii")&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;File "&amp;lt;stdin&gt;", line 1, in ?&lt;br /&gt;TypeError: decoding Unicode is not supported&lt;/blockquote&gt;&lt;br /&gt;This strikes me as rather bizarre behavior. Surely &lt;em&gt;unicode(s)&lt;/em&gt; ought  to bahave exactly the same as  &lt;em&gt;unicode(s, sys.getdefaultencoding())&lt;/em&gt;?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-1782708711266442420?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/1782708711266442420/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=1782708711266442420" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/1782708711266442420?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/1782708711266442420?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/python-unicode-function-weirdness_5441.html" title="Python unicode function weirdness" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFRH88fip7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-6035053944694151020</id><published>2006-08-30T10:45:00.006+01:00</published><updated>2007-10-07T14:53:35.176+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:35.176+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Unexpected ElementTree behavior</title><content type="html">I've been using the Python &lt;a title="ElementTree Home Page" href="http://effbot.org/zone/element-index.htm"&gt;ElementTree&lt;/a&gt; library for parsing web service responses for my &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; site and generally found it reliable and easy to use.&lt;br /&gt;&lt;br /&gt;Character encoding issues have caused me a number of problems recently and I've come across another one with ElementTree:&lt;br /&gt;&lt;blockquote&gt;&gt;&gt;&gt; from elementtree import ElementTree as ET&lt;br /&gt;&gt;&gt;&gt;  ET.XML('&amp;lt;?xml version="1.0" encoding="utf-8" ?&gt;&amp;lt;title&gt;Good morning Mazatl\xc3\xa1n!&amp;lt;/title&gt;').text&lt;br /&gt;u'Good morning Mazatl\xe1n!'&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; ET.XML('&amp;lt;?xml version="1.0" encoding="utf-8" ?&gt;&amp;lt;title&gt;Good morning Mazatln!&amp;lt;/title&gt;').text&lt;br /&gt;'Good morning Mazatln!'&lt;/blockquote&gt;&lt;br /&gt;It seems that if the element contains any non-ASCII characters then the result will be a unicode string otherwise it will be a plain string.&lt;br /&gt;&lt;br /&gt;It would be preferable to have a consistent return type (e.g. always unicode or always in the input encoding).&lt;br /&gt;&lt;br /&gt;So, in my case, I pass the result through &lt;em&gt;unicode()&lt;/em&gt; to ensure I always get a unicode result.&lt;br /&gt;&lt;br /&gt;(There's an issue here with the &lt;em&gt;unicode&lt;/em&gt; function and its reliance on the default encoding but that belongs in another post...)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-6035053944694151020?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/6035053944694151020/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=6035053944694151020" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6035053944694151020?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6035053944694151020?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/unexpected-elementtree-behavior_3034.html" title="Unexpected ElementTree behavior" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UFRXw8fyp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-2811533489620147540</id><published>2006-08-25T10:24:00.006+01:00</published><updated>2007-10-07T14:53:34.277+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:34.277+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>worldinpictures.org - see more</title><content type="html">I've added &lt;em&gt;nearer&lt;/em&gt; and &lt;em&gt;further&lt;/em&gt; links to &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt;, so now you can see more than just the 12 nearest images to your chosen place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-2811533489620147540?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/2811533489620147540/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=2811533489620147540" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/2811533489620147540?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/2811533489620147540?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/worldinpicturesorg-see-more_5351.html" title="worldinpictures.org - see more" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UESHczeSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-6949926713146358972</id><published>2006-08-24T12:58:00.006+01:00</published><updated>2007-10-07T14:53:29.981+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:29.981+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unicode" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>Google maps UTF-8 problem</title><content type="html">A while ago I came across a problem with the google geocoder apparently returning Latin1 encoded characters rather than UTF-8. I posted an &lt;a href="http://groups.google.com/group/Google-Maps-API/msg/cc0230b40cc7f906"&gt;enquiry&lt;/a&gt; to the Google Maps API group   but didn't get any responses.&lt;br /&gt;&lt;br /&gt;Now I've had time to look at this in more detail and found how to fix it. From my investigations I found that:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;	&lt;li&gt;&lt;em&gt;wget&lt;/em&gt;, &lt;em&gt;curl&lt;/em&gt; and requests made with Python &lt;em&gt;urllib2&lt;/em&gt; all returned responses encoded in &lt;em&gt;Latin1&lt;/em&gt;. Requests made with Firefox returned responses encoded in &lt;em&gt;UTF-8&lt;/em&gt;.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Regardless of the actual encoding returned, the XML always stated &lt;em&gt;encoding="UTF-8"&lt;/em&gt;.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;The Content-Type header in the HTTP response correctly gave the returned encoding (either &lt;em&gt;UTF-8&lt;/em&gt; or &lt;em&gt;ISO-8859-1&lt;/em&gt;).&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;So it looked like this had something to do with the headers sent in the HTTP request. I used &lt;em&gt;curl&lt;/em&gt; to play around with these and see if I could get a &lt;em&gt;UTF-8&lt;/em&gt; response. The obvious ones (e.g. &lt;em&gt;Accept-Charset: utf-8&lt;/em&gt;) didn't work. But what did work was changing the &lt;em&gt;User-agent&lt;/em&gt; header. So, if you want to ensure you get a &lt;em&gt;UTF-8&lt;/em&gt; response, pretend to be Firefox:&lt;br /&gt;&lt;blockquote&gt;curl -H'User-Agent: Mozilla/5.0' 'http://maps.google.com/maps/geo?key=&amp;q=cologne&amp;output=xml'&lt;/blockquote&gt;&lt;br /&gt;All this means that you can now search for cologne on &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; and it will display &lt;em&gt;Köln&lt;/em&gt; rather than &lt;em&gt;K�ln&lt;/em&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-6949926713146358972?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/6949926713146358972/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=6949926713146358972" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6949926713146358972?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6949926713146358972?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/google-maps-utf-8-problem_9034.html" title="Google maps UTF-8 problem" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total></entry><entry gd:etag="W/&quot;D0UESXcycCp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-33448638155479859</id><published>2006-08-23T14:05:00.006+01:00</published><updated>2007-10-07T14:53:28.998+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:28.998+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Ubuntu xserver problem</title><content type="html">If you find X suddenly stopped working on Ubuntu in the last few days you may have the same problem I had. Yesterday a routine update installed &lt;em&gt;xserver-xorg-core 1:1.0.2-0unbuntu10.3. &lt;/em&gt;Turns out this "breaks PCI setup for many users", so the solution is to do another update and get &lt;em&gt;xserver-xorg-core 1:1.0.2-0unbuntu10.4&lt;/em&gt; which reverts the change.&lt;br /&gt;&lt;br /&gt;Unfortunately I spent several hours trying to fix the problem before doing the sensible thing and checking if an new update was available.&lt;br /&gt;&lt;br /&gt;Note to self: always check for an update first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-33448638155479859?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/33448638155479859/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=33448638155479859" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/33448638155479859?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/33448638155479859?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/ubuntu-xserver-problem_4230.html" title="Ubuntu xserver problem" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UER3wzcSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-99982318094969946</id><published>2006-08-22T10:09:00.012+01:00</published><updated>2007-10-07T14:53:26.289+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:26.289+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="geocoding" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>worldinpictures gets UK postcodes</title><content type="html">With the help of the geocoder web service available at &lt;a href="http://worldkit.org/geocoder/"&gt;worldkit&lt;/a&gt;, &lt;a href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; now understands UK postcodes.&lt;br /&gt;&lt;br /&gt;The geocoder only gives accuracy down to the first part of the postcode  but I allow searches on full ("SW1A 0AA") or partial codes ("SW1A").&lt;br /&gt;&lt;br /&gt;Unfortunately the geocoder doesn't give results for all postcodes - "N1" for example doesn't get resolved. Not sure if this is due to the worldkit web service or the source data it uses (which comes from &lt;a href="http://www.jibble.org/ukpostcodes/"&gt;jibble.org&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Still this makes searching within the UK that bit easier - at least until the google geocoder supports it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-99982318094969946?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/99982318094969946/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=99982318094969946" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/99982318094969946?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/99982318094969946?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/worldinpictures-gets-uk-postcodes_4219.html" title="worldinpictures gets UK postcodes" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;D0UERH48fyp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-6073369103854508697</id><published>2006-08-17T09:56:00.006+01:00</published><updated>2007-10-07T14:53:25.077+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:25.077+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shell" /><title>Detabifying</title><content type="html">If that was a word I'm not sure that would be the way to spell it. I'm referring to the process of replacing tabs by spaces.&lt;br /&gt;&lt;br /&gt;The unix command &lt;em&gt;expand&lt;/em&gt; does this job - taking a file and replacing tabs with a specified number of spaces.&lt;br /&gt;&lt;br /&gt;What's the best way to run this command over a number files? &lt;em&gt;find&lt;/em&gt; is likely to be useful here to return the files to process. In my case these are all &lt;em&gt;.php&lt;/em&gt; and &lt;em&gt;.css&lt;/em&gt; files in and below the current directory:&lt;br /&gt;&lt;blockquote&gt;find . -name '*.php' -o -name '*.css'&lt;/blockquote&gt;&lt;br /&gt;will get me a list of these.&lt;br /&gt;&lt;br /&gt;I thought perhaps I could use find's &lt;em&gt;-exec&lt;/em&gt; option to run expand on the resulting files. Unfortunately expand will only send its output to stdout and as far as I can see there's no way of specifying that you want the output of an -exec'd command redirected.&lt;br /&gt;&lt;br /&gt;However, I can iterate over the results with &lt;em&gt;for&lt;/em&gt; and this does the trick (copying the results to &lt;em&gt;/tmp/x&lt;/em&gt; in this case):&lt;br /&gt;&lt;blockquote&gt;cp -r . /tmp/x&lt;br /&gt;for f in `find . -name '*.php' -o -name '*.css'`; do expand -i -t4 $f &gt; /tmp/x/$f; done&lt;/blockquote&gt;&lt;br /&gt;The initial &lt;em&gt;cp&lt;/em&gt; is just a crude way of creating the directory structure in the destintion location to stop expand failing when sub-directories don't exist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-6073369103854508697?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/6073369103854508697/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=6073369103854508697" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6073369103854508697?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/6073369103854508697?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/detabifying_8541.html" title="Detabifying" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0UERXwzeSp7ImA9WB9SF0s.&quot;"><id>tag:blogger.com,1999:blog-2786129300888040953.post-4438952100123957676</id><published>2006-08-15T16:37:00.006+01:00</published><updated>2007-10-07T14:53:24.281+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-10-07T14:53:24.281+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="geocoding" /><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures" /><title>worldinpictures.org to do list</title><content type="html">There's plenty of improvements I'd like to make to &lt;a title="worldinpictures.org" href="http://worldinpictures.org"&gt;worldinpictures.org&lt;/a&gt; in the (hopefully) near future. These include, in no particular order:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;	&lt;li&gt;Improve geocoding: The google service I currently use doesn't support all countries. Specifically it doesn't support the UK, so if you want to view images from the UK you have to find out the latitude and longitude yourself. Not very convenient. I think &lt;a title="worldkit site" href="http://worldkit.org/geocoder/"&gt;worldkit.org&lt;/a&gt; and/or &lt;a title="ukpostcodes list" href="http://www.jibble.org/ukpostcodes/"&gt;http://www.jibble.org/ukpostcodes/&lt;/a&gt; may help here.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Add a "more" button to view more  than the initial 12 images currently displayed.&lt;/li&gt;&lt;br /&gt;	&lt;li&gt;Add a feed feature so that users can subscribe to a feed of photos for a particular location.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2786129300888040953-4438952100123957676?l=www.codesimple.net' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.codesimple.net/feeds/4438952100123957676/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=4438952100123957676" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4438952100123957676?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2786129300888040953/posts/default/4438952100123957676?v=2" /><link rel="alternate" type="text/html" href="http://www.codesimple.net/2006/08/worldinpicturesorg-to-do-list_3286.html" title="worldinpictures.org to do list" /><author><name>maport</name><uri>http://www.blogger.com/profile/08407079188820602678</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="10633567591050240520" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
