<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2786129300888040953</id><updated>2016-10-26T03:47:55.132+01:00</updated><category term="worldinpictures"/><category term="cogteeth"/><category term="geocoding"/><category term="python"/><category term="unicode"/><category term="zazzle"/><category term="amazon"/><category term="android"/><category term="app engine"/><category term="blogger"/><category term="flickr"/><category term="google maps"/><category term="javascript"/><category term="persuasion"/><category term="cappuccino"/><category term="cycling"/><category term="django"/><category term="erlang"/><category term="gdata"/><category term="google apps"/><category term="html5"/><category term="mytracks"/><category term="qr code"/><category term="shell"/><category term="that big shop"/><category term="ubuntu"/><category term="wordpress"/><title type='text'>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='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><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'/><author><name>Michael Porter</name><uri>https://plus.google.com/114073795637690149215</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-Vtq4Fzf5DpI/AAAAAAAAAAI/AAAAAAAAABQ/i7ACbd0ARUc/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>30</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2786129300888040953.post-9008545835054962411</id><published>2013-05-20T11:24:00.002+01:00</published><updated>2013-05-20T11:40:48.029+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cycling"/><category scheme="http://www.blogger.com/atom/ns#" term="mytracks"/><title type='text'>Century cycle ride training</title><content type='html'>Last year I completed my first century cycle ride (a rather windy &lt;a href=&quot;http://www.centurycyclechallenge.co.uk/&quot;&gt;Century Cycle Challenge&lt;/a&gt; from Nevill Holt in Leicestershire to Brancaster on the north Norfolk coast). This year I&#39;m going to try the &lt;a href=&quot;http://www.onyourmarksevents.org/events1/cycle-events/3-counties-100.html&quot;&gt;3 Counties 100 Cyclosportive&lt;/a&gt; which is a circular route through Northamptonshire, Leicestershire and Rutland.&lt;br /&gt;&lt;br /&gt;I followed a simple nine week training plan&amp;nbsp;&amp;nbsp;last year with targets for the longest ride and longest distance each week building up the event.&lt;br /&gt;&lt;br /&gt;This year I&#39;ve created a &lt;a href=&quot;http://codesimple.bitbucket.org/tplan/&quot;&gt;Century Training Plan web app&lt;/a&gt;&amp;nbsp;so I can easily track my training against the plan. It integrates with the Google &lt;a href=&quot;http://www.google.com/mobile/mytracks/&quot;&gt;MyTracks&lt;/a&gt; app that I use on my phone to record my training rides and show me how I&#39;m doing.&lt;br /&gt;&lt;br /&gt;Head over to the &lt;a href=&quot;http://codesimple.bitbucket.org/tplan/&quot;&gt;web app&lt;/a&gt; and set the event date to use the plan for your own ride. Here&#39;s &lt;a href=&quot;http://codesimple.bitbucket.org/tplan/#%7B%3Aidf%20%22dd%2FMM%2Fyy%22%2C%20%3Aed%20%2220130721%22%7D&quot;&gt;a plan&lt;/a&gt; for the 3 Counties 100 Cyclosportive.&lt;br /&gt;&lt;br /&gt;To integrate it with your own training ride data you can either use MyTracks or record your ride details in a Google Drive spreadsheet. See the instructions on the page for details.</content><link rel='replies' type='application/atom+xml' href='http://www.codesimple.net/feeds/9008545835054962411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=9008545835054962411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/9008545835054962411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/9008545835054962411'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2013/05/century-cycle-ride-training.html' title='Century cycle ride training'/><author><name>Michael Porter</name><uri>https://plus.google.com/114073795637690149215</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-Vtq4Fzf5DpI/AAAAAAAAAAI/AAAAAAAAABQ/i7ACbd0ARUc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2786129300888040953.post-2368359882274689289</id><published>2013-02-06T17:06:00.000+00:00</published><updated>2013-02-06T17:06:52.803+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="app engine"/><category scheme="http://www.blogger.com/atom/ns#" term="html5"/><category scheme="http://www.blogger.com/atom/ns#" term="persuasion"/><title type='text'>Simple aggressive caching with Google App Engine</title><content type='html'>For the HTML5 version of my puzzle game &lt;a href=&quot;http://persuasiongame.codesimple.net/persuasion/&quot;&gt;Persuasion&lt;/a&gt;, I wanted to make sure the static resources (images, stylesheets, javascript etc) get cached for as long as possible but still ensure that I can push out new versions whenever they change.&lt;br /&gt;&lt;br /&gt;One way of doing this is to embed a version number in the URL for each resource file. You can then give the resources an expiry time far in the future and, when you need to update them, change the version number and reference them at the new URL.&lt;br /&gt;&lt;br /&gt;This is pretty straightforward with Google App Engine since you automatically get a versioned URL for your application at &lt;i&gt;versionstring&lt;/i&gt;.&lt;i&gt;yourapplication&lt;/i&gt;.appspot.com. So you can keep your app at &lt;i&gt;yourapplication&lt;/i&gt;.appspot.com (or a custom domain) and reference your resources at the versioned URL. As a bonus this also means you avoid the overhead of cookie data being sent with every resource request.&lt;br /&gt;&lt;br /&gt;For example, in my case I just use&amp;nbsp;&lt;i&gt;base&lt;/i&gt; and relative URLs to reference the resources:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;index.html&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;  &lt;i&gt;...&lt;/i&gt;&lt;br /&gt;  &amp;lt;!-- &quot;3-owap&quot; is the name of the current version of my app --&amp;gt;&lt;br /&gt;  &amp;lt;base href=&#39;//3-owap.persuasiongame.appspot.com/persuasion/&#39; /&amp;gt;&lt;br /&gt;  &lt;i&gt;...&lt;/i&gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;  &lt;i&gt;...&lt;/i&gt;&lt;br /&gt;  &amp;lt;!-- Use relative URL to reference resource file --&amp;gt;&lt;br /&gt;  &amp;lt;script src=&quot;res/js/main.js&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;  &lt;i&gt;...&lt;/i&gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Then set a long expiration for your resources, e.g. (for a Java app):&lt;br /&gt;&lt;br /&gt;&lt;b&gt;appengine-web.xml&lt;/b&gt;: &lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;i&gt;...&lt;/i&gt;&lt;br /&gt;&amp;lt;static-files&amp;gt;&lt;br /&gt;  &amp;lt;include path=&quot;/persuasion/res/**&quot; expiration=&quot;365d&quot; /&amp;gt;&lt;br /&gt;  &lt;i&gt;...&lt;/i&gt;&lt;br /&gt;&amp;lt;/static-files&amp;gt;&lt;br /&gt;&lt;i&gt;...&lt;/i&gt;&lt;/pre&gt;&lt;/blockquote&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codesimple.net/feeds/2368359882274689289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=2368359882274689289' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/2368359882274689289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/2368359882274689289'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2013/02/simple-aggressive-caching-with-google.html' title='Simple aggressive caching with Google App Engine'/><author><name>Michael Porter</name><uri>https://plus.google.com/114073795637690149215</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-Vtq4Fzf5DpI/AAAAAAAAAAI/AAAAAAAAABQ/i7ACbd0ARUc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2786129300888040953.post-3069343411649601002</id><published>2011-04-15T09:46:00.001+01:00</published><updated>2011-05-03T21:07:59.616+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="amazon"/><category scheme="http://www.blogger.com/atom/ns#" term="android"/><title type='text'>Amazon Appstore restrictive terms</title><content type='html'>This &lt;a href=&quot;http://igdaboard.wordpress.com/2011/04/14/important-advisory-about-amazon%E2%80%99s-appstore-distribution-terms-2/&quot;&gt;IGDA post&lt;/a&gt; very much echoes the concerns I had when I considering publishing to the Amazon Appstore.&lt;br /&gt;&lt;br /&gt;Make sure you read it (and the full Amazon terms) before participating in the Amazon Appstore.</content><link rel='replies' type='application/atom+xml' href='http://www.codesimple.net/feeds/3069343411649601002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=3069343411649601002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/3069343411649601002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/3069343411649601002'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2011/04/amazon-appstore-restrictive-terms.html' title='Amazon Appstore restrictive terms'/><author><name>maport</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2786129300888040953.post-316086487795863543</id><published>2010-10-27T16:45:00.002+01:00</published><updated>2011-03-17T18:51:43.646+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="android"/><category scheme="http://www.blogger.com/atom/ns#" term="persuasion"/><title type='text'>Persuasion Android app</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em; text-align: center;&quot;&gt;&lt;a href=&quot;http://persuasion.codesimple.net/&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/_1r8HCRxu89A/TMg4U0x4XpI/AAAAAAAAAD0/s77n6zJxQ7c/s1600/large_icon.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I recently published my first Android app. It&#39;s a puzzle game called &lt;i&gt;Persuasion&lt;/i&gt;. You can search for it on the market or find out more at &lt;span id=&quot;goog_1404866411&quot;&gt;&lt;/span&gt;&lt;span id=&quot;goog_1404866412&quot;&gt;&lt;/span&gt;&lt;a href=&quot;http://persuasion.codesimple.net/&quot;&gt;persuasion.codesimpl&lt;span id=&quot;goog_1404866416&quot;&gt;&lt;/span&gt;&lt;span id=&quot;goog_1404866417&quot;&gt;&lt;/span&gt;e.net&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;clear: left;&quot;&gt;Here&#39;s a few things I learnt in the process:&lt;/div&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Developing for Android is pretty pleasant: the documentation and tools are good and comprehensive. And if, like me, you&#39;re not a fan of Eclipse you don&#39;t have to use it: The tools will generate an Ant build file for your project complete with an install task to run the app on your device or emulator. I imported this into a &lt;i&gt;Java Free-Form Project&lt;/i&gt; in &lt;i&gt;NetBeans&lt;/i&gt; to get code-completion goodness whilst still using the standard build file.&lt;/li&gt;&lt;li&gt;If you want to add global highscores to your game, I&#39;d recommend &lt;a href=&quot;http://www.scoreloop.com/&quot;&gt;Scoreloop&lt;/a&gt;. Basic integration is easy and I found the support excellent.&lt;/li&gt;&lt;li&gt;Don&#39;t be afraid of the &lt;i&gt;dips&lt;/i&gt;. I initially wrote my app to run in &quot;compatibility mode&quot; (i.e. the Android System will pretend the screen is 320x480 regardless of the device). For a game, I thought it would be hassle switching to using &lt;i&gt;dips&lt;/i&gt; and handling this stuff myself. It wasn&#39;t. All I needed to do was work in &lt;i&gt;dips&lt;/i&gt; internally, grab the &lt;i&gt;density&lt;/i&gt; from &lt;i&gt;DisplayMetrics&lt;/i&gt; and then use it to scale to pixels when calling drawing APIs and scale from pixels when receiving input events.&lt;/li&gt;&lt;li&gt;If you&#39;re planning to do multiple versions of the app (e.g. a free and a paid one) use a &lt;a href=&quot;http://developer.android.com/guide/developing/other-ide.html#libraryProject&quot;&gt;Library Project&lt;/a&gt;. You can then put all your shared code and resources in a separate project. Create a new project for each variant and the build script will take care of merging the resources and code.&lt;/li&gt;&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.codesimple.net/feeds/316086487795863543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=316086487795863543' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/316086487795863543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/316086487795863543'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2010/10/persuasion-android-app.html' title='Persuasion Android app'/><author><name>maport</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_1r8HCRxu89A/TMg4U0x4XpI/AAAAAAAAAD0/s77n6zJxQ7c/s72-c/large_icon.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="amazon"/><category scheme="http://www.blogger.com/atom/ns#" term="cappuccino"/><category scheme="http://www.blogger.com/atom/ns#" term="that big shop"/><title type='text'>That Big Shop</title><content type='html'>&lt;div style=&quot;float: left&quot;&gt;&lt;a href=&quot;http://www.thatbigshop.com/&quot;&gt;&lt;img src=&quot;http://4.bp.blogspot.com/_1r8HCRxu89A/Srj87QpAkyI/AAAAAAAAADc/eFsfRn3Rc6I/s320/logo_100.png&quot; style=&quot;padding: 0; border: 0px none;&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I&#39;ve always found shopping at Amazon a bit of a cumbersome experience. The pages seem a little cluttered and when choosing between products there&#39;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&#39;d make use of the Amazon Product Advertising API and write my own interface. The result is &lt;a href=&quot;http://www.thatbigshop.com/&quot;&gt;That Big Shop&lt;/a&gt;. It&#39;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=&quot;http://cappuccino.org/&quot;&gt;Cappuccino&lt;/a&gt; framework and I&#39;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&#39;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.</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='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5767574622033830691' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5767574622033830691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5767574622033830691'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></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>2</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="qr code"/><title type='text'>QR codes for cogteeth.com</title><content type='html'>&lt;a href=&quot;http://cogteeth.com&quot;&gt;&lt;img src=&quot;http://3.bp.blogspot.com/_1r8HCRxu89A/SKF5vNP_x6I/AAAAAAAAADU/dz2Lbt3sOJA/s320-R/chart.png&quot; style=&quot;border: 0pt none ; float: left;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;With a little help from the &lt;a href=&quot;http://code.google.com/apis/chart/&quot;&gt;Google Chart API&lt;/a&gt;, I&#39;ve added the ability to create &lt;a href=&quot;http://en.wikipedia.org/wiki/QR_Code&quot;&gt;QR code&lt;/a&gt; t-shirt, mugs and cards over at &lt;a href=&quot;http://cogteeth.com/&quot;&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=&quot;http://code.google.com/p/zxing/wiki/BarcodeContents&quot;&gt;documentation&lt;/a&gt; for the zxing reader gives a good summary of these conventions.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5875410658978849850'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></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>3</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="app engine"/><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="django"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>Google App Engine</title><content type='html'>It took less than two hours to convert &lt;a href=&quot;http://cogteeth.com/&quot;&gt;cogteeth.com&lt;/a&gt; to run with the &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;Google App Engine&lt;/a&gt;. Admittedly this is a pretty simple example since cogteeth doesn&#39;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=&quot;http://code.google.com/appengine/articles/django.html&quot;&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&#39;s running with the App Engine that&#39;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...</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5739631995324729797'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="blogger"/><category scheme="http://www.blogger.com/atom/ns#" term="google apps"/><title type='text'>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 &quot;codesimple.net&quot; it complains with a somewhat dubious &quot;Another blog is already hosted at this address&quot; 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&#39;t find any setting in Google Apps to control this &quot;feature&quot;.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/8489092292891747163'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><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.986+00:00</updated><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"/><category scheme="http://www.blogger.com/atom/ns#" term="wordpress"/><title type='text'>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=&quot;http://code.google.com/apis/blogger/overview.html&quot;&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=&quot;http://www.codesimple.net-a.googlepages.com/wptoblogger.py&quot;&gt;wptoblogger.py&lt;/a&gt;.&lt;/li&gt;  &lt;li&gt;Ensure you have &lt;a href=&quot;http://python.org/&quot;&gt;Python 2.5&lt;/a&gt;, &lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/&quot;&gt;BeautifulSoup&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/gdata-python-client/&quot;&gt;Google&#39;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=&quot;font-style: italic;&quot;&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&#39;t support multiple blog authors - all posts will be marked with the &lt;span style=&quot;font-style: italic;&quot;&gt;author_for_posts&lt;/span&gt;.&lt;/li&gt;&lt;li&gt;A limitation with the Blogger API means that comment authors can&#39;t be set (they always appear as the blog author). As a workaround, I prefix each comment with a &quot;Comment from...&quot; 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;</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='http://www.blogger.com/comment.g?blogID=2786129300888040953&amp;postID=5433798081074846960' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5433798081074846960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5433798081074846960'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>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&#39;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; &#39;:&#39;.join([&#39;a&#39;,&#39;b&#39;,&#39;c&#39;])&lt;br /&gt;&#39;a:b:c&#39;&lt;br /&gt;&gt;&gt;&gt; &#39;a:b:c&#39;.split(&#39;:&#39;)&lt;br /&gt;[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]&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(&quot;:&quot;, [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]).&lt;br /&gt;[&quot;a&quot;,&quot;:&quot;,&quot;b&quot;,&quot;:&quot;,&quot;c&quot;]&lt;br /&gt;&gt; join(&quot;:&quot;, [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]).&lt;br /&gt;&quot;a:b:c&quot;&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;</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/8109416419120593027'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2786129300888040953.post-8503757987473119977</id><published>2006-11-16T18:54:00.004+00:00</published><updated>2007-10-07T14:53:44.577+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="flickr"/><title type='text'>Flickr bookmarklet</title><content type='html'>I&#39;ve just added Flickr support to the &lt;a href=&quot;http://cogteeth.com/bookmarklet/&quot;&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;</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/8503757987473119977'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2006/11/flickr-bookmarklet_8444.html' title='Flickr bookmarklet'/><author><name>maport</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><category scheme="http://www.blogger.com/atom/ns#" term="zazzle"/><title type='text'>Create products from worldinpictures.org</title><content type='html'>Integration of &lt;a href=&quot;http://cogteeth.com&quot;&gt;Cogteeth.com&lt;/a&gt; and &lt;a href=&quot;http://worldinpictures.org/&quot;&gt;worldinpictures.org&lt;/a&gt; now means that you can create &lt;a href=&quot;http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home&quot;&gt;Zazzle&lt;/a&gt; products from any images you see on worldinpictures.org. Just click the &quot;Make product...&quot; links.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/4054740461544771456'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="zazzle"/><title type='text'>Cogteeth Bookmarklet</title><content type='html'>Just added a new feature at &lt;a href=&quot;http://cogteeth.com/&quot;&gt;Cogteeth&lt;/a&gt;: the Cogteeth Bookmarklet.  Once installed, this allows you to create a &lt;a href=&quot;http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home&quot;&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&#39;s an easy solution to this - switch to a decent browser.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/5905225554460225256'/><link rel='alternate' type='text/html' href='http://www.codesimple.net/2006/10/cogteeth-bookmarklet_8339.html' title='Cogteeth Bookmarklet'/><author><name>maport</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="unicode"/><title type='text'>Cogteeth decoder added</title><content type='html'>I&#39;ve added a message decoder to &lt;a href=&quot;http://cogteeth.com&quot;&gt;Cogteeth.com&lt;/a&gt; so if you don&#39;t want to buy a t-shirt you can use it as a general UTF-8 coder/decoder!</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/7803110097709028161'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="cogteeth"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="unicode"/><category scheme="http://www.blogger.com/atom/ns#" term="zazzle"/><title type='text'>Cogteeth.com - personalized T-Shirts</title><content type='html'>Partly as an experiment with the new &lt;a title=&quot;Zazzle home page&quot; href=&quot;http://www.zazzle.com/link.asp?associate_id=238555278775050294&amp;redirect=home&quot;&gt;Zazzle&lt;/a&gt; API, I&#39;ve created a new site &lt;a title=&quot;Cogteeth.com&quot; href=&quot;http://cogteeth.com&quot;&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&#39;s what I&#39;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=&quot;Javascript source code&quot; href=&quot;http://cogteeth.com/res/mpsupport.js&quot;&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&#39;t there an &quot;onFieldValueChange&quot; event for form fields?  I currently use the &quot;keyup&quot; event but I&#39;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;</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/35596466998919601'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="geocoding"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>UK place name support for worldinpictures.org</title><content type='html'>Thanks to the excellent &lt;a href=&quot;http://www.geonames.org/export/&quot;&gt;Geo-Names webservices&lt;/a&gt; you can now enter UK place names at &lt;a href=&quot;http://worldinpictures.org/&quot;&gt;worldinpictures.org&lt;/a&gt; to see photos from that location.&lt;br /&gt;&lt;br /&gt;Previously I&#39;d been relying on the Google geocoder which doesn&#39;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.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/4749493794984343693'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="geocoding"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>Geocoded YouTube videos</title><content type='html'>I had a look at adding videos to &lt;a href=&quot;http://worldinpictures.org&quot;&gt;worldinpictures.org&lt;/a&gt; this morning. &lt;a href=&quot;http://www.youtube.com&quot;&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&#39;t make a lot of sense to geocode many of the videos on there, but I thought there might be a few more.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/7703182214110026614'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><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><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 type='text'>Retrieving officially geocoded flickr photos</title><content type='html'>I&#39;ve been updating &lt;a href=&quot;http://worldinpictures.org&quot;&gt;worldinpictures.org&lt;/a&gt; to use the new flickr geocoding API. Unfortunately it doesn&#39;t provide a &quot;find all photos near to a point ordered by distance&quot; 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 &quot;officially&quot; 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 &quot;officially&quot; 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.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/7032792970304233203'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>Firefox trounces IE</title><content type='html'>&lt;a href=&quot;http://worldinpictures.org&quot;&gt;worldinpictures.org&lt;/a&gt; made it on to the front page of &lt;a href=&quot;http://digg.com&quot;&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=&quot;http://www.memset.com?source=porteab&quot;&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&#39;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.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/551606810026774437'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="google maps"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>Google maps tabbed windows</title><content type='html'>For the new map view at &lt;a href=&quot;http://worldinpictures.org&quot;&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 (&quot;info windows&quot; 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 &quot;tabbing&quot; 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...</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/1632905230678803645'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="google maps"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>Maps added to worldinpictures.org</title><content type='html'>I&#39;ve just added a &quot;map view&quot; to &lt;a href=&quot;http://worldinpictures.org&quot;&gt;worldinpictures.org&lt;/a&gt;. There&#39;s now a couple of links below the search results to switch between &quot;gallery view&quot; and &quot;map view&quot;. Select &quot;map view&quot; 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&#39;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.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/3190254499120041719'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="unicode"/><title type='text'>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&quot;abc&quot;)&lt;br /&gt;u&#39;abc&#39;&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; unicode(u&quot;abc&quot;, &quot;ascii&quot;)&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;File &quot;&amp;lt;stdin&gt;&quot;, 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;?</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/1782708711266442420'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="python"/><category scheme="http://www.blogger.com/atom/ns#" term="unicode"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>Unexpected ElementTree behavior</title><content type='html'>I&#39;ve been using the Python &lt;a title=&quot;ElementTree Home Page&quot; href=&quot;http://effbot.org/zone/element-index.htm&quot;&gt;ElementTree&lt;/a&gt; library for parsing web service responses for my &lt;a href=&quot;http://worldinpictures.org&quot;&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&#39;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(&#39;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;&amp;lt;title&gt;Good morning Mazatl\xc3\xa1n!&amp;lt;/title&gt;&#39;).text&lt;br /&gt;u&#39;Good morning Mazatl\xe1n!&#39;&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; ET.XML(&#39;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;&amp;lt;title&gt;Good morning Mazatln!&amp;lt;/title&gt;&#39;).text&lt;br /&gt;&#39;Good morning Mazatln!&#39;&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&#39;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...)</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/6035053944694151020'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>worldinpictures.org - see more</title><content type='html'>I&#39;ve added &lt;em&gt;nearer&lt;/em&gt; and &lt;em&gt;further&lt;/em&gt; links to &lt;a href=&quot;http://worldinpictures.org&quot;&gt;worldinpictures.org&lt;/a&gt;, so now you can see more than just the 12 nearest images to your chosen place.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/2811533489620147540'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><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><category scheme="http://www.blogger.com/atom/ns#" term="unicode"/><category scheme="http://www.blogger.com/atom/ns#" term="worldinpictures"/><title type='text'>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=&quot;http://groups.google.com/group/Google-Maps-API/msg/cc0230b40cc7f906&quot;&gt;enquiry&lt;/a&gt; to the Google Maps API group   but didn&#39;t get any responses.&lt;br /&gt;&lt;br /&gt;Now I&#39;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=&quot;UTF-8&quot;&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&#39;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&#39;User-Agent: Mozilla/5.0&#39; &#39;http://maps.google.com/maps/geo?key=&amp;q=cologne&amp;output=xml&#39;&lt;/blockquote&gt;&lt;br /&gt;All this means that you can now search for cologne on &lt;a href=&quot;http://worldinpictures.org&quot;&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;.</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='http://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'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2786129300888040953/posts/default/6949926713146358972'/><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><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry></feed>