<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><!-- name="generator" content="blosxom/2.0" 
 --><rss xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Sounds From The Dungeon   </title>
    <link>http://antrix.net/journal</link>
    <description>musings of a meshuga mind</description>
    <language>en</language>
    <copyright>Copyright Deepak Sarda</copyright>
 <managingEditor>deepak@antrix.net (deepak sarda)</managingEditor>

  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://www.antrix.net/journal/index.rss" type="application/rss+xml" /><feedburner:emailServiceId>antrix</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><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><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>Links for 2009-07-01 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-07-01</link><pubDate>Thu, 02 Jul 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-07-01</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-June/020620.html"&gt;[whatwg] Codecs for &amp;lt;audio&amp;gt; and &amp;lt;video&amp;gt;&lt;/a&gt;&lt;br/&gt;
Great overview of the (sad) situation&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Links for 2009-06-30 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-06-30</link><pubDate>Wed, 01 Jul 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-06-30</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://io9.com/5302099/michaelbayfacts-+-the-greatest-transformers-tie+in-yet"&gt;Michael Bay Facts&lt;/a&gt;&lt;br/&gt;
Like Chuck Norris Facts :-)&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Links for 2009-06-23 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-06-23</link><pubDate>Wed, 24 Jun 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-06-23</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.techgoondu.com/2009/06/23/pay-apple-us4990-to-fix-46-security-holes-in-your-ipod-touch/"&gt;Pay Apple US$9.90 to fix 46 security holes in your iPod Touch&lt;/a&gt;&lt;br/&gt;
Food for thought&lt;/li&gt;
&lt;/ul&gt;</description></item><item>
    <title>New Toys</title>
    <link>http://antrix.net/journal/misc/new_toys.html</link>
    <description>&lt;p&gt;This past Saturday, I went down to the PC Show 2009 and got some new toys to play with.&lt;/p&gt;

&lt;p&gt;The first is the &lt;a href="http://www.engadget.com/2009/06/05/acer-aspire-timeline-review-roundup/"&gt;Acer Aspire Timeline 3810T&lt;/a&gt; notebook, sporting Intel's new ultra-low voltage &lt;a href="http://www.engadget.com/2009/06/05/acer-aspire-timeline-review-roundup/"&gt;SU9400 Core 2 Duo&lt;/a&gt; processor and promising a battery life of 8 hours! &lt;/p&gt;

&lt;p&gt;&lt;img src="http://antrix.net/images/journal/acer-timeline.jpg" alt="Acer Aspire Timeline notebook" /&gt;&lt;/p&gt;

&lt;p&gt;Some specs: 13.3" (1366x768) LED-backlit display, 4GB DDR3 RAM, 500GB HDD. Price: SGD 1470.&lt;/p&gt;

&lt;p&gt;I really like the design of this laptop. Very clean without any of the gimmicky buttons or a hundred flashing lights that seem to be so prevalent on all the laptops these days. But what really made me settle on this model was the combination of insanely long battery life coupled with an amazingly light body weight of just 1.6kg!&lt;/p&gt;

&lt;p&gt;It is a bit weak in the graphics department but it plays HD videos from vimeo.com and youtube just fine which is enough juice for my needs. &lt;/p&gt;

&lt;p&gt;The other toy I got was a replacement for my ageing N73 phone: a sleek black &lt;a href="http://www.android.com/"&gt;Android&lt;/a&gt; powered &lt;a href="http://www.htc.com/sea/product/magic_GMS/overview.html"&gt;HTC Magic&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://antrix.net/images/journal/htcmagic.jpg" alt="HTC Magic phone" /&gt;&lt;/p&gt;

&lt;p&gt;This was a bit of a surprise since I hadn't expected the Magic to be on sale and even if it was, all news I had heard about it indicated that it would be retailing at SGD 1000+ - something out of my budget. As it turned out, my current service provider M1 had quietly launched the Magic and I was able to get one for SGD 508 after trading in the N73 for a 100 dollar rebate.&lt;/p&gt;

&lt;p&gt;All in all, the geek in me is super happy playing with the new toys :)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/misc</category>
 <slash:comments>5</slash:comments> 
  <comments>http://antrix.net/journal/misc/new_toys.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/misc/new_toys.html</guid>   <pubDate>Mon, 15 Jun 2009 11:37 +0800</pubDate>
    </item>
  <item><title>Links for 2009-06-08 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-06-08</link><pubDate>Tue, 09 Jun 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-06-08</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://feedproxy.google.com/~r/GoogleOpenSourceBlog/~3/un-P6NVCPhA/introducing-android-scripting.html"&gt;Introducing Android Scripting Environment&lt;/a&gt;&lt;br/&gt;
I really must get an Android phone now!&lt;/li&gt;
&lt;/ul&gt;</description></item><item>
    <title>Logo Wars!</title>
    <link>http://antrix.net/journal/misc/logo_wars.html</link>
    <description>&lt;p&gt;Exhibit #1&lt;/p&gt;

&lt;p&gt;&lt;a style="border: none;" href="http://edubuntu.org/"&gt;&lt;img src="http://antrix.net/images/journal/edubuntu-logo.png" alt="Edubuntu Logo" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exhibit #2&lt;/p&gt;

&lt;p&gt;Something I noticed plastered on a bus today:&lt;/p&gt;

&lt;p&gt;&lt;a style="border: none;" href="http://fairemployment.sg/"&gt;&lt;img src="http://antrix.net/images/journal/fairemployment-sg-logo.jpg" alt="Fairemployment.sg Logo" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wonder which came first!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/misc</category>
 <slash:comments>0</slash:comments> 
  <comments>http://antrix.net/journal/misc/logo_wars.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/misc/logo_wars.html</guid>   <pubDate>Fri, 05 Jun 2009 12:05 +0800</pubDate>
    </item>
  <item><title>Links for 2009-05-31 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-05-31</link><pubDate>Mon, 01 Jun 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-05-31</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://techno-cast.blogspot.com/2009/05/podcast-0-aka-hello-world-google-wave.html"&gt;TechnoBabble Podcast #0, a.k.a. 'Hello, World'&lt;/a&gt;&lt;br/&gt;
wherein we babble about Google Wave&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Links for 2009-05-24 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-05-24</link><pubDate>Mon, 25 May 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-05-24</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://r6.ca/blog/20090522T015739Z.html"&gt;Do Not Play the Lottery Unless You Are a Millionaire&lt;/a&gt;&lt;br/&gt;
Can someone run the numbers for Singapore&amp;#039;s 4D?&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Links for 2009-05-22 [del.icio.us]</title><link>http://del.icio.us/antrix/linker#2009-05-22</link><pubDate>Sat, 23 May 2009 00:00:00 PDT</pubDate><guid isPermaLink="false">http://del.icio.us/antrix/linker#2009-05-22</guid><description>&lt;ul&gt;
&lt;li&gt;&lt;a href="http://farm4.static.flickr.com/3653/3540848670_a44a547d89_o.jpg"&gt;Size does not matter!&lt;/a&gt;&lt;br/&gt;
being in the right place does :)&lt;/li&gt;
&lt;/ul&gt;</description></item><item>
    <title>Giving up on NextBus</title>
    <link>http://antrix.net/journal/techtalk/sbsnextbus4.html</link>
    <description>&lt;p&gt;My bus arrival timings web-app, &lt;a href="http://sbsnextbus.appspot.com/"&gt;NextBus&lt;/a&gt;, has been performing very poorly for the past several weeks. I've tried everything I can to fix it but unfortunately I can't. Given the circumstances, I have decided to stop further development on the app.&lt;/p&gt;

&lt;p&gt;I'll try and describe why the site is broken but the summary is this: I have reason to believe that SBS Transit is rejecting network connections from my app to its servers. In the face of this, there is no way that I can keep NextBus functional.&lt;/p&gt;

&lt;p&gt;To regular users who have come to rely on NextBus, I am sorry for letting you down. I have also let down the folks behind third-party apps such as &lt;a href="http://www.singeo.com.sg/?p=204"&gt;iSingeo&lt;/a&gt; and &lt;a href="http://www.iridianstudio.com/"&gt;SG Buses&lt;/a&gt; which relied on NextBus. I feel really bad that they spent time integrating their applications with NextBus which is now a waste.&lt;/p&gt;

&lt;p&gt;I'll leave the site running and it will at least work for the &lt;a href="http://www.publictransport.sg/public/ptp/en/Getting-Around/list-of-bus-stops-arrival-time.html"&gt;200 odd stops&lt;/a&gt; for which arrival information is available via &lt;a href="http://www.publictransport.sg/"&gt;PublicTransport@SG&lt;/a&gt;. iPhone users: you may want to try &lt;a href="http://www.line-42.com/products/transguide/"&gt;tranSGuide&lt;/a&gt;, an app that shows bus arrival timings. It's developed by a friend and it still works :-)&lt;/p&gt;

&lt;h4&gt;The Details&lt;/h4&gt;

&lt;p&gt;As you know, the core functionality of NextBus is to provide you with arrival information of all buses at any bus stop. To do this, it has to communicate with the &lt;a href="http://www.sbstransit.com.sg/mobileiris/"&gt;SBS Transit mobile iris&lt;/a&gt; website which provides the information, although in a &lt;a href="http://antrix.net/journal/techtalk/sbsnextbus.html"&gt;rather inconvenient manner&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Starting sometime in the last week of March, several connection requests to the SBS Transit servers from the Google App Engine environment (&lt;a href="http://antrix.net/journal/techtalk/sbsnextbus2.html"&gt;the infrastructure that hosts NextBus&lt;/a&gt;), started timing out. I didn't notice it initially since the stops that I personally use NextBus for are handled by the &lt;a href="http://www.publictransport.sg/"&gt;Public Transport@SG&lt;/a&gt; service, which NextBus also supports. When I did notice the problem from the server logs, I didn't have sufficient time to investigate the cause since I was to leave town for a week. So the site suffered while I was away.&lt;/p&gt;

&lt;p&gt;When I got back, it took me a day to figure out what the problem was (requests to SBS servers timing out) and another day to implement a work-around. My work-around was simple - I implemented a simple web proxy that just fetches pages from SBS servers and returns them as is. I put up this proxy on an &lt;a href="http://aws.amazon.com/ec2/"&gt;Amazon EC2&lt;/a&gt; server instance hosted in the US. I modified the NextBus code to request pages from this proxy instead of requesting them directly from SBS servers. This worked! SBS pages were flowing back to NextBus via the proxy. So I quickly put this new proxy-powered code into production and the NextBus site was working reliably again. I thought it was kind-of weird that direct connections from the App Engine environment were not working but connections from Amazon servers were working. But hey, it was working now! So I didn't give it much thought.&lt;/p&gt;

&lt;p&gt;Until a week later.&lt;/p&gt;

&lt;p&gt;A week after implementing the proxy, requests from the Amazon EC2 server hosting the proxy also started timing out! I then moved the proxy service to my shared hosting server; the same server that shows you this blog. So now requests were going from NextBus to my shared hosting server to SBS servers and all the way back. NextBus was working again.&lt;/p&gt;

&lt;p&gt;This lasted for three days.&lt;/p&gt;

&lt;p&gt;Interestingly enough, when the proxy service on my shared hosting server stopped working, it wasn't because of connections to SBS timing out. No, the connection attempts were simply getting dropped! They still are, as a matter of fact. &lt;/p&gt;

&lt;p&gt;Then I asked couple of my friends to help me out. They kindly agreed to host the proxy service on their servers.  You can guess how that went.&lt;/p&gt;

&lt;p&gt;Given what I've seen so far, I think the reasonable conclusion to draw is that the folks at SBS are denying connections from NextBus. It may be intentional or it may just be an automated response by some network monitoring tool that is banning any IP that originates an unusually high number of requests. Either way, I don't have an endless supply of proxy servers at my disposal to try and work around the connection bans. And even if I did have that supply, I have no intention of actually doing it since it makes no sense to go on with NextBus when SBS does not like what I am doing here.&lt;/p&gt;

&lt;p&gt;So to all of NextBus' users, &lt;em&gt;so long and thanks for all the fish!&lt;/em&gt;&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>21</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/sbsnextbus4.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/sbsnextbus4.html</guid>   <pubDate>Fri, 15 May 2009 00:01 +0800</pubDate>
    </item>
  <item>
    <title>Talk on Google App Engine</title>
    <link>http://antrix.net/journal/media/appengine_talk.html</link>
    <description>&lt;p&gt;I gave an introductory talk on &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt; yesterday at &lt;a href="http://riaction.sg/"&gt;RIAction&lt;/a&gt;, a Rich Internet Application platforms focussed day-long event here in Singapore. I am embedding the slides here or you can &lt;a href="http://docs.google.com/Present?docid=df9w5z4c_19cg3fb5cd&amp;amp;skipauth=true"&gt;click here&lt;/a&gt; to view in fullscreen or download the deck. Sorry about the lack of any notes!&lt;/p&gt;

&lt;iframe src='http://docs.google.com/EmbedSlideshow?docid=df9w5z4c_19cg3fb5cd' frameborder='0' width='410' height='342'&gt;&lt;/iframe&gt;

&lt;p&gt;The event went well for a first effort. Thanks to the organizers &amp;amp; the sponsors for putting this thing together!&lt;/p&gt;

&lt;p&gt;On a humourous note, the goodie bag included a first-aid kit sponsored by Microsoft. Feel free to speculate on why MS would be handing out band-aids to developers ;-)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/media</category>
 <slash:comments>4</slash:comments> 
  <comments>http://antrix.net/journal/media/appengine_talk.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/media/appengine_talk.html</guid>   <pubDate>Fri, 27 Feb 2009 11:28 +0800</pubDate>
    </item>
  <item>
    <title>Gothere script update</title>
    <link>http://antrix.net/journal/techtalk/nextbus_gothere2.html</link>
    <description>&lt;p&gt;Some time back, I wrote about my tiny little &lt;a href="http://antrix.net/journal/techtalk/nextbus_gothere.html"&gt;greasemonkey script for gothere.sg&lt;/a&gt; - all it does is replace links to SBS Transit with links to my NextBus app. Back then, I also wrote that time permitting, I'd update the script to fetch the bus arrival timings &amp;amp; show them within the bubble itself, instead of triggering a new page load. As you've already guessed, I found the time :)&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/journal/gothere-nextbus.png" alt="gothere nextbus screenshot"/&gt;&lt;/div&gt;

&lt;p&gt;To install/upgrade, just click here: &lt;a href="http://antrix.net/code/hg/misc/greasemonkey/raw-file/tip/nextbus_gotheresg.user.js"&gt;NextBus &amp;amp; gothere.sg&lt;/a&gt;. Remember, you must have &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt; already installed in Firefox. If someone feels like packaging the script as a Firefox extension, please do :-)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Okay, here's the &lt;a href="http://antrix.net/stuff/nextbus_gotheresg.xpi"&gt;NextBus &amp;amp; gothere Firefox Extension.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, a note of thanks to the &lt;a href="http://gothere.sg/"&gt;gothere&lt;/a&gt; folks. This update wouldn't have been possible without some code changes on the gothere site. I wrote to them about it and in just a few hours, Dominic got back saying he had already implemented my request! After that, updating the script took no time. Thanks Dominic!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>6</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/nextbus_gothere2.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/nextbus_gothere2.html</guid>   <pubDate>Fri, 23 Jan 2009 10:16 +0800</pubDate>
    </item>
  <item>
    <title>Boxee + Wiimote = &#x2665;</title>
    <link>http://antrix.net/journal/techtalk/boxee_wiimote.html</link>
    <description>&lt;p&gt;I've been using &lt;a href="http://boxee.tv/"&gt;Boxee&lt;/a&gt; on my Linux system at home for several months now and I am really happy with it. However, one thing that is kind of a pain is having to get up and reach for the keyboard just to control Boxee. Ever since I got a Wii a month ago, I had resolved to correct this shortcoming and the recent upgrade to Ubuntu Intrepid seemed like a perfect time to dive in. So herewith are my short notes on how to control Boxee with a Wiimote!&lt;/p&gt;

&lt;p&gt;The basic idea here is that the Wiimote communicates with the Wii console using &lt;em&gt;bluetooth&lt;/em&gt;. So if your computer supports bluetooth, it can start talking to the Wiimote over bluetooth using some custom bits of software. Note that this does not involve the use of the Wii's IR sensor bar. Leave that connected to your TV!&lt;/p&gt;

&lt;p&gt;First thing you'll need to do is to install a bunch of packages that enable interaction with the Wiimote.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; sudo apt-get install wminput wmgui lswm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once these packages are installed, run &lt;code&gt;lswm&lt;/code&gt; to see if your Wii got detected. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; lswm
Put Wiimotes in discoverable mode now (press 1+2)...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Follow the instructions and you should soon see &lt;code&gt;lswm&lt;/code&gt; print out your Wiimote's bluetooth MAC address. This would be something like &lt;code&gt;00:1E:35:09:9A:9A&lt;/code&gt;. If &lt;code&gt;lswm&lt;/code&gt; exits before discovery is complete, just re-run it till you see the MAC address. Make note of the address.&lt;/p&gt;

&lt;p&gt;Next, to verify that all the Wiimote button presses can be detected by your computer, run &lt;code&gt;wmgui&lt;/code&gt; and use the &lt;code&gt;File &amp;gt; Connect&lt;/code&gt; option to connect to the Wii. You may be asked to put the Wii in discoverable mode again. Once the Wiimote is connected, just press the buttons on your Wiimote &amp;amp; &lt;code&gt;wmgui&lt;/code&gt; will show what buttons you pressed.&lt;/p&gt;

&lt;p&gt;Now that this basic test procedure is done, we are ready to use the Wiimote as a mouse. This requires the use of a kernel module called &lt;code&gt;uinput&lt;/code&gt;. Load it up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; sudo modprobe uinput
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now enable mouse mode by typing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; sudo wminput 00:1E:35:09:9A:9A
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Take care to replace the bluetooth address in the above command with your own Wiimote's address! With &lt;code&gt;wminput&lt;/code&gt; running, you should be able to control the mouse (in a bizarre way) by tilting your Wiimote &amp;amp; pressing the A or B buttons. Once this works, hit &lt;code&gt;Ctrl+C&lt;/code&gt; to exit &lt;code&gt;wminput&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If you noticed, in the default mouse mode, the Wiimote's A button was mapped to left click while the button B was mapped to right click. The &lt;code&gt;wminput&lt;/code&gt; tools allows you to map the buttons in whatever manner suits you. We'll setup a key mapping that makes sense to use with Boxee. &lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; cd /etc/cwiid/wminput
&amp;#036; sudo cp buttons boxee-buttons
&amp;#036; sudo vim boxee-buttons
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;boxee-buttons&lt;/code&gt; file, you'll find the default key mappings for the Wiimote as well as the Nunchuck &amp;amp; the Nintendo Classic controller. Ignore the latter two and replace the Wiimote's key mapping lines with these:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#buttons
Wiimote.A       = KEY_KPENTER
Wiimote.B       = KEY_ESC
Wiimote.Up      = KEY_UP
Wiimote.Down    = KEY_DOWN
Wiimote.Left    = KEY_LEFT
Wiimote.Right   = KEY_RIGHT
Wiimote.Minus   = KEY_KPMINUS
Wiimote.Plus    = KEY_KPPLUS
Wiimote.Home    = KEY_H
Wiimote.1       = KEY_SPACE
Wiimote.2       = KEY_S
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above mapping should be obvious. You can get a list of supported key codes from the &lt;a href="http://abstrakraft.org/cwiid/browser/trunk/wminput/action_enum.txt"&gt;wminput source&lt;/a&gt;. With the mapping file in place, re-run &lt;code&gt;wminput&lt;/code&gt; but specifying this custom mapping file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; sudo wminput -c boxee-buttons 00:1E:35:09:9A:9A
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once &lt;code&gt;wminput&lt;/code&gt; is running, fire up Boxee and you should now be able to control it using your Wiimote!&lt;/p&gt;

&lt;p&gt;It is time to make all these settings permanent. First, the loading of the kernel module is automated by adding the module name &lt;code&gt;uinput&lt;/code&gt; to a new line at the end of the file &lt;code&gt;/etc/modules&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;If you noticed, we were running &lt;code&gt;wminput&lt;/code&gt; with superuser privileges. We'll remedy this by adding a &lt;code&gt;udev&lt;/code&gt; rule that lets any user in the &lt;code&gt;plugdev&lt;/code&gt; group access the &lt;code&gt;uinput&lt;/code&gt; module. Create a file (as root) named &lt;code&gt;50-cwiid-input.rules&lt;/code&gt; in the &lt;code&gt;/etc/udev/rules.d&lt;/code&gt; directory with the following line in the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;KERNEL=="uinput", GROUP="plugdev"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Typically, your user will be in the &lt;code&gt;plugdev&lt;/code&gt; group. If not, replace the group with something else like &lt;code&gt;admin&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;Finally, create a startup script that starts &lt;code&gt;wminput&lt;/code&gt; when you log in to your X session. For KDE, this would mean creating a script in &lt;code&gt;~/.kde/Autostart&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;#036; cd ~/.kde/Autostart
&amp;#036; echo '#!/bin/sh' &amp;gt; wminput.sh
&amp;#036; echo 'wminput -dc boxee-buttons 00:1E:35:09:9A:9A' &amp;gt;&amp;gt; wminput.sh
&amp;#036; chmod +x wminput.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That's it! Once you restart your computer, your Wiimote will be ready to use! If you find it's not working, try putting it in discoverable mode and the already running &lt;code&gt;wminput&lt;/code&gt; daemon will pick it up.&lt;/p&gt;

&lt;p&gt;Have fun!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>2</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/boxee_wiimote.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/boxee_wiimote.html</guid>   <pubDate>Sun, 18 Jan 2009 18:23 +0800</pubDate>
    </item>
  <item>
    <title>A brief announcement</title>
    <link>http://antrix.net/journal/misc/marriage.html</link>
    <description>&lt;p&gt;I'm off to India today for about &lt;a href="http://www.dopplr.com/traveller/antrix/public"&gt;two weeks&lt;/a&gt; starting today. Top item on the agenda for this trip is to get married next Saturday :)&lt;/p&gt;

&lt;p&gt;If you happen to be in Hyderabad, &lt;a href="http://antrix.net/card/"&gt;you are invited&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Adios.&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/misc</category>
 <slash:comments>3</slash:comments> 
  <comments>http://antrix.net/journal/misc/marriage.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/misc/marriage.html</guid>   <pubDate>Sat, 22 Nov 2008 17:48 +0800</pubDate>
    </item>
  <item>
    <title>Mitter 0.4</title>
    <link>http://antrix.net/journal/techtalk/mitter_release.html</link>
    <description>&lt;p&gt;After a long time, we have a new &lt;a href="http://code.google.com/p/mitter/"&gt;Mitter&lt;/a&gt; release. What's Mitter you say? Mitter is a sweet and simple &lt;a href="http://twitter.com/"&gt;Twitter&lt;/a&gt; client for Linux desktops. You can use it as a regular graphical app that sits in your system tray till you need it or as a CLI app tucked away in one of your half a dozen terminal windows.&lt;/p&gt;

&lt;p&gt;There isn't much new feature wise in this release. The &lt;a href="http://code.google.com/p/mitter/wiki/ChangeLog04"&gt;Changelog&lt;/a&gt; is there for you to peruse. Just think of it as a release that rolls up all the current fixes and lets us focus on the next set of features :-)&lt;/p&gt;

&lt;p&gt;If you are a Twitter user running Linux, do give Mitter a try! It's really nice, and that's &lt;a href="http://code.google.com/p/mitter/wiki/Quotes"&gt;not just me&lt;/a&gt; saying it :-)&lt;/p&gt;

&lt;p&gt;Source packages can be downloaded from &lt;a href="http://code.google.com/p/mitter/"&gt;Mitter's project page&lt;/a&gt; while Ubuntu users can use &lt;a href="https://launchpad.net/~sugree/+archive"&gt;Sugree's PPA&lt;/a&gt; to get the latest version.&lt;/p&gt;

&lt;p&gt;Incidentally, the release names for the 0.4 cycle will be based on quotes from Jurassic Park, in honour of Michael Crichton.&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>0</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/mitter_release.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/mitter_release.html</guid>   <pubDate>Wed, 12 Nov 2008 19:10 +0800</pubDate>
    </item>
  <item>
    <title>NextBus meets gothere.sg</title>
    <link>http://antrix.net/journal/techtalk/nextbus_gothere.html</link>
    <description>&lt;p&gt;Without a doubt, &lt;a href="http://gothere.sg/"&gt;gothere.sg&lt;/a&gt; is one of the best Singapore-focussed map sites today. It may not be the best in terms of content but it's surely the best in terms of usability.&lt;/p&gt;

&lt;p&gt;They have this feature where they show little &lt;a href="http://blog.gothere.sg/2008/06/click-and-drag-goodness.html"&gt;bus stop icons&lt;/a&gt; on the map which you can click to bring up a list of bus services operating at that stop. They also include a link to SBS Transit's mobile iris website to check when the next bus is arriving. You can see where this is going :-)&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://bp3.blogger.com/_fQvkbekoJ9w/SFDGmxkm_HI/AAAAAAAAAAM/itcFWg7h1lA/s400/screen1.png" alt="Gothere.sg bus stop popup" /&gt;&lt;/div&gt;

&lt;p&gt;I just put together a tiny &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/748"&gt;Greasemonkey&lt;/a&gt; script which replaces the link to iris with a link to my &lt;a href="http://sbsnextbus.appspot.com/"&gt;NextBus&lt;/a&gt; app. If you have Greasemonkey already setup in your Firefox, you can install the script by clicking here: &lt;a href="http://antrix.net/code/hg/misc/greasemonkey/raw-file/tip/nextbus_gotheresg.user.js"&gt;NextBus &amp;amp; gothere.sg&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or just install the &lt;a href="http://antrix.net/stuff/nextbus_gotheresg.xpi"&gt;NextBus &amp;amp; gothere Firefox Extension&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I find some time in the future, I'll update the script to fetch the arrival timings and show them within the bubble itself, instead of having to load a new page. &lt;strong&gt;Update:&lt;/strong&gt; &lt;a href="http://antrix.net/journal/techtalk/nextbus_gothere2.html"&gt;Done!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As always, bug reports are welcome. :-)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>0</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/nextbus_gothere.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/nextbus_gothere.html</guid>   <pubDate>Thu, 06 Nov 2008 18:23 +0800</pubDate>
    </item>
  <item>
    <title>SBS NextBus: The Next Release</title>
    <link>http://antrix.net/journal/techtalk/sbsnextbus3.html</link>
    <description>&lt;p&gt;I've just pushed to production a new version of &lt;a href="http://sbsnextbus.appspot.com/"&gt;NextBus&lt;/a&gt;, a web-app that I created for tracking bus arrival information at bus stops in Singapore. Read more about it in my earlier post &lt;a href="http://antrix.net/journal/techtalk/sbsnextbus.html"&gt;announcing NextBus&lt;/a&gt;. Now before I get into what's new, let me first provide you with a list of things that provided the impetus for this new release.&lt;/p&gt;

&lt;p&gt;Firstly, NextBus is way more popular than I expected it to ever be. Currently, the site receives well over a thousand requests per day! Considering that I spent zero energy in &lt;em&gt;marketing&lt;/em&gt; it, I am quite happy with the uptake and have to thank everyone for using it as well as for spreading the word about its existence! What this also means is that I now have an incentive to keep maintaining it and making new releases!&lt;/p&gt;

&lt;p&gt;Secondly, nearly 40% of the site's usage is via Jon's &lt;a href="http://www.singeo.com.sg/?p=204"&gt;integration of NextBus with isingeo.com and singeo.com.sg&lt;/a&gt;. That's quite a few people who are accessing the app only indirectly. And this is despite the fact that the mashup that Jon created is a very crude one relying on just embedding the sbsnextbus.appspot.com pages within his sites. Could I do something to improve the quality and scope of such mashups?&lt;/p&gt;

&lt;p&gt;Thirdly, the demographic that uses the app is quite different from my initial expectations. When I first released the app, I had assumed that the majority of requests would come from mobile phones and the app's design &amp;amp; implementation was based on this assumption. But a look at the logs pulled from Google Analytics reveal that the reality is quite different:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/journal/analytics-nextbus.png" alt="chart of requests breakdown by browser" title="requests breakdown by browser" /&gt;&lt;/div&gt;

&lt;p&gt;There's a caveat to these numbers: the tracking code is only used on the home page. If you visit only the results pages or use the app via isingeo.com, etc., your usage won't show up in the data above. Nevertheless, as you can see, over 45% of usage is from full-fledged desktop browsers. If you count the iPhone too, the proportion of visitors using a fully capable browser goes up by another 18%. The conclusion from all this data? Although I designed the NextBus app for browsers that face network latency &amp;amp; bandwidth constraints - like my Nokia N73 browser - there's significant usage from browsers that face no such constraints. So a substantial number of users are getting a sub-optimal experience from the site.&lt;/p&gt;

&lt;p&gt;And finally, the launch of &lt;a href="http://www.publictransport.sg/"&gt;PublicTransport@SG&lt;/a&gt; couple of weeks ago. This new site is maintained by the Land Transport Authority and includes real time bus arrival information for quite a few bus stops around town. The obvious benefit over SBS Transit's iris service is that LTA's information includes timing information for buses operated by SMRT. Apart from providing arrival information on the PublicTransport@SG site, LTA has also launched an SMS enquiry service similar to iris. However, there is no trace of a mobile optimized version of the site. Thus, there is scope for me to do some work after all :-)&lt;/p&gt;

&lt;p&gt;So these were the things I had in mind while working on the three big features in this new release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimized site for capable browsers&lt;/strong&gt; If your browser can handle it, it will be presented with a results page that is much faster to load. This is done by querying for all the different services at your particular bus stop in parallel using AJAX. Once the page is loaded, you can refresh the results without causing a full page reload. You can also refresh results for just one particular service by clicking its link. For other (mobile phone) browsers which can't handle AJAX, the old style static html results page will be served. I've tested this in Firefox, IE 6/7 and Opera on the desktop. The AJAX powered results also work on the iPhone. If there's something broken with this feature, please do get in touch! &lt;strong&gt;Note:&lt;/strong&gt; if you have saved the results pages as bookmarks, you'll not get the AJAX effect since the URLs have changed. Please update your bookmarks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JSON API&lt;/strong&gt; With this release, I am launching a publicly accessible API to provide developers with access to bus arrival data in a clean format. The whole AJAX experience is itself powered by this API. I hope the release of this API will spur the creation of lots of great mashups! The details of the API are documented further down this post and I welcome developer feedback for this feature. Also, this feature finally makes NextBus Web 2.0 compliant. ;-)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PublicTransport@SG integration&lt;/strong&gt; As you may have guessed (if you actually read the preamble!), NextBus now integrates results from LTA's site. If the bus stop you query for happens to be one of the (as of now) &lt;a href="http://www.publictransport.sg/public/ptp/en/Getting-Around/list-of-bus-stops-arrival-time.html"&gt;213 stops&lt;/a&gt; that PublicTransport@SG provides results for, NextBus will pull results from there. By virtue of this, arrival info for SMRT buses is also available for these 213 stops.&lt;/p&gt;

&lt;p&gt;That's about it! I urge you to &lt;a href="http://sbsnextbus.appspot.com/"&gt;try out the new release&lt;/a&gt; and let me know if you find anything that's broken or doesn't work as expected. If you do find NextBus to be more useful than ever, please talk about it! &lt;em&gt;Marketing!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name="JSONAPI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;JSON API&lt;/h3&gt;

&lt;p&gt;The API is very simple. There are two URI end points that the API provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;http://sbsnextbus.appspot.com/api/v1/&amp;lt;busstopnumber&amp;gt;/&lt;/code&gt;  -&gt; Returns the stop description (if available) and a list of bus services operating at the queried stop.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;http://sbsnextbus.appspot.com/api/v1/&amp;lt;busstopnumber&amp;gt;/&amp;lt;service&amp;gt;/&lt;/code&gt; -&gt; Returns arrival timings for the queried bus service &amp;amp; stop combination.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples: &lt;a href="http://sbsnextbus.appspot.com/api/v1/92049/"&gt;http://sbsnextbus.appspot.com/api/v1/92049/&lt;/a&gt; and &lt;a href="http://sbsnextbus.appspot.com/api/v1/92049/15/"&gt;http://sbsnextbus.appspot.com/api/v1/92049/15/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The response is in the &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; format. The response schema should be pretty obvious looking at the results to the above query. &lt;/p&gt;

&lt;p&gt;To facilitate building of browser based mashups that use the API, I've also provided support for JSONP callbacks using the &lt;code&gt;callback=foo&lt;/code&gt; parameter, like so: &lt;a href="http://sbsnextbus.appspot.com/api/v1/92049/?callback=myCallbackFunction"&gt;http://sbsnextbus.appspot.com/api/v1/92049/?callback=myCallbackFunction&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Things to watch out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the API response, the &lt;code&gt;code&lt;/code&gt; attribute value should be &lt;code&gt;200&lt;/code&gt;. If it isn't, then something went wrong. If possible, the cause of the error will be sent back as the value of a &lt;code&gt;message&lt;/code&gt; attribute. Example: &lt;a href="http://sbsnextbus.appspot.com/api/v1/00000/"&gt;http://sbsnextbus.appspot.com/api/v1/00000/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;There's some inconsistency between SBS iris &amp;amp; PT@SG regarding the use of service numbers. While PT@SG truncates leading zeros (service &lt;code&gt;15&lt;/code&gt; instead of &lt;code&gt;015&lt;/code&gt;), iris demands that no truncation take place. Hence, you should use the service number strings exactly as returned by the API without any modifications between successive calls.&lt;/li&gt;
&lt;li&gt;The backend caches the arrival timing information for one minute. Hence, there's no point in making calls for the same service &amp;amp; stop combo more than once a minute.&lt;/li&gt;
&lt;li&gt;Don't treat NextBus as an authoritative source of bus services &amp;amp; stops in Singapore. When the API returns a list of services operating at a stop, it only means that the API can provide arrival info for those services. It does not mean that that list of bus services is the complete list of services operating at that stop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do get in touch if you have any concerns about this API. If you go ahead and build something using the API, I would love to hear about it!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>7</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/sbsnextbus3.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/sbsnextbus3.html</guid>   <pubDate>Thu, 30 Oct 2008 18:11 +0800</pubDate>
    </item>
  <item>
    <title>Bizarro Mail
</title>
    <link>http://antrix.net/journal/misc/bizarro_mail.html</link>
    <description>&lt;p&gt;When I first read the subject &lt;em&gt;Recurrent/Occult hernias&lt;/em&gt;, I figured this was just another spam mail which had escaped GMail's filters. Now GMail's filtering is so good that everytime something escapes their trap, it indicates a new approach by the spammers in their never-ending quest to bypass the filters. So whenever I encounter a spam message in my inbox, I have to read it to see what's this new trick up the spammers' sleeves. Thus, intellectual curiosity forced me to read what is truly one of the more bizarre mails I've ever received.&lt;/p&gt;

&lt;p&gt;Here's the thread (start reading at the bottom). Folks with a weak constitution should avoid reading further!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;From: "Deepak Sarda" &amp;lt;dsarda@gmail&amp;gt;
To: jd@yahoo
Subject: Re: Recurrent/Occult hernias

No.. this is 'dsarda' while you want 'desarda' - notice the extra 'e'?

On Tue, Sep 23, 2008 at 1:57 AM, John Doe &amp;lt;jd@yahoo&amp;gt; wrote:
&amp;gt; Isn't this email coming from the correct address?
&amp;gt; This mail is supposed to go to a surgeon in India
&amp;gt;
&amp;gt; Sincerely
&amp;gt;
&amp;gt; --- On Mon, 9/22/08, Deepak Sarda &amp;lt;dsarda@gmail&amp;gt; wrote:
&amp;gt;
&amp;gt; From: Deepak Sarda &amp;lt;dsarda@gmail&amp;gt;
&amp;gt; Subject: Re: Recurrent/Occult hernias
&amp;gt; To: jd@yahoo.com
&amp;gt; Date: Monday, September 22, 2008, 5:41 PM
&amp;gt;
&amp;gt; Dear John Doe
&amp;gt;
&amp;gt; I empathize with your situation. However, I don't think I can help you.
&amp;gt;
&amp;gt; But perhaps 'desarda@gmail' can help you?
&amp;gt;
&amp;gt; Cheers.
&amp;gt;
&amp;gt; On Tue, Sep 23, 2008 at 1:03 AM, John Doe &amp;lt;jd@yahoo&amp;gt; wrote:
&amp;gt;&amp;gt;
&amp;gt;&amp;gt; Dear
&amp;gt;&amp;gt;
&amp;gt;&amp;gt; Dr. Desarda,
&amp;gt;&amp;gt;
&amp;gt;&amp;gt; I have had trouble with mesh retraction/shrinkage and last year had a
&amp;gt;&amp;gt; surgeon take out and replace Dr. Goodyears prolene PHS dual layer mesh with
&amp;gt;&amp;gt; a Ultra Pro flat mesh via a laparocopic TAPP repair.  Prior to this I had a
&amp;gt;&amp;gt; lichtenstein mesh which folded up which Dr. Goodyear took out, and several
&amp;gt;&amp;gt; attempts by a Shouldice surgeon to keep the mesh flat via stitches which
&amp;gt;&amp;gt; helped but didn't work.  But this TAPP repair worked for 9 months and now
&amp;gt;&amp;gt; the pain is coming back.  I felt an odd pain which was probably the mesh
&amp;gt;&amp;gt; shrinking up.
&amp;gt;&amp;gt;
&amp;gt;&amp;gt; Can you check for any hernia and then do your repair?  Would it be necessary
&amp;gt;&amp;gt; to take out the mesh placed via a laparscopic TAPP method?  What is the
&amp;gt;&amp;gt; cost?
&amp;gt;&amp;gt;
&amp;gt;&amp;gt; Sincerely
&amp;gt;&amp;gt; John Doe
&amp;gt;&amp;gt; Seattle WA
&amp;gt;&amp;gt;
&amp;gt;
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
    <category domain="http://antrix.net/journal">/misc</category>
 <slash:comments>2</slash:comments> 
  <comments>http://antrix.net/journal/misc/bizarro_mail.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/misc/bizarro_mail.html</guid>   <pubDate>Tue, 23 Sep 2008 18:52 +0800</pubDate>
    </item>
  <item>
    <title>Dropbox without Gnome</title>
    <link>http://antrix.net/journal/techtalk/dropbox_kde.html</link>
    <description>&lt;p&gt;&lt;a href="http://www.getdropbox.com/"&gt;Dropbox&lt;/a&gt;, the 'it just works' file syncing service, released their Linux client recently. Unfortunately, it has a heavy Gnome/Nautilus dependency. If you don't use Gnome, you can get Dropbox to work without that baggage with these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the closed source Dropbox Linux client from &lt;a href="http://www.getdropbox.com/download?plat=lnx.x86"&gt;http://www.getdropbox.com/download?plat=lnx.x86&lt;/a&gt; (x86_64 for 64 bit)&lt;/li&gt;
&lt;li&gt;Extract the contents and you should get a &lt;code&gt;.dropbox-dist&lt;/code&gt; folder out of the archive. Move the folder to &lt;code&gt;&amp;#036;HOME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;~/.dropbox-dist/dropboxd&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time you run the &lt;code&gt;dropboxd&lt;/code&gt; daemon, a wizard will prompt you to configure the client for your machine. By default, Dropbox syncs the contents of the &lt;code&gt;~/Dropbox&lt;/code&gt; folder and as long as the &lt;code&gt;dropboxd&lt;/code&gt; daemon is running, it will transparently sync that folder with your Dropbox account. To ensure that the daemon runs whenever you use your computer, just add a symlink to it in your &lt;code&gt;~/.kde/Autostart/&lt;/code&gt; folder or equivalent location.&lt;/p&gt;

&lt;p&gt;You don't actually need to do anything beyond that since it 'just works'. But if you feel like getting hold of some of the info that the Nautilus client provides, you can download &lt;a href="http://forums.getdropbox.com/topic.php?id=2543"&gt;this command line utility&lt;/a&gt; that some kind soul has written. Hopefully, someone out there is working on KDE integration even as I write this!&lt;/p&gt;

&lt;p&gt;The only thing that I am syncing right now with my Dropbox account is my Firefox bookmarks and history information. Firefox 3 stores this data in a file called &lt;code&gt;places.sqlite&lt;/code&gt; which lives in the Firefox user profile folder. On my work and home computers, I just moved this file to my &lt;code&gt;~/Dropbox&lt;/code&gt; folder and symlinked to it from the profile folder. It's been working ok for me so far without any conflicts. Let's see if this turns out to be a better solution than &lt;a href="https://wiki.mozilla.org/Labs/Weave"&gt;Weave&lt;/a&gt; which has never ever worked for me.&lt;/p&gt;

&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client = "pub-9530227814232312";
//reiserfs-horiz
google_ad_slot = "9451439877";
google_ad_width = 728;
google_ad_height = 90;
//--&gt;&lt;/script&gt;
&lt;p style="text-align: center;"&gt;
&lt;script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;

&lt;p&gt;&lt;/p&gt;&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>16</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/dropbox_kde.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/dropbox_kde.html</guid>   <pubDate>Wed, 17 Sep 2008 12:22 +0800</pubDate>
    </item>
  <item>
    <title>SBS NextBus: Behind the Scenes </title>
    <link>http://antrix.net/journal/techtalk/sbsnextbus2.html</link>
    <description>&lt;p&gt;I must admit that I am slightly surprised by the positive reception to the &lt;a href="http://sbsnextbus.appspot.com/"&gt;SBS NextBus app&lt;/a&gt; that I announced in my &lt;a href="http://antrix.net/journal/techtalk/sbsnextbus.html"&gt;previous post&lt;/a&gt;. I thought it would languish in obscurity like most of the other toys that I've created over the years but a positive recommendation from &lt;a href="http://www.mrbrown.com/blog/2008/09/a-better-sbs-tr.html"&gt;Mr Brown&lt;/a&gt; turned on a firehose of traffic that, after almost a week now, still hasn't died out. &lt;/p&gt;

&lt;p&gt;The attention also reminded me of how old this blog is now. When I started it, &lt;em&gt;Sounds from the Dungeon&lt;/em&gt; sounded like a cool name and had some meaning to boot. Now I am old and jaded and it just grates on my nerves whenever someone writes words like, &lt;em&gt;Deepak of Sounds from the Dungeon says..&lt;/em&gt; It's high time I streamlined the whole antrix.net experience, getting rid of all the archaic and disconnected stuff around here, reorganizing the content into a cohesive whole and getting rid of the whole dungeon metaphor in the process.&lt;/p&gt;

&lt;p&gt;Anyway, getting back to topic, I do hope that the traffic to the SBS NextBus app converts to a steady userbase; there's nothing like your users screaming at you to provide motivation to maintain the app!&lt;/p&gt;

&lt;p&gt;Speaking of maintaining the app, I committed a couple of feature additions to SBS NextBus last night and with those, I think the app is basically done. The only updates it is likely to see are when the parsers break because SBS Transit decided to change something upstream. I do hope such situations would be really rare!&lt;/p&gt;

&lt;p&gt;With the app basically done, I figured it would be worthwhile to describe here some of the technical bits involved in building the app. If you are the kind that enjoys such geekery, read on :-)&lt;/p&gt;

&lt;p&gt;As is obvious from the domain - sbsnextbus.appspot.com - the app is running on &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. The basic application is fairly straight-forward but there are a couple of twists in its implementation that are worth noting. First of all, the core logic behind the app is dead-simple. When a user requests for bus arrival info at a stop, the app must:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetch page from the &lt;a href="http://www.sbstransit.com.sg/mobileiris/"&gt;mobile iris site&lt;/a&gt; for a bus stop and parse that page for services operating at the stop.&lt;/li&gt;
&lt;li&gt;For each service, fetch page from iris that shows arrival info at that stop.&lt;/li&gt;
&lt;li&gt;Collate results and render output page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I had the basic code structure and rough-cut implementation of this done in about an hour or so, most of which was spent in writing the html parsing bits which I wrote based on html served by the mobile iris site to Firefox. This was a mistake. When I actually started fetching pages from &lt;a href="http://code.google.com/appengine/docs/thedevwebserver.html"&gt;App Engine's development server&lt;/a&gt;, the parsers broke down because iris was serving different html to these requests! One quick way to fix this would have been to emulate Firefox's &lt;a href="http://en.wikipedia.org/wiki/User_agent"&gt;User Agent&lt;/a&gt; in the requests to iris. Unfortunately, App Engine's &lt;a href="http://code.google.com/appengine/docs/urlfetch/"&gt;&lt;code&gt;urlfetch&lt;/code&gt;&lt;/a&gt; currently doesn't provide any way of overriding the user agent identifier. So I had to basically rewrite the parsing bits to adapt to the different html. It didn't take much time but still counted as wasted effort.&lt;/p&gt;

&lt;p&gt;Once the basic app was ready, I had to tackle what I knew would be a problem going in. For those of you who are not aware of its design, App Engine does not allow for long running requests in apps and requires that each HTTP request to your app be served within a short time. If you exceed this short time interval at your disposal, you app process will be killed and the user's request terminated. Although Google does not document the exact duration, looking at App Engine's &lt;a href="http://code.google.com/appengine/docs/theadminconsole.html"&gt;app monitoring dashboard&lt;/a&gt;, I can say that this time limit is around 8 seconds, i.e. every HTTP request to your app has to be handled and a response sent back within 8 seconds. Since App Engine also forbids spawning of threads or processes, you are essentially limited to less that 8 seconds of sequential processing from request to response. For the NextBus app, if it needs to query the iris site for 10 bus numbers at a particular bus stop, all those requests have to happen sequentially and there's no telling how long each remote request would take to complete. Thus, it is quite likely that the 8 second limit is exceeded and your app process is killed for taking too long to complete. The fact that App Engine's &lt;code&gt;urlfetch&lt;/code&gt; call does not support specifying request time outs just exacerbates the problem.&lt;/p&gt;

&lt;p&gt;Thankfully, the App Engine environment doesn't just summarily kill your app on exceeding the alloted time quota. Instead, your app receives a &lt;code&gt;DeadlineExceededError&lt;/code&gt; exception and is given a few more cycles to finish cleaning up before it is killed for good. So we can exploit this &lt;em&gt;last chance at redemption&lt;/em&gt; in a manner similar to this psuedocode:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;try:
    for service in services:
        if service not in memcache:
            # fetch page from iris
            # parse html and extract timings
            # add to memcache
        else:
            # fetch timings from memcache
        # add timings to http response
    #return http response
except google.appengine.runtime.DeadlineExceededError:
    # send as response a HTTP redirect to ourselves:
    # 'http://domain/stop/?number=[stop number]&amp;amp;random=[random int]'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So what's happening here? The core idea is that in the event that our application process receives the &lt;code&gt;DeadlineExceededError&lt;/code&gt; exception, we save our state and redirect the user to make the same request one more time. In the subsequent request, we continue from where we left off last time and hopefully in the span of this new request, we'll be able to finish processing the request. If not, rinse and repeat! &lt;/p&gt;

&lt;p&gt;State communication between requests can be done via url request parameters or via saving/reading from the &lt;a href="http://code.google.com/appengine/docs/datastore/"&gt;Datastore&lt;/a&gt; or via &lt;a href="http://code.google.com/appengine/docs/memcache/"&gt;memcache&lt;/a&gt;. For this app, I chose the memcache approach. Once a bus service's arrival timing is known, it is immediately saved to memcache with an expiry time of 1 minute since after a minute, the arrival timings would be practically useless.&lt;/p&gt;

&lt;p&gt;Thus, this trick of redirecting to self and spreading the processing load between multiple requests allows us to effectively work around the &lt;em&gt;8 seconds&lt;/em&gt; limitation imposed by App Engine. However, there's one final issue to be resolved. The class of the exception thrown seems to vary with environment. After a bit of googling and testing, I ended up with something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;try:
    from google.appengine.runtime import DeadlineExceededError
except:
    # on the development server 
    from google.appengine.runtime.apiproxy_errors import DeadlineExceededError

try:
    # this was noticed in the logs after deployment
    from google3.apphosting.runtime import DeadlineExceededError as DeadlineExceededError2
except:
    DeadlineExceededError2 = DeadlineExceededError

# some app code

try:
    # app logic
except (DeadlineExceededError, DeadlineExceededError2):
    # serve redirect
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hopefully, the inconsistency in the exception class resulting in the boilerplate above will be fixed in a future App Engine update.&lt;/p&gt;

&lt;p&gt;That wraps up all that I remember as worth writing about the SBS NextBus app. But before I end, a few words on the general experience of working with App Engine. After &lt;a href="http://oohembed.com"&gt;oohEmbed.com&lt;/a&gt;, this is the second app I've built that runs on App Engine. For these kind of apps with bare-bones functionality, using the App Engine is a no-brainer simply because the deployment is &lt;em&gt;so damn easy!&lt;/em&gt; For the NextBus app, after I had everything working on the local development server, I just had to go online and register the app id (&lt;code&gt;sbsnextbus&lt;/code&gt;), upload the code and visit &lt;code&gt;sbsnextbus.appspot.com&lt;/code&gt;. The code just worked and I went from &lt;em&gt;development to deployment in under one minute&lt;/em&gt;! The only code change I had to make subsequently was regarding the import of the &lt;code&gt;DeadlineExceededError&lt;/code&gt; exception as noted above. Compare this to the process of configuring Python scripts to be served under &lt;code&gt;cgi&lt;/code&gt;, &lt;code&gt;fcgi&lt;/code&gt; or &lt;code&gt;mod_python&lt;/code&gt; in traditional hosting environments where getting the deployment right often takes as long as developing the entire app.&lt;/p&gt;

&lt;p&gt;From these two app building experiences, I can confidentally say that if you are writing simple Python web apps, you should strongly consider using the App Engine environment. However, this is a very qualified recommendation since I haven't yet used the &lt;a href="http://code.google.com/appengine/docs/datastore/"&gt;Datastore&lt;/a&gt; and have no idea how easy or difficult it would be to adapt to that data model.&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>4</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/sbsnextbus2.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/sbsnextbus2.html</guid>   <pubDate>Mon, 08 Sep 2008 18:52 +0800</pubDate>
    </item>
  <item>
    <title>Improving SBS Transit's iris NextBus</title>
    <link>http://antrix.net/journal/techtalk/sbsnextbus.html</link>
    <description>&lt;p&gt;If you happen to use public transport in Singapore and also happen to surf the internets on the go, chances are that you've heard of &lt;a href="http://www.sbstransit.com.sg/iRIS/nextbus.aspx"&gt;SBS Transit's NextBus information service, &lt;strong&gt;iris&lt;/strong&gt;&lt;/a&gt;. I am a frequent user of this service and although I like it, there is one particular aspect of it that really annoys me. Allow me to illustrate.&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/nextbus/Screenshot0001.png" alt="iris homepage" /&gt;&lt;/div&gt;

&lt;p&gt;This above is the home page of the iris service on which you enter the &lt;a href="http://www.sbstransit.com.sg/iris3/busstopno.aspx"&gt;bus stop number&lt;/a&gt; &amp;amp; the bus service number for which you wish to know the arrival time. Although it isn't obvious from the page, you can leave the bus service field empty and submit the form. When the bus service number is not specified, you get a page that lists all the services operating at the specified bus stop. Like this:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/nextbus/Screenshot0002.png" alt="iris stop listing" /&gt;&lt;/div&gt;

&lt;p&gt;Now once you get this page, you can click on any of the service numbers to get the estimated arrival times. Clicking on 93 above would get you:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/nextbus/Screenshot0003.png" alt="iris service listing" /&gt;&lt;/div&gt;

&lt;p&gt;And this is what annoys me. It is quite likely that I would be interested in more than one of these bus numbers. But to get information on multiple service numbers, I have to navigate back &amp;amp; forth between the service numbers listing &amp;amp; the individual service numbers arrival info.&lt;/p&gt;

&lt;p&gt;To fix this annoyance, I made &lt;a href="http://sbsnextbus.appspot.com/"&gt;sbsnextbus.appspot.com&lt;/a&gt;. When you visit this new site, you are greeted with this page:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/nextbus/Screenshot0004.png" alt="sbsnextbus homepage" /&gt;&lt;/div&gt;

&lt;p&gt;As earlier, you just enter the bus stop number and hit &lt;em&gt;Fetch&lt;/em&gt;. If all goes well, the resulting page will look something like this:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://antrix.net/images/nextbus/Screenshot0005.png" alt="sbsnextbus service listing" /&gt;&lt;/div&gt;

&lt;p&gt;There, all the arrival information in one easily accessible page! No more annoying back &amp;amp; forth navigation! So if you use public transport in Singapore and also happen to surf the internets on the go, please test out &lt;a href="http://sbsnextbus.appspot.com/"&gt;sbsnextbus.appspot.com&lt;/a&gt; and let me know how it works (or not!) for you.&lt;/p&gt;

&lt;p&gt;Oh, here's the QR Code to the site, if your phone supports reading these digital hieroglyphics:&lt;/p&gt;

&lt;div style="text-align: center;"&gt;&lt;img src="http://mobilecodes.nokia.com/qr?DATA=http%3A//sbsnextbus.appspot.com/&amp;MODULE_SIZE=6&amp;name=sbsnextbus.appspot.com&amp;MARGIN=2&amp;ENCODING=BYTE&amp;type=link&amp;MODE=TEXT&amp;a=view" alt="sbsnextbus.appspot.com" /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;(4/Sep/2008)&lt;/em&gt; Hello to everyone coming here via Mr Brown's blog! Thanks for your interest and for trying out this app! Your usage has revealed a few corner cases and bugs which I have now fixed. I've also made a few cosmetic changes suggested by Eric (in comments) and Jon (of &lt;a href="http://isingeo.com/"&gt;iSinGeo.com&lt;/a&gt;) so that the pages display better on an iPhone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;(7/Sep/2008)&lt;/em&gt; This app is now integrated with &lt;a href="http://www.singeo.com.sg/?p=204"&gt;SinGeo&lt;/a&gt; as well as &lt;a href="http://isingeo.com/"&gt;iSinGeo.com&lt;/a&gt;! Read the details on the &lt;a href="http://www.singeo.com.sg/?p=204"&gt;SinGeo blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;(8/Sep/2008)&lt;/em&gt; The app now shows bus stop descriptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;(9/Sep/2008)&lt;/em&gt; Read the blog post describing some of the &lt;a href="http://antrix.net/journal/techtalk/sbsnextbus2.html"&gt;tech behind the app.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; &lt;em&gt;(30/Oct/2008)&lt;/em&gt; New release with &lt;a href="http://antrix.net/journal/techtalk/sbsnextbus3.html"&gt;new features.&lt;/a&gt;&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>39</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/sbsnextbus.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/sbsnextbus.html</guid>   <pubDate>Mon, 01 Sep 2008 15:12 +0800</pubDate>
    </item>
  <item>
    <title>Computing Mysteries</title>
    <link>http://antrix.net/journal/ramblings/computing_mysteries.html</link>
    <description>&lt;p&gt;From time to time, I'm confounded by computers. I have come to know them reasonably well over the years, at least at a superficial level if not at a more &lt;a href="http://www.amazon.com/Inside-Machine-Introduction-Microprocessors-Architecture/dp/1593271042/antrixnet-20"&gt;intimate level&lt;/a&gt;. However, they can still throw up some error, some noise or some silence that leaves me scratching my head.&lt;/p&gt;

&lt;p&gt;Consider this: we bought a commodity server for work some time back. It's nothing fancy, just Linux running on a Core 2 Duo sitting on a Gigabyte mainboard. The curious thing about this machine is the kernel loading phase. You see, the kernel on this machine apparently doesn't like USB keyboards very much and simply refuses to boot up if it doesn't detect a PS/2 keyboard! Of course, this preference is limited only to the initial bootstrapping stage; once the init image is loaded up, I could not only disconnect the PS/2 keyboard but also shred it to bits and the kernel wouldn't care. It would just use the USB keyboard like nothing ever happened between them. So now whenever I reboot this server, I have to remember to plug in the PS/2 keyboard. Yes, the same one which I haven't shred to bits.&lt;/p&gt;

&lt;p&gt;You can imagine what process of trial and error led me to solve the case of the spurned keyboard. &lt;/p&gt;

&lt;p&gt;Then consider my desktop computer at home which feels like it has to compete with my work machines to get my attention. This computer doesn't even get to the kernel loading stage. It hangs before loading GRUB, the OS bootloader. The culprit? My external Seagate USB hard drive which is always connected to the PC. Apparently, the BIOS on this computer doesn't like to be connected to this external disk on boot. So I've to power off the Seagate before turning on the PC. Of course, it isn't as simple as that. If I forget to power on the Seagate before Linux starts booting, then the init scripts detect the missing disk and throw a fit. So I am left with co-ordinating this intricate boot up dance sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Power off the Seagate external drive&lt;/li&gt;
&lt;li&gt;Power on PC&lt;/li&gt;
&lt;li&gt;Wait for GRUB to show up&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Esc&lt;/code&gt; to enter GRUB menu&lt;/li&gt;
&lt;li&gt;Power on the external drive&lt;/li&gt;
&lt;li&gt;Wait for the beep from the BIOS indicating recognition of the drive.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Enter&lt;/code&gt; in GRUB to load Linux&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thankfully, this workaround wasn't that tricky to figure out.&lt;/p&gt;

&lt;p&gt;Finally, there's my old IBM Thinkpad which I recently turned on after leaving it sitting in a cabinet for almost an year. Well, tried to turn on. When powered up, the Thinkpad does nothing but emit four loud beeps repeated four times in case you miss them the first, second or third time. Lenovo says this beep pattern means &lt;em&gt;&lt;a href="http://www-307.ibm.com/pc/support/site.wss/document.do?sitestyle=lenovo&amp;amp;lndocid=MIGR-46018"&gt;System board (Security chip)&lt;/a&gt;.&lt;/em&gt; I am not sure that's very meaningful.&lt;/p&gt;

&lt;p&gt;Thankfully, this kind of stuff doesn't happen often enough for me to consider alternate careers - like that MBA everyone keeps talking about. :-)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/ramblings</category>
 <slash:comments>2</slash:comments> 
  <comments>http://antrix.net/journal/ramblings/computing_mysteries.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/ramblings/computing_mysteries.html</guid>   <pubDate>Wed, 27 Aug 2008 15:11 +0800</pubDate>
    </item>
  <item>
    <title>Shared stuff, APIs, feeds, oh my!</title>
    <link>http://antrix.net/journal/techtalk/friendfeed_yummy.html</link>
    <description>&lt;p&gt;There's no doubt about the fact that we are generating lots and lots of content as part of our online activities. We blog, leave comments, bookmark sites, upload photos and videos, provide status updates and what not. There's so much activity that it's hard to keep track of it all. RSS/Atom feeds have helped but it's just too much work to track down, subscribe and manage a dozen or more feeds for every person that you know.&lt;/p&gt;

&lt;p&gt;On a personal level, I've tried to provide feeds for as many of the things I create/share as possible. There's this blog, the &lt;a href="http://antrix.net/mini/"&gt;tidbits&lt;/a&gt; blog, the &lt;a href="http://antrix.net/dumble/?u=antrix"&gt;tumblelog&lt;/a&gt;, photos on &lt;a href="http://www.flickr.com/photos/antrix/"&gt;flickr&lt;/a&gt;, &lt;a href="http://antrix.net/code/hg/"&gt;code commits&lt;/a&gt;, &lt;a href="http://www.dopplr.com/traveller/antrix/public"&gt;travel updates&lt;/a&gt;, &lt;a href="http://twitter.com/antrix"&gt;status updates&lt;/a&gt; and more. &lt;a href="http://antrix.net/recently/"&gt;Recently&lt;/a&gt; was &lt;a href="http://antrix.net/journal/misc/recently.html"&gt;my attempt&lt;/a&gt; at bringing all of these bits and pieces of info back to a single location on antrix.net. Although slick (bias!), it really isn't what a central clearing house of a person's activities should look like. As it stands, &lt;em&gt;Recently&lt;/em&gt; is rather limited: it doesn't provide permalinks nor feeds and does it allow interaction in the form of comments, etc.&lt;/p&gt;

&lt;p&gt;Enter stage left: FriendFeed.&lt;/p&gt;

&lt;p&gt;I've used &lt;a href="http://friendfeed.com/"&gt;FriendFeed&lt;/a&gt; on and off for some time now, most of the it spent trying to figure out what exactly it does. I still haven't so I will not try to explain. What I will do is to tell you that as of now, I've settled on letting FriendFeed track as much of my publicly accessible info as possible. So everything I mentioned above, with the exception of twitter updates, is now available to you - dear readers - on a &lt;a href="http://friendfeed.com/antrix"&gt;single FriendFeed page&lt;/a&gt;. Love it or ignore it!&lt;/p&gt;

&lt;p&gt;If you are on Facebook, a smaller helping of this stuff should also appear in your Facebook news feed. Of course, only if you are my 'friend'.&lt;/p&gt;

&lt;p&gt;There's exactly one thing that I did towards this &lt;em&gt;shuffling of data&lt;/em&gt; that's worth noting here. Regular readers will know that I've long been using &lt;a href="http://del.icio.us/antrix/linker"&gt;del.icio.us as a link blog&lt;/a&gt;. I use it so much that I even &lt;a href="http://antrix.net/journal/techtalk/dumble.html"&gt;wrote Dumble&lt;/a&gt; (and now &lt;a href="http://oohembed.com/"&gt;oohEmbed&lt;/a&gt;) as a friendly tumblelog style front end to del.icio.us. So del.icio.us has to remain as &lt;em&gt;the definitive link archive&lt;/em&gt; in these quarters.&lt;/p&gt;

&lt;p&gt;With that in mind, you can understand why I've been so slow on the uptake of Google Reader's &lt;a href="http://googlereader.blogspot.com/2008/05/share-anything-anytime-anywhere.html"&gt;shared items&lt;/a&gt; feature, although I've been using Reader exclusively since perhaps late 2006. Simply put, I didn't want to fragment my shared links under two different sources - one of which wouldn't play ball with Dumble. The horror! The only &lt;em&gt;reasonable&lt;/em&gt; thing to do was to write some code that took shared items from Google Reader and posted them to my del.icio.us account. And so I wrote &lt;a href="http://antrix.net/code/hg/misc/yummy/file/tip/yummy.py"&gt;yummy&lt;/a&gt;. My &lt;a href="http://antrix.net/journal/techtalk/python_constrained_containers.html"&gt;last blog post&lt;/a&gt; alluded to this wee bit of code and indeed, &lt;code&gt;yummy&lt;/code&gt; does incorporate feedback from you, dear readers. Where by readers, I mean &lt;a href="http://poundbang.in/"&gt;Harish&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;On the whole, I think I'm happy with the current situation. Of course, I'd much happier if we were in the year 2012 with all this drama behind us - a distant memory of less civilized times. :-)&lt;/p&gt;

&lt;p&gt;Now, I shall go pack my bags since, as &lt;a href="http://www.dopplr.com/traveller/antrix/public"&gt;Dopplr&lt;/a&gt; says, I'm scheduled to be in Mumbai tomorrow!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>2</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/friendfeed_yummy.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/friendfeed_yummy.html</guid>   <pubDate>Wed, 09 Jul 2008 17:02 +0800</pubDate>
    </item>
  <item>
    <title>Python: constrained containers</title>
    <link>http://antrix.net/journal/techtalk/python_constrained_containers.html</link>
    <description>&lt;p&gt;As it happens, I was playing with the &lt;a href="http://del.icio.us/"&gt;del.icio.us&lt;/a&gt; &lt;a href="http://del.icio.us/help/api/"&gt;API&lt;/a&gt; today because of reasons which I shall hopefully elaborate upon in the coming few days. While cooking up some code to interact with the API, I saw the need to model a basic del.icio.us &lt;code&gt;post&lt;/code&gt; entity. For my needs, this entity wouldn't have to be much more than a dumb dictionary with keys like &lt;code&gt;url&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, etc. So I started out that way but pretty soon I thought, wouldn't it be nice to be able to write &lt;code&gt;post.url&lt;/code&gt; instead of &lt;code&gt;post['url']&lt;/code&gt;? Further, wouldn't it be nice to constrain the keys in the dictionary to those required and prevent typo errors such as &lt;code&gt;post['descrption']&lt;/code&gt; instead of &lt;code&gt;post['description']&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;This seemed like the perfect opportunity to put into practice some of the stuff I'd learned about &lt;a href="http://www.geocities.com/foetsch/python/new_style_classes.htm"&gt;"new" style classes&lt;/a&gt; not too long ago. So I wrote the following class which implements the requirements laid out in the preceding paragraph. Since I'm just getting the hang of this stuff, please critique the code!&lt;/p&gt;

&lt;pre style="background-color: #1e1e1e;"&gt;
&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;class &lt;/span&gt;&lt;span style="font-weight: bold;color: #f6aa27;"&gt;Post&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;object&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #80ff80;"&gt;    """Class to model a del.icio.us Post. It works like a struct/dict &lt;/span&gt;
&lt;span style="color: #80ff80;"&gt;    like object which limits keys to a retricted subset, i.e. those&lt;/span&gt;
&lt;span style="color: #80ff80;"&gt;    used in a del.icio.us post."""&lt;/span&gt;

&lt;span style="color: #b3bfa7;"&gt;    __slots__ &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'url'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'extended'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'tags'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;

&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;    def &lt;/span&gt;&lt;span style="font-weight: bold;color: #f6ec2a;"&gt;__getitem__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;if&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; key &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__slots__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;return&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__getattribute__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;else&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;raise&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; KeyError&lt;/span&gt;

&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;    def &lt;/span&gt;&lt;span style="font-weight: bold;color: #f6ec2a;"&gt;__setitem__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; value&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;if&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; key &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__slots__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__setattr__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; value&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;else&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;raise&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; KeyError&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'Given key is not allowed in class &lt;/span&gt;&lt;span style="color: #ef88ff;"&gt;%s&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;\&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;                                &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;%&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__class__.__name__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)&lt;/span&gt;

&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;    def &lt;/span&gt;&lt;span style="font-weight: bold;color: #f6ec2a;"&gt;__contains__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;try&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__getitem__&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;key&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;except&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;            &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;return&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;False&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;return&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;True&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;    &lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;    &lt;/span&gt;&lt;span style="color: #80ff80;"&gt;# urllib.urlencode() just needs this beyond the basic stuff above&lt;/span&gt;
&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;    def &lt;/span&gt;&lt;span style="font-weight: bold;color: #f6ec2a;"&gt;items&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;        &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;return&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;k&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;k&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;])&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;for&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; k &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;.__slots__ &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;if&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; k &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d0dec2;"&gt;self&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;And here's the usage of the class.&lt;/p&gt;

&lt;pre style="background-color: #1e1e1e;"&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; Post&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;()&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.url&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;Traceback &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;most recent call last&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;File &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;"&amp;lt;stdin&amp;gt;"&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; line &lt;/span&gt;&lt;span style="color: #ffa407;"&gt;1&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;module&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;AttributeError&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;:&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; url&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.url &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.url&lt;/span&gt;
&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'url'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;
&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'desc'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;Traceback &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;most recent call last&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;):&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;File &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;"&amp;lt;stdin&amp;gt;"&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; line &lt;/span&gt;&lt;span style="color: #ffa407;"&gt;1&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt;module&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;File &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;"yummy.py"&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; line &lt;/span&gt;&lt;span style="color: #ffa407;"&gt;17&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; __getitem__&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;    &lt;/span&gt;&lt;span style="font-weight: bold;color: #6ec7d7;"&gt;raise&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; KeyError&lt;/span&gt;
&lt;span style="color: #b3bfa7;"&gt;KeyError&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'Google homepage'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;[&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;]&lt;/span&gt;
&lt;span style="color: #d87be6;"&gt;'Google homepage'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.items&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;()&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;[(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'Google homepage'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'url'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)]&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.tags &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'search'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.items&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;()&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;[(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'Google homepage'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'url'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'tags'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'search'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)]&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'extended'&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;in&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p&lt;/span&gt;
&lt;span style="color: #d0dec2;"&gt;False&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.extended &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;=&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'homepage of the world'&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; p.items&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;()&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;[(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'description'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'Google homepage'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'url'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'http://google.com'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'extended'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'homepage of the world'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;),&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;(&lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'tags'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;,&lt;/span&gt;&lt;span style="color: #b3bfa7;"&gt; &lt;/span&gt;&lt;span style="color: #d87be6;"&gt;'search'&lt;/span&gt;&lt;span style="font-weight: bold;color: #ffffff;"&gt;)]&lt;/span&gt;
&lt;span style="font-weight: bold;color: #ffffff;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;So, what am I doing wrong? :-)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>6</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/python_constrained_containers.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/python_constrained_containers.html</guid>   <pubDate>Fri, 04 Jul 2008 18:04 +0800</pubDate>
    </item>
  <item>
    <title>Announcing oohEmbed!</title>
    <link>http://antrix.net/journal/techtalk/oohembed_announce.html</link>
    <description>&lt;p&gt;In my &lt;a href="http://antrix.net/journal/misc/todo_may.html"&gt;last post here&lt;/a&gt;, I mentioned some items on my ever growing TODO list and on top of that list was: &lt;em&gt;Finish the web app that I've started working on.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Well, it's time to scratch that one off the list since &lt;a href="http://oohembed.com/"&gt;oohEmbed.com&lt;/a&gt; is now live!&lt;/p&gt;

&lt;p&gt;A bit of background before I get to what is oohEmbed. As you know, I've been working on and off on &lt;a href="http://antrix.net/dumble/"&gt;Dumble&lt;/a&gt; for the past several months. Now Dumble is a purely browser based application with antrix.net serving up just a bunch of static files. Because of this non-involvement of server-side programming and the web browser's &lt;em&gt;same origin policy&lt;/em&gt; restrictions, there's a limit to how much smart URL-content-inferring can be achieved in Dumble. With the current design, Dumble can go only as far as the number of websites out there that support JSON APIs.&lt;/p&gt;

&lt;p&gt;So on one side, I was toying around with adding a server-side component to Dumble's design to alleviate this problem. On the other, I was looking to kick the tires around &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. In between the two, the &lt;a href="http://oembed.com"&gt;oEmbed&lt;/a&gt; specification was announced and thus was born &lt;a href="http://oohembed.com/"&gt;oohEmbed&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So what exactly is oohEmbed? In the simplest terms, oohEmbed acts like a oEmbed API compatible proxy service between you (the developer) and target websites. For more details, visit the &lt;a href="http://oohembed.com"&gt;oohEmbed.com&lt;/a&gt; web site where I've described it a bit more with some examples.&lt;/p&gt;

&lt;p&gt;Of course, I've re-written parts of Dumble to use this new oohEmbed service. You can find the forked version at &lt;a href="http://oohembed.com/dumble/"&gt;oohembed.com/dumble/&lt;/a&gt;. If things go well, I'll designate this as the authoritative version and switch/redirect the version at antrix.net/dumble/ to it.&lt;/p&gt;

&lt;p&gt;Thanks to the folks behind oEmbed for drafting the spec and to Google for creating App Engine. Although the App Engine environment is restrictive development wise, there's something to be said for a stack which allows one command - &lt;code&gt;appcfg.py update myapp/&lt;/code&gt; - deployments to the cloud! And it's all Python so I couldn't be any happier!&lt;/p&gt;

&lt;p&gt;Please test out oohEmbed and let me know what you think. If you really want to please me, go build something on top of it!&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>4</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/oohembed_announce.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/oohembed_announce.html</guid>   <pubDate>Sun, 01 Jun 2008 22:19 +0800</pubDate>
    </item>
  <item>
    <title>TODO List</title>
    <link>http://antrix.net/journal/misc/todo_may.html</link>
    <description>&lt;p&gt;My TODO list just keeps growing. In no particular order, I have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Finish the web app that I've started working on&lt;/li&gt;
&lt;li&gt;Start the web app that I've planned out&lt;/li&gt;
&lt;li&gt;Finish processing &lt;a href="http://www.flickr.com/photos/antrix/"&gt;photos&lt;/a&gt; and clear that backlog&lt;/li&gt;
&lt;li&gt;Get photo backups in order&lt;/li&gt;
&lt;li&gt;Print a few photos as an experiment&lt;/li&gt;
&lt;li&gt;Implement a major feature that I've planned for &lt;a href="http://code.google.com/p/mitter/"&gt;Mitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Finish reading the four books in various stages of completion. Perhaps only three; &lt;a href="http://www.amazon.com/Confederacy-Dunces-John-Kennedy-Toole/dp/0807126063/antrixnet-20"&gt;this one&lt;/a&gt; is too irritating to finish. &lt;/li&gt;
&lt;li&gt;Buy an Xbox 360 and play GTA 4, Bioshock&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is not counting all of the stuff from work! I'm just too lazy these days and need to get my act together.&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/misc</category>
 <slash:comments>2</slash:comments> 
  <comments>http://antrix.net/journal/misc/todo_may.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/misc/todo_may.html</guid>   <pubDate>Wed, 28 May 2008 14:47 +0800</pubDate>
    </item>
  <item>
    <title>Dumble Update #3</title>
    <link>http://antrix.net/journal/techtalk/dumble4.html</link>
    <description>&lt;p&gt;Alright, time for another &lt;a href="http://antrix.net/dumble/"&gt;Dumble&lt;/a&gt; update. For those tuning in late, Dumble is a web-app that auto-magically creates a tumblelog out of someone's delicious bookmarks. More background in &lt;a href="http://antrix.net/journal/techtalk/dumble.html"&gt;this introductory post&lt;/a&gt; from last November.&lt;/p&gt;

&lt;p&gt;So what's been cooking since the &lt;a href="http://antrix.net/journal/techtalk/dumble3.html"&gt;last Dumble update&lt;/a&gt; which was all the way back in December? For starters, Dumble's source code repository is &lt;a href="http://antrix.net/code/hg/dumble/"&gt;now online&lt;/a&gt; so you can follow Dumble's progress as it happens!&lt;/p&gt;

&lt;p&gt;Looking at the &lt;a href="http://antrix.net/code/hg/dumble/shortlog"&gt;changes&lt;/a&gt; since December, apart from the bug-fixes and speedup related commits, I've added support for three more sites &amp;mdash; &lt;a href="http://www.metacafe.com/"&gt;Metacafe&lt;/a&gt;, &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/"&gt;Wikipedia&lt;/a&gt; &amp;mdash; while improving support for Amazon. While the Metacafe support just relies on the standard video embed widget, the Twitter and Wikipedia support leverages their respective APIs.&lt;/p&gt;

&lt;p&gt;There are a few minor UI changes. You can find a feed subscription link to the currently viewed user's delicious bookmarks.&lt;/p&gt;

&lt;p&gt;Finally, there's one change explicitly to support embedding of Dumble on other websites. Let's say you have a website and wish to have your own copy of Dumble running over there tumbling your delicious bookmarks. One way to do this is to just copy all the Dumble code and host it on your site. While I'm perfectly happy if you do that, there is a drawback to that approach. As and when I make any changes to Dumble, you'll have to keep up by modifying your copy of Dumble. &lt;/p&gt;

&lt;p&gt;An easier way is to just embed http://antrix.net/dumble/ onto your site. Just copy the following HTML snippet into an &lt;code&gt;index.html&lt;/code&gt; file and place it somewhere on your website. Be sure to modify the delicious username and optionally the tag parameters.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Dumble : auto tumble your delicious links&amp;lt;/title&amp;gt;
    &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8"/&amp;gt;
    &amp;lt;style type="text/css" media="screen"&amp;gt;
    html, body {
        margin: 0;
        padding: 0;
        border: 0;
        outline: 0;
    }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;iframe src="http://antrix.net/dumble/?u=USERNAME&amp;amp;t=TAG&amp;amp;title=My delicious tumblelog" height="100%" width="100%" frameborder="0" scrolling="auto"&amp;gt;
Since your browser doesn't support IFrames, please &amp;lt;a href="http://antrix.net/dumble/?u=Ravages"&amp;gt;visit Dumble directly&amp;lt;/a&amp;gt;.
&amp;lt;/iframe&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Did you notice the &lt;code&gt;title&lt;/code&gt; parameter in the &lt;code&gt;iframe src&lt;/code&gt; URI? That's something I added just to enhance this kind of embedding of Dumble. The value of that &lt;code&gt;title&lt;/code&gt; parameter will become the window/browser title.&lt;/p&gt;

&lt;p&gt;You can see an example of such an embedded Dumble over on &lt;a href="http://www.selectiveamnesia.org/dumble/"&gt;Selective Amnesia&lt;/a&gt;. In industry parlance, this would be called a &lt;em&gt;reference installation.&lt;/em&gt; ;-)&lt;/p&gt;

&lt;p&gt;As usual, please test Dumble on your browser/OS combo and let me know of any stuff that breaks. The Wikipedia support is especially hacky and I would appreciate some feedback on that. :)&lt;/p&gt;</description>
    <category domain="http://antrix.net/journal">/techtalk</category>
 <slash:comments>0</slash:comments> 
  <comments>http://antrix.net/journal/techtalk/dumble4.comments</comments>
 <guid isPermaLink="false">http://antrix.net/journal/techtalk/dumble4.html</guid>   <pubDate>Wed, 28 May 2008 14:36 +0800</pubDate>
    </item>
  <lastBuildDate>Thu, 02 Jul 2009 00:00:00 PDT</lastBuildDate></channel>
</rss>
